+++ /dev/null
-/*
- * 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 PacketLastTouch
-{
- /**
- * Requests the touch event to be called back just before the message
- * transmission starts.
- */
- async command void request(message_t* msg);
-
- /**
- * Cancels any pending requests.
- */
- async command void cancel(message_t* msg);
-
- /**
- * Returns TRUE if the touch callback is already scheduled.
- */
- async command bool isPending(message_t* msg);
-
- /**
- * This event is called by the MAC layer when the tranmission of the
- * message starts (the SFD byte is already transmitted and the packet
- * is already time stamped). In this method the packet payload can be
- * updated. This method MUST do absolutely minimal processing, and
- * should complete in 1-2 microseconds.
- */
- async event void touch(message_t* msg);
-}
+++ /dev/null
-/*
- * 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 PacketTimeStamp<precision_tag, size_type>
-{
- /**
- * 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 before
- * 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);
-
- /**
- * Return the time stamp for the given message. Please check with the
- * isSet command if this value can be relied upon. If this command is
- * called after transmission, then the transmit time of the packet
- * is returned (the time when the frame synchronization byte was
- * transmitted). If this command is called after the message is received,
- * the tne receive time of the message is returned.
- */
- async command size_type get(message_t* msg);
-
- /**
- * Sets the isSet flag to FALSE.
- */
- 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, size_type value);
-}
interface PacketField<uint8_t> as PacketLinkQuality;
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketField<uint8_t> as PacketRSSI;
- interface PacketTimeStamp<TRF230, uint16_t>;
- interface PacketLastTouch;
+ interface PacketTimeStamp<TRF230, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
}
}
PacketLinkQuality = RF230PacketC.PacketLinkQuality;
PacketTransmitPower = RF230PacketC.PacketTransmitPower;
PacketRSSI = RF230PacketC.PacketRSSI;
- PacketTimeStamp = RF230PacketC.PacketTimeStamp;
+ PacketTimeStampRadio = RF230PacketC;
+ PacketTimeStampMilli = RF230PacketC;
LowPowerListening = LowPowerListeningLayerC;
- PacketLastTouch = RF230PacketC;
- RF230LayerC.lastTouch -> RF230PacketC.lastTouch;
-
components ActiveMessageLayerC;
#ifdef LOW_POWER_LISTENING
components LowPowerListeningLayerC;
CsmaLayerC -> RF230LayerC.RadioCCA;
RF230LayerC.RF230Config -> RF230ActiveMessageP;
- RF230LayerC.PacketLinkQuality -> RF230PacketC.PacketLinkQuality;
- RF230LayerC.PacketTransmitPower -> RF230PacketC.PacketTransmitPower;
- RF230LayerC.PacketRSSI -> RF230PacketC.PacketRSSI;
- RF230LayerC.PacketTimeStamp -> RF230PacketC.PacketTimeStamp;
}
interface RadioCCA;
}
- uses
- {
- interface RF230Config;
-
- interface PacketField<uint8_t> as PacketLinkQuality;
- interface PacketField<uint8_t> as PacketTransmitPower;
- interface PacketField<uint8_t> as PacketRSSI;
- interface PacketTimeStamp<TRF230, uint16_t>;
-
- async event void lastTouch(message_t* msg);
- }
+ uses interface RF230Config;
}
implementation
{
- components RF230LayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC;
+ components RF230LayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC, RF230PacketC, LocalTimeMicroC as LocalTimeRadioC;
RadioState = RF230LayerP;
RadioSend = RF230LayerP;
RadioCCA = RF230LayerP;
RF230Config = RF230LayerP;
- PacketLinkQuality = RF230LayerP.PacketLinkQuality;
- PacketTransmitPower = RF230LayerP.PacketTransmitPower;
- PacketRSSI = RF230LayerP.PacketRSSI;
- PacketTimeStamp = RF230LayerP.PacketTimeStamp;
+
+ RF230LayerP.PacketLinkQuality -> RF230PacketC.PacketLinkQuality;
+ RF230LayerP.PacketTransmitPower -> RF230PacketC.PacketTransmitPower;
+ RF230LayerP.PacketRSSI -> RF230PacketC.PacketRSSI;
+ RF230LayerP.PacketTimeSyncOffset -> RF230PacketC.PacketTimeSyncOffset;
+ RF230LayerP.PacketTimeStamp -> RF230PacketC;
+ RF230LayerP.LocalTime -> LocalTimeRadioC;
RF230LayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
RadioAlarmC.Alarm -> HplRF230C.Alarm;
RF230LayerP.Tasklet -> TaskletC;
RF230LayerP.BusyWait -> BusyWaitMicroC;
- lastTouch = RF230LayerP.lastTouch;
-
#ifdef RF230_DEBUG
components DiagMsgC;
RF230LayerP.DiagMsg -> DiagMsgC;
interface PacketField<uint8_t> as PacketLinkQuality;
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketField<uint8_t> as PacketRSSI;
- interface PacketTimeStamp<TRF230, uint16_t>;
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
+
+ interface PacketTimeStamp<TRF230, uint32_t>;
+ interface LocalTime<TRF230>;
interface RF230Config;
interface Tasklet;
interface RadioAlarm;
- async event void lastTouch(message_t* msg);
-
#ifdef RF230_DEBUG
interface DiagMsg;
#endif
uint8_t length;
uint8_t* data;
uint8_t header;
+ uint32_t time32;
if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq )
return EBUSY;
writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower);
}
+ time32 = call LocalTime.get();
+
// we have missed an incoming message in this short amount of time
if( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) != RF230_PLL_ON )
{
length -= header;
- // first upload the header
+ // first upload the header to gain some time
do {
call HplRF230.spiSplitReadWrite(*(data++));
}
while( --header != 0 );
- call PacketTimeStamp.set(msg, time);
- signal lastTouch(msg);
+ time32 += (int16_t)(time) - (int16_t)(time32);
+
+ if( call PacketTimeSyncOffset.isSet(msg) )
+ ((timesync_footer_t*)(msg->data + call PacketTimeSyncOffset.get(msg)))->time_offset += time32;
do {
call HplRF230.spiSplitReadWrite(*(data++));
}
#endif
+ if( call PacketTimeSyncOffset.isSet(msg) )
+ ((timesync_footer_t*)(msg->data + call PacketTimeSyncOffset.get(msg)))->time_offset -= time32;
+
+ call PacketTimeStamp.set(msg, time32);
+
// wait for the TRX_END interrupt
state = STATE_BUSY_TX_2_RX_ON;
cmd = CMD_TRANSMIT;
length = call RF230Config.getLength(rxMsg);
call DiagMsg.str("rx");
- call DiagMsg.uint16(call PacketTimeStamp.isSet(rxMsg) ? call PacketTimeStamp.get(rxMsg) : 0);
+ call DiagMsg.uint32(call PacketTimeStamp.isSet(rxMsg) ? call PacketTimeStamp.get(rxMsg) : 0);
call DiagMsg.uint16(call RadioAlarm.getNow());
call DiagMsg.uint8(crc != 0);
call DiagMsg.uint8(length);
timesync_footer_t timesync;
} rf230packet_footer_t;
-typedef nx_struct rf230packet_metadata_t
+typedef struct rf230packet_metadata_t
{
- nx_uint8_t flags;
- nx_uint8_t lqi;
- nx_uint8_t power; // shared between TXPOWER and RSSI
- nx_uint16_t timestamp;
+ uint8_t flags;
+ uint8_t lqi;
+ uint8_t power; // shared between TXPOWER and RSSI
+ uint32_t timestamp;
} rf230packet_metadata_t;
enum rf230packet_metadata_flags
{
RF230PACKET_WAS_ACKED = 0x01, // PacketAcknowledgements
RF230PACKET_TIMESTAMP = 0x02, // PacketTimeStamp
- RF230PACKET_LAST_TOUCH = 0x04, // PacketLastTouch.touch
- RF230PACKET_TXPOWER = 0x10, // PacketTransmitPower
- RF230PACKET_RSSI = 0x20, // PacketRSSI
+ RF230PACKET_TXPOWER = 0x04, // PacketTransmitPower
+ RF230PACKET_RSSI = 0x08, // PacketRSSI
+ RF230PACKET_TIMESYNC = 0x10, // PacketTimeSync (update timesync_footer)
RF230PACKET_CLEAR_METADATA = 0x00,
};
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketField<uint8_t> as PacketRSSI;
interface PacketField<uint16_t> as PacketSleepInterval;
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
- interface PacketTimeStamp<TRF230, uint16_t>;
- interface PacketLastTouch;
-
- async event void lastTouch(message_t* msg);
+ interface PacketTimeStamp<TRF230, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
}
}
implementation
{
- components RF230PacketP, IEEE154PacketC;
+ components RF230PacketP, IEEE154PacketC, LocalTimeMicroC, LocalTimeMilliC;
RF230PacketP.IEEE154Packet -> IEEE154PacketC;
+ RF230PacketP.LocalTimeRadio -> LocalTimeMicroC;
+ RF230PacketP.LocalTimeMilli -> LocalTimeMilliC;
Packet = RF230PacketP;
AMPacket = IEEE154PacketC;
- PacketAcknowledgements = RF230PacketP;
- PacketLinkQuality = RF230PacketP.PacketLinkQuality;
- PacketTransmitPower = RF230PacketP.PacketTransmitPower;
- PacketRSSI = RF230PacketP.PacketRSSI;
- PacketSleepInterval = RF230PacketP.PacketSleepInterval;
- PacketTimeStamp = RF230PacketP;
-
- PacketLastTouch = RF230PacketP;
- lastTouch = RF230PacketP;
+
+ PacketAcknowledgements = RF230PacketP;
+ PacketLinkQuality = RF230PacketP.PacketLinkQuality;
+ PacketTransmitPower = RF230PacketP.PacketTransmitPower;
+ PacketRSSI = RF230PacketP.PacketRSSI;
+ PacketSleepInterval = RF230PacketP.PacketSleepInterval;
+ PacketTimeSyncOffset = RF230PacketP.PacketTimeSyncOffset;
+
+ PacketTimeStampRadio = RF230PacketP;
+ PacketTimeStampMilli = RF230PacketP;
}
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketField<uint8_t> as PacketRSSI;
interface PacketField<uint16_t> as PacketSleepInterval;
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
- interface PacketTimeStamp<TRF230, uint16_t>;
- interface PacketLastTouch;
-
- async event void lastTouch(message_t* msg);
+ interface PacketTimeStamp<TRF230, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
}
uses
{
interface IEEE154Packet;
+
+ interface LocalTime<TRF230> as LocalTimeRadio;
+ interface LocalTime<TMilli> as LocalTimeMilli;
}
}
{
PACKET_LENGTH_INCREASE =
sizeof(rf230packet_header_t) - 1 // the 8-bit length field is not counted
- + sizeof(ieee154_footer_t), // the CRC is not stored in memory
+ + sizeof(ieee154_footer_t), // the CRC is not stored in memory
};
inline rf230packet_metadata_t* getMeta(message_t* msg)
getMeta(msg)->lqi = value;
}
-/*----------------- PacketTimeStamp -----------------*/
+/*----------------- PacketTimeStampRadio -----------------*/
- async command bool PacketTimeStamp.isSet(message_t* msg)
+ async command bool PacketTimeStampRadio.isValid(message_t* msg)
{
return getMeta(msg)->flags & RF230PACKET_TIMESTAMP;
}
- async command uint16_t PacketTimeStamp.get(message_t* msg)
+ async command uint32_t PacketTimeStampRadio.timestamp(message_t* msg)
{
return getMeta(msg)->timestamp;
}
- async command void PacketTimeStamp.clear(message_t* msg)
+ async command void PacketTimeStampRadio.clear(message_t* msg)
{
getMeta(msg)->flags &= ~RF230PACKET_TIMESTAMP;
}
- async command void PacketTimeStamp.set(message_t* msg, uint16_t value)
+ async command void PacketTimeStampRadio.set(message_t* msg, uint32_t value)
{
getMeta(msg)->flags |= RF230PACKET_TIMESTAMP;
getMeta(msg)->timestamp = value;
}
+/*----------------- PacketTimeStampMilli -----------------*/
+
+ async command bool PacketTimeStampMilli.isValid(message_t* msg)
+ {
+ return call PacketTimeStampRadio.isValid(msg);
+ }
+
+ async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
+ {
+ int32_t offset = call PacketTimeStampRadio.timestamp(msg) - call LocalTimeRadio.get();
+
+ // TODO: Make the shift constant configurable
+ return (offset >> 10) + call LocalTimeMilli.get();
+ }
+
+ async command void PacketTimeStampMilli.clear(message_t* msg)
+ {
+ call PacketTimeStampRadio.clear(msg);
+ }
+
+ async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
+ {
+ // TODO: Make the shift constant configurable
+ int32_t offset = (value - call LocalTimeMilli.get()) << 10;
+
+ call PacketTimeStampRadio.set(msg, offset + call LocalTimeRadio.get());
+ }
+
/*----------------- PacketTransmitPower -----------------*/
async command bool PacketTransmitPower.isSet(message_t* msg)
getMeta(msg)->power = value;
}
+/*----------------- PacketTimeSyncOffset -----------------*/
+
+ async command bool PacketTimeSyncOffset.isSet(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_TIMESYNC;
+ }
+
+ async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
+ {
+ return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE - sizeof(timesync_footer_t);
+ }
+
+ async command void PacketTimeSyncOffset.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_TIMESYNC;
+ }
+
+ async command void PacketTimeSyncOffset.set(message_t* msg, uint8_t value)
+ {
+ // the value is ignored, the offset always points to the timesync footer at the end of the payload
+ getMeta(msg)->flags |= RF230PACKET_TIMESYNC;
+ }
+
/*----------------- Global fields -----------------*/
norace uint8_t flags;
flags |= FLAG_SLEEPINT;
sleepInterval = value;
}
-
-/*----------------- PacketLastTouch -----------------*/
-
- async command void PacketLastTouch.request(message_t* msg)
- {
- getMeta(msg)->flags |= RF230PACKET_LAST_TOUCH;
- }
-
- async command void PacketLastTouch.cancel(message_t* msg)
- {
- getMeta(msg)->flags &= ~RF230PACKET_LAST_TOUCH;
- }
-
- async command bool PacketLastTouch.isPending(message_t* msg)
- {
- return getMeta(msg)->flags & RF230PACKET_LAST_TOUCH;
- }
-
- async event void lastTouch(message_t* msg)
- {
- if( getMeta(msg)->flags & RF230PACKET_LAST_TOUCH )
- signal PacketLastTouch.touch(msg);
- }
-
- default async event void PacketLastTouch.touch(message_t* msg)
- {
- }
}
typedef nx_struct timesync_footer_t
{
- nx_uint32_t time_offset; // in micorsec
+ nx_int32_t time_offset; // in micorsec
} timesync_footer_t;
#endif//__TIMESYNCMESSAGE_H__
#include <Timer.h>
#include <AM.h>
+#include <HplRF230.h>
configuration TimeSyncMessageC
{
interface Packet;
interface AMPacket;
- interface TimeSyncSend<TMicro> as TimeSyncSendMicro[am_id_t id];
- interface TimeSyncPacket<TMicro> as TimeSyncPacketMicro;
-// interface LocalTime<TMicro> as LocalTimeMicro;
+ interface TimeSyncAMSend<TRF230, uint32_t> as TimeSyncAMSendRadio[am_id_t id];
+ interface TimeSyncPacket<TRF230, uint32_t> as TimeSyncPacketRadio;
- interface TimeSyncSend<TMilli> as TimeSyncSendMilli[am_id_t id];
- interface TimeSyncPacket<TMilli> as TimeSyncPacketMilli;
- interface LocalTime<TMilli> as LocalTimeMilli;
-
- interface PacketTimeStamp<TMicro, uint16_t>;
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
}
}
implementation
{
- components TimeSyncMessageP, RF230ActiveMessageC, LocalTimeMilliC;
+ components TimeSyncMessageP, RF230ActiveMessageC, LocalTimeMilliC, LocalTimeMicroC as LocalTimeRadioC;
- TimeSyncSendMicro = TimeSyncMessageP;
- TimeSyncPacketMicro = TimeSyncMessageP;
-// LocalTimeMicro = LocalTimeMicroC;
+ TimeSyncAMSendRadio = TimeSyncMessageP;
+ TimeSyncPacketRadio = TimeSyncMessageP;
- TimeSyncSendMilli = TimeSyncMessageP;
+ TimeSyncAMSendMilli = TimeSyncMessageP;
TimeSyncPacketMilli = TimeSyncMessageP;
- LocalTimeMilli = LocalTimeMilliC;
Packet = TimeSyncMessageP;
TimeSyncMessageP.SubSend -> RF230ActiveMessageC.AMSend;
TimeSyncMessageP.SubPacket -> RF230ActiveMessageC.Packet;
- TimeSyncMessageP.PacketTimeStamp -> RF230ActiveMessageC;
+ TimeSyncMessageP.PacketTimeStampRadio -> RF230ActiveMessageC;
+ TimeSyncMessageP.PacketTimeStampMilli -> RF230ActiveMessageC;
+ TimeSyncMessageP.LocalTimeRadio -> LocalTimeRadioC;
TimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
- TimeSyncMessageP.PacketLastTouch -> RF230ActiveMessageC;
-
SplitControl = RF230ActiveMessageC;
Receive = RF230ActiveMessageC.Receive;
Snoop = RF230ActiveMessageC.Snoop;
AMPacket = RF230ActiveMessageC;
- PacketTimeStamp = RF230ActiveMessageC;
}
*/
#include <TimeSyncMessage.h>
+#include <HplRF230.h>
module TimeSyncMessageP
{
provides
{
- interface TimeSyncSend<TMicro> as TimeSyncSendMicro[uint8_t id];
- interface TimeSyncSend<TMilli> as TimeSyncSendMilli[uint8_t id];
+ interface TimeSyncAMSend<TRF230, uint32_t> as TimeSyncAMSendRadio[uint8_t id];
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
interface Packet;
- interface TimeSyncPacket<TMicro> as TimeSyncPacketMicro;
- interface TimeSyncPacket<TMilli> as TimeSyncPacketMilli;
+
+ interface TimeSyncPacket<TRF230, uint32_t> as TimeSyncPacketRadio;
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
}
uses
{
interface AMSend as SubSend[uint8_t id];
interface Packet as SubPacket;
- interface PacketTimeStamp<TMicro,uint16_t>; // TODO: change this to 32-bit
- interface PacketLastTouch;
- interface LocalTime<TMicro> as LocalTimeMicro;
+ interface PacketTimeStamp<TRF230, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+
+ interface LocalTime<TRF230> as LocalTimeRadio;
interface LocalTime<TMilli> as LocalTimeMilli;
}
}
implementation
{
-/*----------------- Packet -----------------*/
-
- typedef struct timesync_local_t
- {
- uint32_t event_time; // in microsec
- } timesync_local_t;
-
// TODO: change the Packet.payloadLength and Packet.maxPayloadLength commands to async
inline timesync_footer_t* getFooter(message_t* msg)
{
- return (timesync_footer_t*)(msg->data + call SubPacket.payloadLength(msg) - sizeof(timesync_footer_t));
+ // we use the payload length we export (the smaller one)
+ return (timesync_footer_t*)(msg->data + call Packet.payloadLength(msg));
}
- inline timesync_local_t* getLocal(message_t* msg)
- {
- return (timesync_local_t*)(msg->data + call SubPacket.maxPayloadLength() - sizeof(timesync_local_t));
- }
+/*----------------- Packet -----------------*/
command void Packet.clear(message_t* msg)
{
call SubPacket.clear(msg);
- call PacketLastTouch.cancel(msg); // TODO: check if we need to do this
}
command void Packet.setPayloadLength(message_t* msg, uint8_t len)
command uint8_t Packet.maxPayloadLength()
{
- return call SubPacket.maxPayloadLength() - sizeof(timesync_footer_t) - sizeof(timesync_local_t);
+ return call SubPacket.maxPayloadLength() - sizeof(timesync_footer_t);
}
command void* Packet.getPayload(message_t* msg, uint8_t len)
{
- return call SubPacket.getPayload(msg, len + sizeof(timesync_footer_t) + sizeof(timesync_local_t));
+ return call SubPacket.getPayload(msg, len + sizeof(timesync_footer_t));
}
-/*----------------- TimeSyncSendMicro -----------------*/
+/*----------------- TimeSyncAMSendRadio -----------------*/
- command error_t TimeSyncSendMicro.send[am_id_t id](uint32_t event_time, am_addr_t addr, message_t* msg, uint8_t len)
+ command error_t TimeSyncAMSendRadio.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
{
- timesync_local_t* local = getLocal(msg);
-
- local->event_time = event_time;
-
- call PacketLastTouch.request(msg);
+ timesync_footer_t* footer = (timesync_footer_t*)(msg->data + len);
+ footer->time_offset = (nx_int32_t)event_time;
return call SubSend.send[id](addr, msg, len + sizeof(timesync_footer_t));
}
- command error_t TimeSyncSendMicro.cancel[am_id_t id](message_t* msg)
+ command error_t TimeSyncAMSendRadio.cancel[am_id_t id](message_t* msg)
{
- call PacketLastTouch.cancel(msg);
return call SubSend.cancel[id](msg);
}
- default event void TimeSyncSendMicro.sendDone[am_id_t id](message_t* msg, error_t error)
+ default event void TimeSyncAMSendRadio.sendDone[am_id_t id](message_t* msg, error_t error)
{
}
- command uint8_t TimeSyncSendMicro.maxPayloadLength[am_id_t id]()
+ command uint8_t TimeSyncAMSendRadio.maxPayloadLength[am_id_t id]()
{
return call SubSend.maxPayloadLength[id]() - sizeof(timesync_footer_t);
}
- command void* TimeSyncSendMicro.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ command void* TimeSyncAMSendRadio.getPayload[am_id_t id](message_t* msg, uint8_t len)
{
return call SubSend.getPayload[id](msg, len + sizeof(timesync_footer_t));
}
-/*----------------- TimeSyncSendMilli -----------------*/
+/*----------------- TimeSyncAMSendMilli -----------------*/
- command error_t TimeSyncSendMilli.send[am_id_t id](uint32_t event_time, am_addr_t addr, message_t* msg, uint8_t len)
+ command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
{
- timesync_local_t* local = getLocal(msg);
-
// compute elapsed time in millisecond
- event_time = ((event_time - call LocalTimeMilli.get()) << 10) + call LocalTimeMicro.get();
-
- local->event_time = event_time;
-
- call PacketLastTouch.request(msg);
+ event_time = ((event_time - call LocalTimeMilli.get()) << 10) + call LocalTimeRadio.get();
- return call SubSend.send[id](addr, msg, len + sizeof(timesync_footer_t));
+ return call TimeSyncAMSendRadio.send[id](addr, msg, len, event_time);
}
- command error_t TimeSyncSendMilli.cancel[am_id_t id](message_t* msg)
+ command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
{
- return call SubSend.cancel[id](msg);
+ return call TimeSyncAMSendRadio.cancel[id](msg);
}
- default event void TimeSyncSendMilli.sendDone[am_id_t id](message_t* msg, error_t error)
+ default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error)
{
}
- command uint8_t TimeSyncSendMilli.maxPayloadLength[am_id_t id]()
+ command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
{
- return call SubSend.maxPayloadLength[id]() - sizeof(timesync_footer_t);
+ return call TimeSyncAMSendRadio.maxPayloadLength[id]();
}
- command void* TimeSyncSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
{
- return call SubSend.getPayload[id](msg, len + sizeof(timesync_footer_t));
+ return call TimeSyncAMSendRadio.getPayload[id](msg, len);
}
/*----------------- SubSend.sendDone -------------------*/
event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
{
- signal TimeSyncSendMicro.sendDone[id](msg, error);
- signal TimeSyncSendMilli.sendDone[id](msg, error);
+ signal TimeSyncAMSendRadio.sendDone[id](msg, error);
+ signal TimeSyncAMSendMilli.sendDone[id](msg, error);
}
- /*----------------- PacketLastTouch.touch -------------------*/
+ /*----------------- TimeSyncPacketRadio -----------------*/
- enum
- {
- TIMESYNC_INVALID_STAMP = 0x80000000L,
- };
-
- async event void PacketLastTouch.touch(message_t* msg)
- {
- timesync_footer_t* footer = footer = getFooter(msg);
- timesync_local_t* local;
-
- if( call PacketTimeStamp.isSet(msg) )
- {
- local = getLocal(msg);
-
- footer->time_offset = local->event_time - call PacketTimeStamp.get(msg);
- }
- else
- footer->time_offset = TIMESYNC_INVALID_STAMP;
- }
-
- /*----------------- TimeSyncPacketMicro -----------------*/
-
- async command bool TimeSyncPacketMicro.hasValidTime(message_t* msg)
+ async command bool TimeSyncPacketRadio.isValid(message_t* msg)
{
timesync_footer_t* footer = getFooter(msg);
- return call PacketTimeStamp.isSet(msg) && footer->time_offset != TIMESYNC_INVALID_STAMP;
+ return call PacketTimeStampRadio.isValid(msg) && footer->time_offset != 0x80000000L;
}
- async command uint32_t TimeSyncPacketMicro.getEventTime(message_t* msg)
+ async command uint32_t TimeSyncPacketRadio.eventTime(message_t* msg)
{
timesync_footer_t* footer = getFooter(msg);
- return (uint32_t)(footer->time_offset) + call PacketTimeStamp.get(msg);
+ return (int32_t)(footer->time_offset) + call PacketTimeStampRadio.timestamp(msg);
}
/*----------------- TimeSyncPacketMilli -----------------*/
- async command bool TimeSyncPacketMilli.hasValidTime(message_t* msg)
+ async command bool TimeSyncPacketMilli.isValid(message_t* msg)
{
timesync_footer_t* footer = getFooter(msg);
- return call PacketTimeStamp.isSet(msg) && footer->time_offset != TIMESYNC_INVALID_STAMP;
+ return call PacketTimeStampMilli.isValid(msg) && footer->time_offset != 0x80000000L;
}
- async command uint32_t TimeSyncPacketMilli.getEventTime(message_t* msg)
+ async command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
{
timesync_footer_t* footer = getFooter(msg);
- // time offset compared to now in microsec, important that this is signed
- int32_t elapsed = (uint32_t)(footer->time_offset) + call PacketTimeStamp.get(msg) - call LocalTimeMicro.get();
-
- return (elapsed >> 10) + call LocalTimeMilli.get();
+ return ((int32_t)(footer->time_offset) << 10) + call PacketTimeStampMilli.timestamp(msg);
}
}
+++ /dev/null
-/*
- * 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 TimeSyncPacket<precision_tag>
-{
- /**
- * Returns TRUE if the value returned by <tt>getTime</tt> can be trusted.
- * Under certain circumstances the received message cannot be properly
- * time stamped, so the sender-receiver synchronization cannot be finished
- * on the receiver side. In this case, this command returns FALSE.
- * This command MUST BE called only on the receiver side and only for
- * messages transmitted via the TimeSyncSend interface.
- */
- async command bool hasValidTime(message_t* msg);
-
- /**
- * This command should be called by the receiver of a message. The time
- * of the synchronization event is returned as expressed in the local
- * clock of the caller. This command MUST BE called only on the receiver
- * side and only for messages transmitted via the TimeSyncSend interface.
- */
- async command uint32_t getEventTime(message_t* msg);
-}
+++ /dev/null
-/*
- * 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 Philip Levis
- * @author Miklos Maroti
- *
- * @see TimeSyncPacket
- */
-
-#include <TinyError.h>
-#include <message.h>
-#include <AM.h>
-
-interface TimeSyncSend<precision_tag>
-{
- /**
- * This command sends a regular message just like <tt>AMSend.send</tt>, but
- * it also performs sender-receiver time synchronization. The <tt>event_time</tt>
- * parameter holds the time of some event as expressed in the local clock of
- * the sender. The receiver can obtain the time of this event (expressed in its
- * own local time) via the <tt>TimeSyncPacket</tt> interface.
- *
- * @param addr address to which to send the packet
- * @param msg the packet
- * @param len the length of the data in the packet payload
- * @param time the synchronization point to be transfered with the message
- * @return SUCCESS if the request to send succeeded and a
- * sendDone will be signaled later, EBUSY if the
- * abstraction cannot send now but will be able to
- * later, or FAIL if the communication layer is not
- * in a state that can send (e.g., off).
- * @see sendDone
- */
- command error_t send(uint32_t event_time, am_addr_t addr, message_t* msg, uint8_t len);
-
- /**
- * Cancel a requested transmission. Returns SUCCESS if the
- * transmission was canceled properly (not sent in its
- * entirety). Note that the component may not know
- * if the send was successfully canceled, if the radio is
- * handling much of the logic; in this case, a component
- * should be conservative and return an appropriate error code.
- * A successful call to cancel must always result in a
- * sendFailed event, and never a sendSucceeded event.
- *
- * @param msg the packet whose transmission should be cancelled.
- * @return SUCCESS if the transmission was cancelled, FAIL otherwise.
- * @see sendDone
- */
- command error_t cancel(message_t* msg);
-
- /**
- * Signaled in response to an accepted send request. <tt>msg</tt> is
- * the message buffer sent, and <tt>error</tt> indicates whether
- * the send was successful.
- *
- * @param msg the packet which was submitted as a send request
- * @param error SUCCESS if it was sent successfully, FAIL if it was not,
- * ECANCEL if it was cancelled
- * @see send
- * @see cancel
- */
- event void sendDone(message_t* msg, error_t error);
-
- /**
- * Return the maximum payload length that this communication layer
- * can provide. This command behaves identically to
- * <tt>Packet.maxPayloadLength</tt> and is included in this
- * interface as a convenience.
- *
- * @return the maximum payload length
- */
- command uint8_t maxPayloadLength();
-
- /**
- * Return a pointer to a protocol's payload region in a packet.
- * This command behaves identically to <tt>Packet.getPayload</tt>
- * (minus the length parameter) and is included in this interface
- * as a convenience.
- *
- * @param msg the packet
- * @return the payload of the packet
- */
- command void* getPayload(message_t* msg, uint8_t len);
-}
interface PacketAcknowledgements;
interface LowPowerListening;
- interface PacketTimeStamp<TMicro, uint16_t>;
+
+ interface PacketTimeStamp<TMicro, uint32_t> as PacketTimeStampMicro;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
}
}
Packet = MAC;
AMPacket = MAC;
- PacketAcknowledgements = MAC.PacketAcknowledgements;
- LowPowerListening = MAC.LowPowerListening;
- PacketTimeStamp = MAC.PacketTimeStamp;
+ PacketAcknowledgements = MAC;
+ LowPowerListening = MAC;
+ PacketTimeStampMilli = MAC;
+ PacketTimeStampMicro = MAC;
}
#include "Timer.h"
-configuration LocalTimeMilliC
+configuration LocalTimeMicroC
{
provides interface LocalTime<TMicro>;
}