]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
timesync support
authormmaroti <mmaroti>
Wed, 20 Feb 2008 01:01:48 +0000 (01:01 +0000)
committermmaroti <mmaroti>
Wed, 20 Feb 2008 01:01:48 +0000 (01:01 +0000)
12 files changed:
tos/chips/rf230/DefaultMacC.nc
tos/chips/rf230/DefaultMacP.nc
tos/chips/rf230/DefaultPacket.h [new file with mode: 0644]
tos/chips/rf230/DefaultPacketC.nc [new file with mode: 0644]
tos/chips/rf230/DefaultPacketP.nc [new file with mode: 0644]
tos/chips/rf230/MessageBufferLayerP.nc
tos/chips/rf230/PacketField.nc [new file with mode: 0644]
tos/chips/rf230/PacketTimeStamp.nc
tos/chips/rf230/PacketTimeSynch.nc
tos/chips/rf230/RF230Config.nc
tos/chips/rf230/RF230LayerC.nc
tos/chips/rf230/RF230LayerP.nc

index 32296187bf19d95e2c545d39edf1dcaafb0cdf08..2f6ca524e15c5fc93a66e60db8d469664851fdcc 100644 (file)
@@ -21,6 +21,8 @@
  * Author: Miklos Maroti
  */
 
+#include <HplRF230.h>
+
 configuration DefaultMacC
 {
        provides 
@@ -34,20 +36,32 @@ configuration DefaultMacC
                interface Packet;
                interface AMPacket;
                interface PacketAcknowledgements;
+
+               interface PacketField<uint8_t> as PacketLinkQuality;
+               interface PacketTimeStamp<TRF230, uint16_t>;
+               interface PacketTimeSynch<TRF230, uint16_t>;
        }
 }
 
 implementation
 {
-       components DefaultMacP, IEEE154PacketC, RadioAlarmC;
+       components DefaultMacP, DefaultPacketC, IEEE154PacketC, RadioAlarmC;
 
 #ifdef RF230_DEBUG
        components AssertC;
 #endif
 
        DefaultMacP.IEEE154Packet -> IEEE154PacketC;
+       DefaultMacP.Packet -> DefaultPacketC;
        DefaultMacP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
 
+       Packet = DefaultPacketC;
+       AMPacket = DefaultPacketC;
+       PacketAcknowledgements = DefaultPacketC;
+       PacketLinkQuality = DefaultPacketC.PacketLinkQuality;
+       PacketTimeStamp = DefaultPacketC.PacketTimeStamp;
+       PacketTimeSynch = DefaultPacketC.PacketTimeSynch;
+
        components ActiveMessageLayerC;
        components MessageBufferLayerC;
        components UniqueLayerC;
@@ -62,9 +76,6 @@ implementation
        AMSend = ActiveMessageLayerC;
        Receive = ActiveMessageLayerC.Receive;
        Snoop = ActiveMessageLayerC.Snoop;
-       Packet = DefaultMacP;
-       AMPacket = IEEE154PacketC;
-       PacketAcknowledgements = DefaultMacP;
 
        ActiveMessageLayerC.Config -> DefaultMacP;
        ActiveMessageLayerC.AMPacket -> IEEE154PacketC;
@@ -74,7 +85,7 @@ implementation
        UniqueLayerC.Config -> DefaultMacP;
        UniqueLayerC.SubSend -> MessageBufferLayerC;
 
-       MessageBufferLayerC.Packet -> DefaultMacP;
+       MessageBufferLayerC.Packet -> DefaultPacketC;
        MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC;
        MessageBufferLayerC.RadioReceive -> UniqueLayerC;
        MessageBufferLayerC.RadioState -> TrafficMonitorLayerC;
@@ -99,4 +110,8 @@ implementation
        CsmaLayerC.SubCCA -> RF230LayerC;
 
        RF230LayerC.RF230Config -> DefaultMacP;
+       RF230LayerC.PacketLinkQuality -> DefaultPacketC.PacketLinkQuality;
+       RF230LayerC.PacketTransmitPower -> DefaultPacketC.PacketTransmitPower;
+       RF230LayerC.PacketTimeStamping -> DefaultPacketC.PacketTimeStamping;
+       RF230LayerC.PacketTimeSynchron -> DefaultPacketC.PacketTimeSynchron;
 }
index ba17f9baf583eb1080eea135bd9f58eae92a3fc0..1ab43da41b710a34ee01c39e9c77be15fea4f3d0 100644 (file)
@@ -21,7 +21,7 @@
  * Author: Miklos Maroti
  */
 
-#include <DefaultMac.h>
+#include <DefaultPacket.h>
 #include <HplRF230.h>
 #include <Tasklet.h>
 
@@ -38,63 +38,18 @@ module DefaultMacP
                interface SlottedCollisionConfig;
                interface ActiveMessageConfig;
                interface DummyConfig;
-
-               interface PacketAcknowledgements;
-               interface Packet;
        }
 
        uses
        {
                interface IEEE154Packet;
+               interface Packet;
                interface RadioAlarm;
        }
 }
 
 implementation
 {
-/*----------------- Packet -----------------*/
-
-       command void Packet.clear(message_t* msg) 
-       {
-               call IEEE154Packet.createDataFrame(msg);
-
-#ifdef IEEE154_6LOWPAN
-               call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
-#endif
-       }
-  
-       command uint8_t Packet.payloadLength(message_t* msg) 
-       {
-               return call IEEE154Packet.getLength(msg) - sizeof(ieee154_header_t) + 1 - sizeof(ieee154_footer_t);
-       }
-  
-       command void Packet.setPayloadLength(message_t* msg, uint8_t len) 
-       {
-               call IEEE154Packet.setLength(msg, len + sizeof(ieee154_header_t) - 1 + sizeof(ieee154_footer_t));
-       }
-  
-       command uint8_t Packet.maxPayloadLength()
-       {
-               return TOSH_DATA_LENGTH;
-       }
-  
-       command void* Packet.getPayload(message_t* msg, uint8_t len)
-       {
-               if( len > TOSH_DATA_LENGTH )
-                       return NULL;
-
-               return msg->data;
-       }
-
-       command error_t ActiveMessageConfig.checkPacket(message_t* msg)
-       {
-               // the user forgot to call clear, we should return EINVAL
-               if( ! call IEEE154Packet.isDataFrame(msg) )
-                       call Packet.clear(msg);
-
-               return SUCCESS;
-       }
-
 /*----------------- RF230Config -----------------*/
 
        async command uint8_t RF230Config.getLength(message_t* msg)
@@ -112,19 +67,9 @@ implementation
                return ((uint8_t*)(call IEEE154Packet.getHeader(msg))) + 1;
        }
 
-       inline defaultmac_metadata_t* getMeta(message_t* msg)
+       inline defpacket_metadata_t* getMeta(message_t* msg)
        {
-               return (defaultmac_metadata_t*)(msg->metadata);
-       }
-
-       async command void RF230Config.setTimestamp(message_t* msg, uint16_t time)
-       {
-               getMeta(msg)->timestamp = time;
-       }
-
-       async command void RF230Config.setLinkQuality(message_t* msg, uint8_t lqi)
-       {
-               getMeta(msg)->lqi = lqi;
+               return (defpacket_metadata_t*)(msg->metadata);
        }
 
        async command uint8_t RF230Config.getHeaderLength()
@@ -136,12 +81,7 @@ implementation
        async command uint8_t RF230Config.getMaxLength()
        {
                // note, that the ieee154_footer_t is not stored, but we should include it here
-               return sizeof(defaultmac_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t);
-       }
-
-       async command uint8_t RF230Config.getTransmitPower(message_t* msg)
-       {
-               return RF230_DEF_RFPOWER;
+               return sizeof(defpacket_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t);
        }
 
        async command uint8_t RF230Config.getDefaultChannel()
@@ -184,9 +124,9 @@ implementation
        async command void SoftwareAckConfig.setAckReceived(message_t* msg, bool acked)
        {
                if( acked )
-                       getMeta(msg)->flags |= DEFAULTMAC_WAS_ACKED;
+                       getMeta(msg)->flags |= DEFPACKET_WAS_ACKED;
                else
-                       getMeta(msg)->flags &= ~DEFAULTMAC_WAS_ACKED;
+                       getMeta(msg)->flags &= ~DEFPACKET_WAS_ACKED;
        }
 
        async command uint16_t SoftwareAckConfig.getAckTimeout()
@@ -199,27 +139,6 @@ implementation
                signal TrafficMonitorConfig.channelError();
        }
 
-/*----------------- PacketAcknowledgements -----------------*/
-
-       async command error_t PacketAcknowledgements.requestAck(message_t* msg)
-       {
-               call IEEE154Packet.setAckRequired(msg, TRUE);
-
-               return SUCCESS;
-       }
-
-       async command error_t PacketAcknowledgements.noAck(message_t* msg)
-       {
-               call IEEE154Packet.setAckRequired(msg, FALSE);
-
-               return SUCCESS;
-       }
-
-       async command bool PacketAcknowledgements.wasAcked(message_t* msg)
-       {
-               return getMeta(msg)->flags & DEFAULTMAC_WAS_ACKED;
-       }
-
 /*----------------- UniqueConfig -----------------*/
 
        async command uint8_t UniqueConfig.getSequenceNumber(message_t* msg)
@@ -242,6 +161,17 @@ implementation
                signal TrafficMonitorConfig.channelError();
        }
 
+/*----------------- ActiveMessageConfig -----------------*/
+
+       command error_t ActiveMessageConfig.checkPacket(message_t* msg)
+       {
+               // the user forgot to call clear, we should return EINVAL
+               if( ! call IEEE154Packet.isDataFrame(msg) )
+                       call Packet.clear(msg);
+
+               return SUCCESS;
+       }
+
 /*----------------- CsmaConfig -----------------*/
 
        async command bool CsmaConfig.requiresSoftwareCCA(message_t* msg)
diff --git a/tos/chips/rf230/DefaultPacket.h b/tos/chips/rf230/DefaultPacket.h
new file mode 100644 (file)
index 0000000..819b5bd
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * 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 __DEFAULTPACKET_H__
+#define __DEFAULTPACKET_H__
+
+#include <IEEE154Packet.h>
+
+typedef ieee154_header_t defpacket_header_t;
+
+typedef nx_struct defpacket_metadata_t
+{
+       nx_uint8_t flags;
+       nx_uint8_t lqi;
+       nx_uint16_t timestamp;
+} defpacket_metadata_t;
+
+enum defpacket_metadata_flags
+{
+       DEFPACKET_WAS_ACKED = 0x01,
+       DEFPACKET_TIMESTAMP = 0x02,
+
+       DEFPACKET_CLEAR_METADATA = 0x00,
+};
+
+typedef nx_struct defpacket_footer_t
+{
+       nx_uint16_t timeoffset;
+} defpacket_footer_t;
+
+enum defpacket_footer_enum
+{
+       // just to signal missing time offsets
+       DEFPACKET_INVALID_TIMEOFFSET = 0x7317,
+};
+
+#endif//__DEFAULTPACKET_H__
diff --git a/tos/chips/rf230/DefaultPacketC.nc b/tos/chips/rf230/DefaultPacketC.nc
new file mode 100644 (file)
index 0000000..f02f3e6
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * 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
+ */
+
+#include <HplRF230.h>
+
+configuration DefaultPacketC
+{
+       provides
+       {
+               interface Packet;
+               interface AMPacket;
+               interface PacketAcknowledgements;
+               interface PacketField<uint8_t> as PacketLinkQuality;
+               interface PacketField<uint8_t> as PacketTransmitPower;
+               interface PacketField<uint16_t> as PacketTimeStamping;
+               interface PacketField<uint16_t> as PacketTimeSynchron;
+
+               interface PacketTimeStamp<TRF230, uint16_t>;
+               interface PacketTimeSynch<TRF230, uint16_t>;
+       }
+}
+
+implementation
+{
+       components DefaultPacketP, IEEE154PacketC;
+
+       DefaultPacketP.IEEE154Packet -> IEEE154PacketC;
+
+       Packet = DefaultPacketP;
+       AMPacket = IEEE154PacketC;
+       PacketAcknowledgements = DefaultPacketP;
+       PacketLinkQuality = DefaultPacketP.PacketLinkQuality;
+       PacketTransmitPower = DefaultPacketP.PacketTransmitPower;
+       PacketTimeStamping = DefaultPacketP.PacketTimeStamping;
+       PacketTimeSynchron = DefaultPacketP.PacketTimeSynchron;
+
+       PacketTimeStamp = DefaultPacketP.PacketTimeStamp;
+       PacketTimeSynch = DefaultPacketP.PacketTimeSynch;
+}
diff --git a/tos/chips/rf230/DefaultPacketP.nc b/tos/chips/rf230/DefaultPacketP.nc
new file mode 100644 (file)
index 0000000..1c2358d
--- /dev/null
@@ -0,0 +1,288 @@
+/*
+ * 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
+ */
+
+#include <DefaultPacket.h>
+
+module DefaultPacketP
+{
+       provides
+       {
+               interface PacketAcknowledgements;
+               interface Packet;
+               interface PacketField<uint8_t> as PacketLinkQuality;
+               interface PacketField<uint8_t> as PacketTransmitPower;
+               interface PacketField<uint16_t> as PacketTimeStamping;
+               interface PacketField<uint16_t> as PacketTimeSynchron;
+
+               interface PacketTimeStamp<TRF230, uint16_t>;
+               interface PacketTimeSynch<TRF230, uint16_t>;
+       }
+
+       uses
+       {
+               interface IEEE154Packet;
+       }
+}
+
+implementation
+{
+/*----------------- Async Packet -----------------*/
+
+#define PACKET_OVERHEAD ((sizeof(ieee154_header_t) - 1) + sizeof(defpacket_footer_t) + sizeof(ieee154_footer_t))
+
+       // async Packet.payloadLength
+       inline uint8_t getPayloadLength(message_t* msg)
+       {
+               //      sizeof(ieee154_header_t) - 1 : the ieee154 header minus the length field
+               //      sizeof(defpacket_footer_t) : footer containing the embedded time offset
+               //      sizeof(ieee154_footer_t) : the size of the CRC (not transmitted)
+
+               return call IEEE154Packet.getLength(msg) - PACKET_OVERHEAD;
+       }
+
+       // async Pakcet.maxPayloadLength
+       inline uint8_t getMaxPayloadLength()
+       {
+               return TOSH_DATA_LENGTH;
+       }
+
+/*----------------- Accessors -----------------*/
+
+       inline defpacket_metadata_t* getMeta(message_t* msg)
+       {
+               return (defpacket_metadata_t*)(msg->metadata);
+       }
+
+       inline defpacket_footer_t* getFooter(message_t* msg)
+       {
+               return (defpacket_footer_t*)(msg->data + getPayloadLength(msg));
+       }
+
+/*----------------- Packet -----------------*/
+
+       command void Packet.clear(message_t* msg) 
+       {
+               call IEEE154Packet.createDataFrame(msg);
+
+#ifdef IEEE154_6LOWPAN
+               call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
+#endif
+
+               getMeta(msg)->flags = DEFPACKET_CLEAR_METADATA;
+       }
+  
+       inline command void Packet.setPayloadLength(message_t* msg, uint8_t len) 
+       {
+               call IEEE154Packet.setLength(msg, len + PACKET_OVERHEAD);
+       }
+  
+       inline command uint8_t Packet.payloadLength(message_t* msg) 
+       {
+               return getPayloadLength(msg);
+       }
+  
+       inline command uint8_t Packet.maxPayloadLength()
+       {
+               return getMaxPayloadLength();
+       }
+  
+       command void* Packet.getPayload(message_t* msg, uint8_t len)
+       {
+               if( len > TOSH_DATA_LENGTH )
+                       return NULL;
+
+               return msg->data;
+       }
+
+/*----------------- PacketAcknowledgements -----------------*/
+
+       async command error_t PacketAcknowledgements.requestAck(message_t* msg)
+       {
+               call IEEE154Packet.setAckRequired(msg, TRUE);
+
+               return SUCCESS;
+       }
+
+       async command error_t PacketAcknowledgements.noAck(message_t* msg)
+       {
+               call IEEE154Packet.setAckRequired(msg, FALSE);
+
+               return SUCCESS;
+       }
+
+       async command bool PacketAcknowledgements.wasAcked(message_t* msg)
+       {
+               return getMeta(msg)->flags & DEFPACKET_WAS_ACKED;
+       }
+
+/*----------------- PacketLinkQuality -----------------*/
+
+       async command bool PacketLinkQuality.isSet(message_t* msg)
+       {
+               return TRUE;
+       }
+
+       async command uint8_t PacketLinkQuality.get(message_t* msg)
+       {
+               return getMeta(msg)->lqi;
+       }
+
+       async command void PacketLinkQuality.clear(message_t* msg)
+       {
+       }
+
+       async command void PacketLinkQuality.set(message_t* msg, uint8_t value)
+       {
+               getMeta(msg)->lqi = value;
+       }
+
+/*----------------- PacketTimeStamp -----------------*/
+
+       async command bool PacketTimeStamping.isSet(message_t* msg)
+       {
+               return getMeta(msg)->flags & DEFPACKET_TIMESTAMP;
+       }
+
+       async command uint16_t PacketTimeStamping.get(message_t* msg)
+       {
+               return getMeta(msg)->timestamp;
+       }
+
+       async command void PacketTimeStamping.clear(message_t* msg)
+       {
+               getMeta(msg)->flags &= ~DEFPACKET_TIMESTAMP;
+       }
+
+       async command void PacketTimeStamping.set(message_t* msg, uint16_t value)
+       {
+               getMeta(msg)->flags |= DEFPACKET_TIMESTAMP;
+               getMeta(msg)->timestamp = value;
+       }
+
+       inline async command bool PacketTimeStamp.isSet(message_t* msg)
+       {
+               return call PacketTimeStamping.isSet(msg);
+       }
+
+       inline async command uint16_t PacketTimeStamp.get(message_t* msg)
+       {
+               return call PacketTimeStamping.get(msg);
+       }
+
+       inline async command void PacketTimeStamp.clear(message_t* msg)
+       {
+               call PacketTimeStamping.clear(msg);
+       }
+
+       inline async command void PacketTimeStamp.set(message_t* msg, uint16_t value)
+       {
+               call PacketTimeStamping.set(msg, value);
+       }
+
+/*----------------- PacketTimeSynch -----------------*/
+
+       async command bool PacketTimeSynchron.isSet(message_t* msg)
+       {
+               // just sanity check if the length is not initialized
+               if( getPayloadLength(msg) > getMaxPayloadLength() )
+                       return FALSE;
+
+               return getFooter(msg)->timeoffset != DEFPACKET_INVALID_TIMEOFFSET;
+       }
+
+       async command uint16_t PacketTimeSynchron.get(message_t* msg)
+       {
+               return getFooter(msg)->timeoffset;
+       }
+
+       async command void PacketTimeSynchron.clear(message_t* msg)
+       {
+               // just sanity check if the length is not initialized
+               if( getPayloadLength(msg) <= getMaxPayloadLength() )
+                       getFooter(msg)->timeoffset = DEFPACKET_INVALID_TIMEOFFSET;
+       }
+
+       async command void PacketTimeSynchron.set(message_t* msg, uint16_t value)
+       {
+               if( getPayloadLength(msg) > getMaxPayloadLength() )
+                       return;
+
+               if( value == DEFPACKET_INVALID_TIMEOFFSET )
+                       ++value;
+
+               getFooter(msg)->timeoffset = value;
+       }
+
+       inline async command bool PacketTimeSynch.isSet(message_t* msg)
+       {
+               return call PacketTimeSynchron.isSet(msg);
+       }
+
+       inline async command uint16_t PacketTimeSynch.get(message_t* msg)
+       {
+               return call PacketTimeSynchron.get(msg);
+       }
+
+       inline async command void PacketTimeSynch.clear(message_t* msg)
+       {
+               call PacketTimeSynchron.clear(msg);
+       }
+
+       inline async command void PacketTimeSynch.set(message_t* msg, uint16_t value)
+       {
+               call PacketTimeSynchron.set(msg, value);
+       }
+
+/*----------------- Global fields -----------------*/
+
+       uint8_t flags;
+       enum
+       {
+               FLAG_TXPOWER = 0x01,
+       };
+
+       uint8_t transmitPower;
+
+/*----------------- PacketTransmitPower -----------------*/
+
+       async command bool PacketTransmitPower.isSet(message_t* msg)
+       {
+               return flags & FLAG_TXPOWER;
+       }
+
+       async command uint8_t PacketTransmitPower.get(message_t* msg)
+       {
+               return transmitPower;
+       }
+
+       async command void PacketTransmitPower.clear(message_t* msg)
+       {
+               flags &= ~FLAG_TXPOWER;
+       }
+
+       async command void PacketTransmitPower.set(message_t* msg, uint8_t value)
+       {
+               flags |= FLAG_TXPOWER;
+               transmitPower = value;
+       }
+}
index 76ef080b397e911e3f613a3df5c6373f5c79a93a..091b6cdc6c888ceafcded1bbbcbe5ac9b4032f51 100644 (file)
@@ -104,6 +104,7 @@ implementation
                
                s = state;
 
+               // change the state before so we can be reentered rom the event
                if( s == STATE_TURN_ON || s == STATE_TURN_OFF )
                        state = STATE_READY;
 
diff --git a/tos/chips/rf230/PacketField.nc b/tos/chips/rf230/PacketField.nc
new file mode 100644 (file)
index 0000000..3f90293
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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
+ */
+
+interface PacketField<value_type>
+{
+       /**
+        * Returns TRUE if the value is set for this message.
+        */
+       async command bool isSet(message_t* msg);
+
+       /**
+        * Returns the stored value of this field in the message. If the
+        * value is not set, then the returned value is undefined.
+        */
+       async command value_type get(message_t* msg);
+
+       /**
+        * Clears the isSet flag.
+        */
+       async command void clear(message_t* msg);
+
+       /**
+        * Sets the isSet false to TRUE and the time stamp value to the 
+        * specified value.
+        */
+       async command void set(message_t* msg, value_type value);
+}
index b45eea03abac873c589cc030b7323697d0c0e962..609d0a33fd6281192e1451b216dec8db8ead5521 100644 (file)
 interface PacketTimeStamp<precision_tag, size_type>
 {
        /**
-        * Returns TRUE if the time stamp stored in the message is valid. Under
-        * special circumstances the radio chip might not be able to correctly
-        * assign a precise time value to an incoming packet (e.g. under very 
-        * heavy traffic multiple interrupts can occur before they could b
-        * serviced, and even if capture registers are used, it is not possible 
-        * to get the time stamp for the first or last unserviced event), in
-        * which case the time stamp value should not be used.
+        * Returns TRUE if the time stamp stored in the metadata of the message 
+        * is valid. Under special circumstances the radio chip might not be 
+        * able to correctly assign a precise time value to an incoming packet 
+        * (e.g. under very heavy traffic multiple interrupts can occur befor
+        * they could be serviced, and even if capture registers are used, it 
+        * is not possible to get the time stamp for the first or last unserviced 
+        * event), in which case the time stamp value should not be used.
         */
        async command bool isSet(message_t* msg);
 
index 47b9051b4a9e8dc5ab1a689dad643f88ba6c7e9d..42ff676e2fe66a9c261fd6e3a687f73454429278 100644 (file)
 interface PacketTimeSynch<precision_tag, size_type>
 {
        /**
-        * This command should be called by the sender on packets used for sender- 
-        * receiver time synchronization. The eventTime parameter should be as 
-        * close to the current time as possible (precision and size of the stamp 
-        * permitting) to avoid large time synchronization errors resulting from
-        * the time skew between the clocks of the sender and receiver. The
-        * time difference between the sending time and eventTime is stored in 
-        * the message just before it is transmitted over the air.
-        */
-       async command void set(message_t* msg, size_type eventTime);
-
-       /**
-        * The recveive should call this method to ensure that the received time
-        * stamp is correct (for the same reason as for PacketTimeStamp.isSet).
-        * If this method returns TRUE, then the eventTime returned by the get
-        * command is correct.
+        * The recveiver should call this method to ensure that the received 
+        * message contains an embedded timestamp and that is correct (for the 
+        * same reason as for PacketTimeStamp.isSet). If this method returns 
+        * TRUE, then the eventTime returned by the get command is correct,
+        * and reflects the event time in the local clock of the receiver.
         */
        async command bool isSet(message_t* msg);
 
@@ -50,4 +40,20 @@ interface PacketTimeSynch<precision_tag, size_type>
         * correct.
         */
        async command size_type get(message_t* msg);
+
+       /**
+        * Clears the time stamp in the message. 
+        */
+       async command void clear(message_t* msg);
+
+       /**
+        * This command should be called by the sender on packets used for sender- 
+        * receiver time synchronization. The eventTime parameter should be as 
+        * close to the current time as possible (precision and size of the stamp 
+        * permitting) to avoid large time synchronization errors resulting from
+        * the time skew between the clocks of the sender and receiver. The
+        * time difference between the sending time and eventTime is stored in 
+        * the message just before it is transmitted over the air.
+        */
+       async command void set(message_t* msg, size_type eventTime);
 }
index 97d23928fd25b1e86db262f554d97f18a044976e..9f5f044cbf254fe9673be53d55eb0d6f46afb848 100644 (file)
@@ -45,16 +45,6 @@ interface RF230Config
         */
        async command uint8_t* getPayload(message_t* msg);
 
-       /**
-        * Sets the timestamp (when the message was sent or received)
-        */
-       async command void setTimestamp(message_t* msg, uint16_t time);
-
-       /**
-        * Sets the link quality indicator field for the received message
-        */
-       async command void setLinkQuality(message_t* msg, uint8_t lqi);
-
        /**
         * Gets the number of bytes we should read before the RadioReceive.header
         * event is fired. If the length of the packet is less than this amount, 
@@ -67,12 +57,6 @@ interface RF230Config
         */
        async command uint8_t getMaxLength();
 
-       /**
-        * Returns the transmit power for the given message, this must be a value 
-        * in the range [0, 15] which will be stored in the PHY_TX_PWR register.
-        */
-       async command uint8_t getTransmitPower(message_t* msg);
-
        /**
         * This command is used at power up to set the default channel.
         * The default CC2420 channel is 26.
index d50ce40a3cf2d4262a9780ea8186d521b8f73a77..596928a685096253e35c655e0cbd18af6bbed6cc 100644 (file)
@@ -25,8 +25,6 @@ configuration RF230LayerC
 {
        provides
        {
-               interface Init as PlatformInit @exactlyonce();
-
                interface RadioState;
                interface RadioSend;
                interface RadioReceive;
@@ -36,6 +34,10 @@ configuration RF230LayerC
        uses 
        {
                interface RF230Config;
+               interface PacketField<uint8_t> as PacketLinkQuality;
+               interface PacketField<uint8_t> as PacketTransmitPower;
+               interface PacketField<uint16_t> as PacketTimeStamping;
+               interface PacketField<uint16_t> as PacketTimeSynchron;
        }
 }
 
@@ -43,14 +45,16 @@ implementation
 {
        components RF230LayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC;
 
-       PlatformInit = RF230LayerP.PlatformInit;
-
        RadioState = RF230LayerP;
        RadioSend = RF230LayerP;
        RadioReceive = RF230LayerP;
        RadioCCA = RF230LayerP;
 
        RF230Config = RF230LayerP;
+       PacketLinkQuality = RF230LayerP.PacketLinkQuality;
+       PacketTransmitPower = RF230LayerP.PacketTransmitPower;
+       PacketTimeStamping = RF230LayerP.PacketTimeStamping;
+       PacketTimeSynchron = RF230LayerP.PacketTimeSynchron;
 
        RF230LayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
        RadioAlarmC.Alarm -> HplRF230C.Alarm;
@@ -73,4 +77,7 @@ implementation
 #endif
 
        MainC.SoftwareInit -> RF230LayerP.SoftwareInit;
+
+       components RealMainP;
+       RealMainP.PlatformInit -> RF230LayerP.PlatformInit;
 }
index e1d329800a6e9032b582f19a4d37767dff4fe9c0..c11a1729631847a2bc5ef02b1f35e3645897c528 100644 (file)
@@ -55,13 +55,16 @@ module RF230LayerP
                interface BusyWait<TMicro, uint16_t>;
 
                interface RF230Config;
+               interface PacketField<uint8_t> as PacketLinkQuality;
+               interface PacketField<uint16_t> as PacketTimeStamping;
+               interface PacketField<uint16_t> as PacketTimeSynchron;
+               interface PacketField<uint8_t> as PacketTransmitPower;
                interface Tasklet;
+               interface RadioAlarm;
 
 #ifdef RF230_DEBUG
                interface DiagMsg;
 #endif
-
-               interface RadioAlarm;
        }
 }
 
@@ -389,7 +392,9 @@ implementation
                writeRegister(RF230_TRX_STATE, RF230_PLL_ON);
 
                // do something useful, just to wait a little
-               length = call RF230Config.getTransmitPower(msg) & RF230_TX_PWR_MASK;
+               length = (call PacketTransmitPower.isSet(msg) ?
+                       call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK;
+
                if( length != txPower )
                {
                        txPower = length;
@@ -408,7 +413,7 @@ implementation
                atomic
                {
                        call SLP_TR.set();
-                       time = call RadioAlarm.getNow();
+                       time = call RadioAlarm.getNow() + TX_SFD_DELAY;
                }
                call SLP_TR.clr();
 
@@ -426,6 +431,10 @@ implementation
                // the FCS is atomatically generated
                length -= 2;
 
+               // calculate and embed the time offset
+               if( call PacketTimeSynchron.isSet(msg) )
+                       call PacketTimeSynchron.set(msg, call PacketTimeSynchron.get(msg) - time);
+
                do {
                        call HplRF230.spiSplitReadWrite(*(data++));
                }
@@ -467,8 +476,11 @@ implementation
                        return FAIL;
                }
 
-               time += TX_SFD_DELAY;
-               call RF230Config.setTimestamp(msg, time);
+               // TODO: be nicer for retransmissions
+               // clear the embedded time stamp field
+               call PacketTimeSynchron.clear(msg);
+
+               call PacketTimeStamping.set(msg, time);
 
                // wait for the TRX_END interrupt
                state = STATE_BUSY_TX_2_RX_ON;
@@ -545,7 +557,7 @@ implementation
                                crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));
                                crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));
 
-                               call RF230Config.setLinkQuality(rxMsg, call HplRF230.spiSplitRead());
+                               call PacketLinkQuality.set(rxMsg, call HplRF230.spiSplitRead());
                        }
                        else
                                crc = 1;
@@ -557,6 +569,10 @@ implementation
                state = STATE_RX_ON;
                cmd = CMD_NONE;
 
+               // we need a correct time stamp of the message
+               if( call PacketTimeSynchron.isSet(rxMsg) && call PacketTimeStamping.isSet(rxMsg) )
+                       call PacketTimeSynchron.set(rxMsg, call PacketTimeSynchron.get(rxMsg) + call PacketTimeStamping.get(rxMsg));
+
                // signal only if it has passed the CRC check
                if( crc == 0 )
                        rxMsg = signal RadioReceive.receive(rxMsg);
@@ -647,7 +663,11 @@ implementation
                                         * we could not be after a transmission, because then cmd = 
                                         * CMD_TRANSMIT.
                                         */
-                                       call RF230Config.setTimestamp(rxMsg, time - RX_SFD_DELAY);
+                                       if( irq == RF230_IRQ_RX_START ) // just to be cautious
+                                               call PacketTimeStamping.set(rxMsg, time - RX_SFD_DELAY);
+                                       else
+                                               call PacketTimeStamping.clear(rxMsg);
+
                                        cmd = CMD_RECEIVE;
                                }
                                else