]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
Added support for timesync/timestamping according to TEPs 132/133, now supporting...
authordevdj <devdj>
Tue, 19 Aug 2008 10:28:02 +0000 (10:28 +0000)
committerdevdj <devdj>
Tue, 19 Aug 2008 10:28:02 +0000 (10:28 +0000)
tos/chips/cc1000/CC1000ActiveMessageC.nc
tos/chips/cc1000/CC1000CsmaRadioC.nc
tos/chips/cc1000/CC1000Msg.h
tos/chips/cc1000/CC1000SendReceiveP.nc
tos/chips/cc1000/CC1000TimeSyncMessage.h [new file with mode: 0644]
tos/chips/cc1000/CC1000TimeSyncMessageC.nc [new file with mode: 0644]
tos/chips/cc1000/CC1000TimeSyncMessageP.nc [new file with mode: 0644]
tos/chips/cc1000/PacketTimeSyncOffset.nc [new file with mode: 0644]
tos/platforms/mica2/TimeSyncMessageC.nc [new file with mode: 0644]

index d35c243d6667a10f0f13d52f6962438b7f6aecbb..7c888373899c7b1bc24e080721f949bfe99c7050 100644 (file)
@@ -1,5 +1,3 @@
-// $Id$
-
 /*
  * "Copyright (c) 2004-2005 The Regents of the University  of California.  
  * All rights reserved.
@@ -38,7 +36,7 @@
  * addr and group).
  * 
  * @author Philip Levis
- * @date June 19 2005
+ * @author Marco Langerwisch (Packet timestamping)
  */
 
 configuration CC1000ActiveMessageC {
@@ -51,6 +49,10 @@ configuration CC1000ActiveMessageC {
     interface Packet;
     interface PacketAcknowledgements;
     interface LinkPacketMetadata;
+
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+    interface PacketTimeSyncOffset;
   }
 }
 implementation {
@@ -73,4 +75,7 @@ implementation {
   AM.amAddress -> Address;
   AM.Packet     -> Radio;
   
+  PacketTimeStamp32khz = Radio;
+  PacketTimeStampMilli = Radio;
+  PacketTimeSyncOffset = Radio;
 }
index faa5d80e2dcd928dbcb8df5c830e59d5353d2472..a04333660cf7f9073c4a0bb6fe26bcc3a9a5b74c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id$
+/*
  * "Copyright (c) 2000-2005 The Regents of the University  of California.  
  * All rights reserved.
  *
@@ -44,6 +44,7 @@
  *
  * @author Joe Polastre
  * @author David Gay
+ * @author Marco Langerwisch (Packet timestamping)
  */
 
 #include "CC1000Const.h"
@@ -55,14 +56,17 @@ configuration CC1000CsmaRadioC {
     interface Send;
     interface Receive;
 
-    interface Packet;    
+    interface Packet;
     interface CsmaControl;
     interface CsmaBackoff;
-    interface RadioTimeStamping;
     interface PacketAcknowledgements;
     interface LinkPacketMetadata;
-    
+
     interface LowPowerListening;
+
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+    interface PacketTimeSyncOffset;
   }
 }
 implementation {
@@ -86,10 +90,9 @@ implementation {
   CsmaControl = Csma;
   CsmaBackoff = Csma;
   LowPowerListening = Csma;
-  RadioTimeStamping = SendReceive;
   PacketAcknowledgements = SendReceive;
   LinkPacketMetadata = SendReceive;
-  
+
   Csma.CC1000Control -> Control;
   Csma.Random -> RandomC;
   Csma.CC1000Squelch -> Squelch;
@@ -103,7 +106,7 @@ implementation {
   SendReceive.amAddress -> ActiveMessageAddressC;
   SendReceive.RssiRx -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
   SendReceive.CC1000Squelch -> Squelch;
-  
+
   Csma.RssiNoiseFloor -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
   Csma.RssiCheckChannel -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
   Csma.RssiPulseCheck -> Rssi.Rssi[unique(UQ_CC1000_RSSI)];
@@ -114,4 +117,16 @@ implementation {
   Rssi.Resource -> Hpl;
   Control.CC -> Hpl;
   Control.BusyWait -> BusyWaitMicroC;
+
+  PacketTimeStamp32khz = SendReceive;
+  PacketTimeStampMilli = SendReceive;
+  PacketTimeSyncOffset = SendReceive;
+
+  components Counter32khz32C, new CounterToLocalTimeC(T32khz);
+  CounterToLocalTimeC.Counter -> Counter32khz32C;
+  SendReceive.LocalTime32khz -> CounterToLocalTimeC;
+
+  //DummyTimer is introduced to compile apps that use no timers
+  components HilTimerMilliC, new TimerMilliC() as DummyTimer;
+  SendReceive.LocalTimeMilli -> HilTimerMilliC;
 }
index a2df2697cc2e260f32fc007fec02cfce3b9011c8..c106b7a090a1df93c2bfc87ee94420e2b30f8410 100644 (file)
@@ -29,9 +29,15 @@ typedef enum {
 typedef nx_struct CC1KMetadata {
   nx_int16_t strength_or_preamble; /* negative when used for preamble length */
   nx_uint8_t metadataBits;
-  nx_uint16_t time;
+  nx_bool timesync;
+  nx_uint32_t timestamp;
   nx_uint8_t sendSecurityMode;
   nx_uint8_t receiveSecurityMode;  
 } cc1000_metadata_t;
 
+enum
+{
+  CC1000_INVALID_TIMESTAMP  = 0x80000000L,
+};
+
 #endif
index 24781e4f088f9b99205533e00d74d15e664b286d..61186cb644dd6cf70e7a339e8cbee65cffe18629 100644 (file)
@@ -1,5 +1,3 @@
-// $Id$
-
 /*
  * "Copyright (c) 2000-2005 The Regents of the University  of California.  
  * All rights reserved.
@@ -32,6 +30,7 @@
 #include "crc.h"
 #include "CC1000Const.h"
 #include "Timer.h"
+#include "CC1000TimeSyncMessage.h"
 
 /**
  * A rewrite of the low-power-listening CC1000 radio stack.
@@ -50,6 +49,7 @@
  * @author Jaein Jeong
  * @author Joe Polastre
  * @author David Gay
+ * @author Marco Langerwisch (Packet timestamping)
  */
   
 module CC1000SendReceiveP @safe() {
@@ -58,11 +58,14 @@ module CC1000SendReceiveP @safe() {
     interface StdControl;
     interface Send;
     interface Receive;
-    interface RadioTimeStamping;
     interface Packet;
     interface ByteRadio;
     interface PacketAcknowledgements;
     interface LinkPacketMetadata;
+
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+    interface PacketTimeSyncOffset;
   }
   uses {
     //interface PowerManagement;
@@ -71,10 +74,21 @@ module CC1000SendReceiveP @safe() {
     interface CC1000Squelch;
     interface ReadNow<uint16_t> as RssiRx;
     async command am_addr_t amAddress();
+
+    interface LocalTime<T32khz> as LocalTime32khz;
+    interface LocalTime<TMilli> as LocalTimeMilli;
   }
 }
 implementation 
 {
+#ifdef PLATFORM_MICA2
+  // estimated calibration, 19.2 Kbps data, Manchester Encoding, time in jiffies (32768 Hz)
+  static const int8_t BIT_CORRECTION[8] = { 27, 28, 30, 32, 34, 36, 38, 40 };
+#else
+  // other platforms not calibrated yet
+  static const uint8_t BIT_CORRECTION[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+#endif
+
   enum {
     OFF_STATE,
 
@@ -257,10 +271,14 @@ implementation
          return FAIL;
        else {
          cc1000_header_t *header = getHeader(msg);
+          cc1000_metadata_t *metadata = getMetadata(msg);
 
          f.txBusy = TRUE;
          header->length = len;
          txBufPtr = msg;
+
+          metadata->timesync = FALSE;
+          metadata->timestamp = CC1000_INVALID_TIMESTAMP;
        }
       }
     signal ByteRadio.rts(msg);
@@ -299,12 +317,23 @@ implementation
     sendNextByte();
     nextTxByte = SYNC_BYTE2;
     enterTxDataState();
-    signal RadioTimeStamping.transmittedSFD(0, txBufPtr); 
   }
 
   void txData() {
     cc1000_header_t *txHeader = getHeader(txBufPtr);
     sendNextByte();
+
+    if (nextTxByte == SYNC_BYTE2) {
+      // SYNC_WORD has just been sent
+      uint32_t time32khz = call LocalTime32khz.get();
+      call PacketTimeStamp32khz.set(txBufPtr, time32khz);
+
+      if (call PacketTimeSyncOffset.isSet(txBufPtr)) {
+        timesync_radio_t *timesync = (timesync_radio_t*)((void*)txBufPtr + call PacketTimeSyncOffset.get(txBufPtr));
+        // set timesync event time as the offset between the event time and the SFD interrupt time (TEP 133)
+        *timesync  -= time32khz;
+      }
+    }
     
     if (count < txHeader->length + sizeof(message_header_t))
       {
@@ -445,9 +474,12 @@ implementation
     else if (count <= 6)
       {
        // TODO: Modify to be tolerant of bad bits in the preamble...
+        uint32_t time;
        uint16_t tmp;
        uint8_t i;
 
+        time = call LocalTime32khz.get();
+
        // bit shift the data in with previous sample to find sync
        tmp = rxShiftBuf;
        rxShiftBuf = rxShiftBuf << 8 | in;
@@ -464,7 +496,10 @@ implementation
                enterRxState();
                signal ByteRadio.rx();
                f.rxBitOffset = 7 - i;
-               signal RadioTimeStamping.receivedSFD(0);
+                // correct receive time according to bit offset and set timestamp
+                time -= BIT_CORRECTION[f.rxBitOffset];
+                call PacketTimeStamp32khz.set(rxBufPtr, time);
+
                call RssiRx.read();
              }
          }
@@ -677,9 +712,71 @@ implementation
   async command bool LinkPacketMetadata.highChannelQuality(message_t* msg) {
     return getMetadata(msg)->metadataBits & CC1000_WHITE_BIT;
   }
-  
-  // Default events for radio send/receive coordinators do nothing.
-  // Be very careful using these, or you'll break the stack.
-  default async event void RadioTimeStamping.transmittedSFD(uint16_t time, message_t *msgBuff) { }
-  default async event void RadioTimeStamping.receivedSFD(uint16_t time) { }
+
+  /***************** PacketTimeStamp32khz Commands ****************/
+  async command bool PacketTimeStamp32khz.isValid(message_t* msg)
+  {
+    return (getMetadata(msg)->timestamp != CC1000_INVALID_TIMESTAMP);
+  }
+
+  async command uint32_t PacketTimeStamp32khz.timestamp(message_t* msg)
+  {
+    return getMetadata(msg)->timestamp;
+  }
+
+  async command void PacketTimeStamp32khz.clear(message_t* msg)
+  {
+    getMetadata(msg)->timesync = FALSE;
+    getMetadata(msg)->timestamp = CC1000_INVALID_TIMESTAMP;
+  }
+
+  async command void PacketTimeStamp32khz.set(message_t* msg, uint32_t value)
+  {
+    getMetadata(msg)->timestamp = value;
+  }
+
+  /***************** PacketTimeStampMilli Commands ****************/
+  // over the air value is always T32khz
+  async command bool PacketTimeStampMilli.isValid(message_t* msg)
+  {
+    return call PacketTimeStamp32khz.isValid(msg);
+  }
+
+  async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
+  {
+    int32_t offset = call PacketTimeStamp32khz.timestamp(msg) - call LocalTime32khz.get();
+    return (offset >> 5) + call LocalTimeMilli.get();
+  }
+
+  async command void PacketTimeStampMilli.clear(message_t* msg)
+  {
+    call PacketTimeStamp32khz.clear(msg);
+  }
+
+  async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
+  {
+    int32_t offset = (value - call LocalTimeMilli.get()) << 5;
+    call PacketTimeStamp32khz.set(msg, offset + call LocalTime32khz.get());
+  }
+
+  /*----------------- PacketTimeSyncOffset -----------------*/
+  async command bool PacketTimeSyncOffset.isSet(message_t* msg)
+  {
+    return getMetadata(msg)->timesync;
+  }
+
+  async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
+  {
+    return sizeof(cc1000_header_t) + getHeader(msg)->length - sizeof(timesync_radio_t);
+  }
+
+  async command void PacketTimeSyncOffset.set(message_t* msg)
+  {
+    getMetadata(msg)->timesync = TRUE;
+  }
+
+  async command void PacketTimeSyncOffset.cancel(message_t* msg)
+  {
+    getMetadata(msg)->timesync = FALSE;
+  }
 }
diff --git a/tos/chips/cc1000/CC1000TimeSyncMessage.h b/tos/chips/cc1000/CC1000TimeSyncMessage.h
new file mode 100644 (file)
index 0000000..a744fd3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ * 
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * 
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __TIMESYNCMESSAGE_H__
+#define __TIMESYNCMESSAGE_H__
+
+// this value is sent in the air
+typedef nx_uint32_t timesync_radio_t;
+
+#endif//__TIMESYNCMESSAGE_H__
diff --git a/tos/chips/cc1000/CC1000TimeSyncMessageC.nc b/tos/chips/cc1000/CC1000TimeSyncMessageC.nc
new file mode 100644 (file)
index 0000000..d370f84
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+/**
+ * The Active Message layer for the CC1000 radio with timesync support. This
+ * configuration is just layer above CC1000ActiveMessageC that supports
+ * TimeSyncPacket and TimeSyncAMSend interfaces (TEP 133)
+ *
+ * @author: Miklos Maroti
+ * @author: Brano Kusy (CC2420 port)
+ * @author: Marco Langerwisch (CC1000 port)
+ */
+
+#include <Timer.h>
+#include <AM.h>
+
+configuration CC1000TimeSyncMessageC
+{
+    provides
+    {
+        interface SplitControl;
+        interface Receive[am_id_t id];
+        interface Receive as Snoop[am_id_t id];
+        interface Packet;
+        interface AMPacket;
+
+        interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+        interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+
+        interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[am_id_t id];
+        interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+
+        interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+        interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+    }
+}
+
+implementation
+{
+        components CC1000TimeSyncMessageP, CC1000ActiveMessageC, LedsC;
+
+        PacketTimeStamp32khz = CC1000ActiveMessageC;
+        PacketTimeStampMilli = CC1000ActiveMessageC;
+
+        TimeSyncAMSend32khz = CC1000TimeSyncMessageP;
+        TimeSyncPacket32khz = CC1000TimeSyncMessageP;
+
+        TimeSyncAMSendMilli = CC1000TimeSyncMessageP;
+        TimeSyncPacketMilli = CC1000TimeSyncMessageP;
+
+        Packet = CC1000TimeSyncMessageP;
+        CC1000TimeSyncMessageP.SubSend -> CC1000ActiveMessageC.AMSend;
+        CC1000TimeSyncMessageP.SubPacket -> CC1000ActiveMessageC.Packet;
+        CC1000TimeSyncMessageP.PacketTimeStamp32khz -> CC1000ActiveMessageC;
+        CC1000TimeSyncMessageP.PacketTimeStampMilli -> CC1000ActiveMessageC;
+        CC1000TimeSyncMessageP.PacketTimeSyncOffset -> CC1000ActiveMessageC;
+
+        components Counter32khz32C,
+            new CounterToLocalTimeC(T32khz) as LocalTime32khzC, LocalTimeMilliC;
+        LocalTime32khzC.Counter -> Counter32khz32C;
+        CC1000TimeSyncMessageP.LocalTime32khz -> LocalTime32khzC;
+        CC1000TimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
+        CC1000TimeSyncMessageP.Leds -> LedsC;
+
+        SplitControl = CC1000ActiveMessageC;
+        Receive = CC1000ActiveMessageC.Receive;
+        Snoop = CC1000ActiveMessageC.Snoop;
+        AMPacket = CC1000ActiveMessageC;
+}
diff --git a/tos/chips/cc1000/CC1000TimeSyncMessageP.nc b/tos/chips/cc1000/CC1000TimeSyncMessageP.nc
new file mode 100644 (file)
index 0000000..1590c52
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * @author: Miklos Maroti
+ * @author: Brano Kusy (CC2420 port)
+ * @author: Marco Langerwisch (CC1000 port)
+ */
+#include "CC1000TimeSyncMessage.h"
+
+module CC1000TimeSyncMessageP
+{
+    provides
+    {
+        interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[uint8_t id];
+        interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
+        interface Packet;
+
+        interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+        interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+    }
+
+    uses
+    {
+        interface AMSend as SubSend[uint8_t id];
+        interface Packet as SubPacket;
+
+        interface PacketTimeStamp<T32khz,uint32_t> as PacketTimeStamp32khz;
+        interface PacketTimeStamp<TMilli,uint32_t> as PacketTimeStampMilli;
+        interface PacketTimeSyncOffset;
+
+        interface LocalTime<T32khz> as LocalTime32khz;
+        interface LocalTime<TMilli> as LocalTimeMilli;
+        interface Leds;
+    }
+}
+
+implementation
+{
+    // TODO: change the Packet.payloadLength and Packet.maxPayloadLength commands to async
+    inline void* getFooter(message_t* msg)
+    {
+        // we use the payload length that we export (the smaller one)
+        return msg->data + call Packet.payloadLength(msg);
+    }
+
+/*----------------- Packet -----------------*/
+    command void Packet.clear(message_t* msg)
+    {
+        call PacketTimeSyncOffset.cancel(msg);
+        call SubPacket.clear(msg);
+    }
+
+    command void Packet.setPayloadLength(message_t* msg, uint8_t len)
+    {
+        call SubPacket.setPayloadLength(msg, len + sizeof(timesync_radio_t));
+    }
+
+    command uint8_t Packet.payloadLength(message_t* msg)
+    {
+        return call SubPacket.payloadLength(msg) - sizeof(timesync_radio_t);
+    }
+
+    command uint8_t Packet.maxPayloadLength()
+    {
+        return call SubPacket.maxPayloadLength() - sizeof(timesync_radio_t);
+    }
+
+    command void* Packet.getPayload(message_t* msg, uint8_t len)
+    {
+        return call SubPacket.getPayload(msg, len + sizeof(timesync_radio_t));
+    }
+
+/*----------------- TimeSyncAMSend32khz -----------------*/
+    command error_t TimeSyncAMSend32khz.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+    {
+        error_t err;
+        timesync_radio_t* timesync = (timesync_radio_t*)(msg->data + len);
+        *timesync = event_time;
+
+        err = call SubSend.send[id](addr, msg, len + sizeof(timesync_radio_t));
+        call PacketTimeSyncOffset.set(msg);
+        return err;
+    }
+
+    command error_t TimeSyncAMSend32khz.cancel[am_id_t id](message_t* msg)
+    {
+        call PacketTimeSyncOffset.cancel(msg);
+        return call SubSend.cancel[id](msg);
+    }
+
+    default event void TimeSyncAMSend32khz.sendDone[am_id_t id](message_t* msg, error_t error) {}
+
+    command uint8_t TimeSyncAMSend32khz.maxPayloadLength[am_id_t id]()
+    {
+        return call SubSend.maxPayloadLength[id]() - sizeof(timesync_radio_t);
+    }
+
+    command void* TimeSyncAMSend32khz.getPayload[am_id_t id](message_t* msg, uint8_t len)
+    {
+        return call SubSend.getPayload[id](msg, len + sizeof(timesync_radio_t));
+    }
+
+/*----------------- TimeSyncAMSendMilli -----------------*/
+    command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+    {
+        // compute elapsed time in millisecond
+        event_time = ((event_time - call LocalTimeMilli.get()) << 5) + call LocalTime32khz.get();
+        return call TimeSyncAMSend32khz.send[id](addr, msg, len, event_time);
+    }
+
+    command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
+    {
+        return call TimeSyncAMSend32khz.cancel[id](msg);
+    }
+
+    default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error){}
+
+    command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
+    {
+        return call TimeSyncAMSend32khz.maxPayloadLength[id]();
+    }
+
+    command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
+    {
+        return call TimeSyncAMSend32khz.getPayload[id](msg, len);
+    }
+
+/*----------------- SubSend.sendDone -------------------*/
+    event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
+    {
+        signal TimeSyncAMSend32khz.sendDone[id](msg, error);
+        signal TimeSyncAMSendMilli.sendDone[id](msg, error);
+    }
+
+/*----------------- TimeSyncPacket32khz -----------------*/
+    command bool TimeSyncPacket32khz.isValid(message_t* msg)
+    {
+        timesync_radio_t* timesync = getFooter(msg);
+        return call PacketTimeStamp32khz.isValid(msg) && *timesync != CC1000_INVALID_TIMESTAMP;
+    }
+
+    command uint32_t TimeSyncPacket32khz.eventTime(message_t* msg)
+    {
+        timesync_radio_t* timesync = getFooter(msg);
+
+        return (uint32_t)(*timesync) + call PacketTimeStamp32khz.timestamp(msg);
+    }
+
+/*----------------- TimeSyncPacketMilli -----------------*/
+    command bool TimeSyncPacketMilli.isValid(message_t* msg)
+    {
+        timesync_radio_t* timesync = getFooter(msg);
+        return call PacketTimeStampMilli.isValid(msg) && *timesync != CC1000_INVALID_TIMESTAMP;
+    }
+
+    command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
+    {
+        timesync_radio_t* timesync = getFooter(msg);
+        return ((int32_t)(*timesync) >> 5) + call PacketTimeStampMilli.timestamp(msg);
+    }
+}
diff --git a/tos/chips/cc1000/PacketTimeSyncOffset.nc b/tos/chips/cc1000/PacketTimeSyncOffset.nc
new file mode 100644 (file)
index 0000000..b3cef8c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti, Brano Kusy
+ *
+ * Interface for one hop time synchronization. Allows to modify timesync
+ * messages in the MAC layer with elapsed time of an event (ETA timesync
+ * primitive). Interface also provides a command to determine offset within
+ * a CC1000 packet, where the timesync ETA value is stored. word 'timestamping'
+ * used in describing commands does not refer to metadata.timestamp value,
+ * rather it refers to the timesync ETA timestamp which is part of data
+ * payload and is transmitted over the air.
+ */
+
+interface PacketTimeSyncOffset
+{
+    /**
+     * @param 'message_t *ONE msg' message to examine.
+     *
+     * Returns TRUE if the current message should be timestamped.
+     */
+    async command bool isSet(message_t* msg);
+
+    /**
+     * @param 'message_t *ONE msg' message to examine.
+     *
+     * Returns the offset of where the timesync timestamp is sotred in a
+     * CC2420 packet
+     */
+    async command uint8_t get(message_t* msg);
+
+    /**
+     * @param 'message_t *ONE msg' message to modify.
+     *
+     *  Sets the current message to be timestamped in the MAC layer.
+     */
+    async command void set(message_t* msg);
+
+    /**
+     * @param 'message_t *ONE msg' message to modify.
+     *
+     * Cancels any pending requests to timestamp the message in MAC.
+     */
+    async command void cancel(message_t* msg);
+}
+
diff --git a/tos/platforms/mica2/TimeSyncMessageC.nc b/tos/platforms/mica2/TimeSyncMessageC.nc
new file mode 100644 (file)
index 0000000..fa22a77
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * "Copyright (c) 2004-2005 The Regents of the University  of California.
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
+ * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
+ *
+ * Copyright (c) 2004-2005 Intel Corporation
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached INTEL-LICENSE
+ * file. If you do not find these files, copies can be found by writing to
+ * Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
+ * 94704.  Attention:  Intel License Inquiry.
+ */
+
+/**
+ *
+ * The Active Message layer on the mica2 platform. This is a naming wrapper
+ * around the CC1000 Active Message layer that implemets timesync interface (TEP 133).
+ *
+ * @author Philip Levis
+ * @author Brano Kusy
+ * @author Marco Langerwisch (Mica2 port)
+ */
+
+configuration TimeSyncMessageC {
+  provides
+  {
+    interface SplitControl;
+    interface Receive[am_id_t id];
+    interface Receive as Snoop[am_id_t id];
+    interface Packet;
+    interface AMPacket;
+
+    interface PacketTimeStamp<T32khz, uint32_t> as PacketTimeStamp32khz;
+    interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+
+    interface TimeSyncAMSend<T32khz, uint32_t> as TimeSyncAMSend32khz[am_id_t id];
+    interface TimeSyncPacket<T32khz, uint32_t> as TimeSyncPacket32khz;
+
+    interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+    interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+  }
+}
+implementation {
+  components CC1000TimeSyncMessageC as AM;
+
+  SplitControl = AM;
+
+  Receive      = AM.Receive;
+  Snoop        = AM.Snoop;
+  Packet       = AM;
+  AMPacket     = AM;
+  TimeSyncAMSend32khz       = AM;
+  TimeSyncAMSendMilli       = AM;
+  TimeSyncPacket32khz       = AM;
+  TimeSyncPacketMilli       = AM;
+  PacketTimeStamp32khz      = AM;
+  PacketTimeStampMilli      = AM;
+}