From f460e224ffeb4ac0adf01bcf204c60e941d96285 Mon Sep 17 00:00:00 2001 From: devdj Date: Tue, 19 Aug 2008 10:28:02 +0000 Subject: [PATCH] Added support for timesync/timestamping according to TEPs 132/133, now supporting FTSP on mica2. --- tos/chips/cc1000/CC1000ActiveMessageC.nc | 11 +- tos/chips/cc1000/CC1000CsmaRadioC.nc | 29 +++- tos/chips/cc1000/CC1000Msg.h | 8 +- tos/chips/cc1000/CC1000SendReceiveP.nc | 117 ++++++++++++-- tos/chips/cc1000/CC1000TimeSyncMessage.h | 30 ++++ tos/chips/cc1000/CC1000TimeSyncMessageC.nc | 87 ++++++++++ tos/chips/cc1000/CC1000TimeSyncMessageP.nc | 178 +++++++++++++++++++++ tos/chips/cc1000/PacketTimeSyncOffset.nc | 63 ++++++++ tos/platforms/mica2/TimeSyncMessageC.nc | 74 +++++++++ 9 files changed, 576 insertions(+), 21 deletions(-) create mode 100644 tos/chips/cc1000/CC1000TimeSyncMessage.h create mode 100644 tos/chips/cc1000/CC1000TimeSyncMessageC.nc create mode 100644 tos/chips/cc1000/CC1000TimeSyncMessageP.nc create mode 100644 tos/chips/cc1000/PacketTimeSyncOffset.nc create mode 100644 tos/platforms/mica2/TimeSyncMessageC.nc diff --git a/tos/chips/cc1000/CC1000ActiveMessageC.nc b/tos/chips/cc1000/CC1000ActiveMessageC.nc index d35c243d..7c888373 100644 --- a/tos/chips/cc1000/CC1000ActiveMessageC.nc +++ b/tos/chips/cc1000/CC1000ActiveMessageC.nc @@ -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 as PacketTimeStamp32khz; + interface PacketTimeStamp as PacketTimeStampMilli; + interface PacketTimeSyncOffset; } } implementation { @@ -73,4 +75,7 @@ implementation { AM.amAddress -> Address; AM.Packet -> Radio; + PacketTimeStamp32khz = Radio; + PacketTimeStampMilli = Radio; + PacketTimeSyncOffset = Radio; } diff --git a/tos/chips/cc1000/CC1000CsmaRadioC.nc b/tos/chips/cc1000/CC1000CsmaRadioC.nc index faa5d80e..a0433366 100644 --- a/tos/chips/cc1000/CC1000CsmaRadioC.nc +++ b/tos/chips/cc1000/CC1000CsmaRadioC.nc @@ -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 as PacketTimeStamp32khz; + interface PacketTimeStamp 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; } diff --git a/tos/chips/cc1000/CC1000Msg.h b/tos/chips/cc1000/CC1000Msg.h index a2df2697..c106b7a0 100644 --- a/tos/chips/cc1000/CC1000Msg.h +++ b/tos/chips/cc1000/CC1000Msg.h @@ -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 diff --git a/tos/chips/cc1000/CC1000SendReceiveP.nc b/tos/chips/cc1000/CC1000SendReceiveP.nc index 24781e4f..61186cb6 100644 --- a/tos/chips/cc1000/CC1000SendReceiveP.nc +++ b/tos/chips/cc1000/CC1000SendReceiveP.nc @@ -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 as PacketTimeStamp32khz; + interface PacketTimeStamp as PacketTimeStampMilli; + interface PacketTimeSyncOffset; } uses { //interface PowerManagement; @@ -71,10 +74,21 @@ module CC1000SendReceiveP @safe() { interface CC1000Squelch; interface ReadNow as RssiRx; async command am_addr_t amAddress(); + + interface LocalTime as LocalTime32khz; + interface LocalTime 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 index 00000000..a744fd38 --- /dev/null +++ b/tos/chips/cc1000/CC1000TimeSyncMessage.h @@ -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 index 00000000..d370f842 --- /dev/null +++ b/tos/chips/cc1000/CC1000TimeSyncMessageC.nc @@ -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 +#include + +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 as PacketTimeStamp32khz; + interface PacketTimeStamp as PacketTimeStampMilli; + + interface TimeSyncAMSend as TimeSyncAMSend32khz[am_id_t id]; + interface TimeSyncPacket as TimeSyncPacket32khz; + + interface TimeSyncAMSend as TimeSyncAMSendMilli[am_id_t id]; + interface TimeSyncPacket 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 index 00000000..1590c52d --- /dev/null +++ b/tos/chips/cc1000/CC1000TimeSyncMessageP.nc @@ -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 as TimeSyncAMSend32khz[uint8_t id]; + interface TimeSyncAMSend as TimeSyncAMSendMilli[uint8_t id]; + interface Packet; + + interface TimeSyncPacket as TimeSyncPacket32khz; + interface TimeSyncPacket as TimeSyncPacketMilli; + } + + uses + { + interface AMSend as SubSend[uint8_t id]; + interface Packet as SubPacket; + + interface PacketTimeStamp as PacketTimeStamp32khz; + interface PacketTimeStamp as PacketTimeStampMilli; + interface PacketTimeSyncOffset; + + interface LocalTime as LocalTime32khz; + interface LocalTime 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 index 00000000..b3cef8c7 --- /dev/null +++ b/tos/chips/cc1000/PacketTimeSyncOffset.nc @@ -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 index 00000000..fa22a779 --- /dev/null +++ b/tos/platforms/mica2/TimeSyncMessageC.nc @@ -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 as PacketTimeStamp32khz; + interface PacketTimeStamp as PacketTimeStampMilli; + + interface TimeSyncAMSend as TimeSyncAMSend32khz[am_id_t id]; + interface TimeSyncPacket as TimeSyncPacket32khz; + + interface TimeSyncAMSend as TimeSyncAMSendMilli[am_id_t id]; + interface TimeSyncPacket 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; +} -- 2.39.2