interface PacketField<uint8_t> as PacketLinkQuality;
interface PacketTimeStamp<TRF230, uint16_t>;
+
+ interface PacketLastTouch;
}
}
PacketLinkQuality = DefaultPacketC.PacketLinkQuality;
PacketTimeStamp = DefaultPacketC.PacketTimeStamp;
+ PacketLastTouch = DefaultPacketC;
+ RF230LayerC.lastTouch -> DefaultPacketC.lastTouch;
+
components ActiveMessageLayerC;
components MessageBufferLayerC;
components UniqueLayerC;
async command void DummyConfig.nothing()
{
}
-
}
enum defpacket_metadata_flags
{
- DEFPACKET_WAS_ACKED = 0x01,
- DEFPACKET_TIMESTAMP = 0x02,
+ DEFPACKET_WAS_ACKED = 0x01, // PacketAcknowledgements
+ DEFPACKET_TIMESTAMP = 0x02, // PacketTimeStamp
+ DEFPACKET_LAST_TOUCH = 0x04, // PacketLastTouch.touch
DEFPACKET_CLEAR_METADATA = 0x00,
};
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketTimeStamp<TRF230, uint16_t>;
+ interface PacketLastTouch;
+
+ async event void lastTouch(message_t* msg);
}
}
PacketAcknowledgements = DefaultPacketP;
PacketLinkQuality = DefaultPacketP.PacketLinkQuality;
PacketTransmitPower = DefaultPacketP.PacketTransmitPower;
- PacketTimeStamp = DefaultPacketP.PacketTimeStamp;
+ PacketTimeStamp = DefaultPacketP;
+
+ PacketLastTouch = DefaultPacketP;
+ lastTouch = DefaultPacketP;
}
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketTimeStamp<TRF230, uint16_t>;
+ interface PacketLastTouch;
+
+ async event void lastTouch(message_t* msg);
}
uses
flags |= FLAG_TXPOWER;
transmitPower = value;
}
+
+/*----------------- PacketLastTouch -----------------*/
+
+ async command void PacketLastTouch.request(message_t* msg)
+ {
+ getMeta(msg)->flags |= DEFPACKET_LAST_TOUCH;
+ }
+
+ async command void PacketLastTouch.cancel(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~DEFPACKET_LAST_TOUCH;
+ }
+
+ async command bool PacketLastTouch.isPending(message_t* msg)
+ {
+ return getMeta(msg)->flags & DEFPACKET_LAST_TOUCH;
+ }
+
+ async event void lastTouch(message_t* msg)
+ {
+ if( getMeta(msg)->flags & DEFPACKET_LAST_TOUCH )
+ signal PacketLastTouch.touch(msg);
+ }
+
+ default async event void PacketLastTouch.touch(message_t* msg)
+ {
+ }
}
*/
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
+++ /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 PacketTimeSynch<precision_tag, size_type>
-{
- /**
- * 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);
-
- /**
- * This command should be called by the receiver. The time stamp of the
- * received message is added to the embedded time difference to get the
- * eventTime as measured by the clock of the receiver. The caller should
- * call the isSet command before to make sure that the returned time is
- * 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);
-}
/**
* 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,
- * then that event is fired earlier.
+ * then that event is fired earlier. The last touch event is not signaled
+ * for packets whose length is less than or equal to this header length.
+ * The header length must be at least 1.
*/
async command uint8_t getHeaderLength();
interface PacketField<uint8_t> as PacketLinkQuality;
interface PacketField<uint8_t> as PacketTransmitPower;
interface PacketTimeStamp<TRF230, uint16_t>;
+
+ async event void lastTouch(message_t* msg);
}
}
RF230LayerP.Tasklet -> TaskletC;
RF230LayerP.BusyWait -> BusyWaitMicroC;
+ lastTouch = RF230LayerP.lastTouch;
+
#ifdef RF230_DEBUG
components DiagMsgC;
RF230LayerP.DiagMsg -> DiagMsgC;
interface Tasklet;
interface RadioAlarm;
+ async event void lastTouch(message_t* msg);
+
#ifdef RF230_DEBUG
interface DiagMsg;
#endif
uint16_t time;
uint8_t length;
uint8_t* data;
+ uint8_t header;
if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq )
return EBUSY;
// length | data[0] ... data[length-3] | automatically generated FCS
call HplRF230.spiSplitReadWrite(length);
- // the FCS is atomatically generated
+ // the FCS is atomatically generated (2 bytes)
length -= 2;
+ header = call RF230Config.getHeaderLength();
+ if( header > length )
+ header = length;
+
+ length -= header;
+
+ // first upload the header
+ do {
+ call HplRF230.spiSplitReadWrite(*(data++));
+ }
+ while( --header != 0 );
+
+ call PacketTimeStamp.set(msg, time);
+ signal lastTouch(msg);
+
do {
call HplRF230.spiSplitReadWrite(*(data++));
}
length -= read;
- while( read-- != 0 )
+ do {
crc = call HplRF230.crcByte(crc, *(data++) = call HplRF230.spiSplitReadWrite(0));
+ }
+ while( --read != 0 );
if( signal RadioReceive.header(rxMsg) )
{
{
interface TimeSyncSend<TMicro> as TimeSyncSendMicro[am_id_t id];
interface TimeSyncPacket<TMicro> as TimeSyncPacketMicro;
- interface LocalTime<TMicro> as LocalTimeMicro;
+// interface LocalTime<TMicro> as LocalTimeMicro;
interface TimeSyncSend<TMilli> as TimeSyncSendMilli[am_id_t id];
interface TimeSyncPacket<TMilli> as TimeSyncPacketMilli;
TimeSyncSendMicro = TimeSyncMessageP;
TimeSyncPacketMicro = TimeSyncMessageP;
- LocalTimeMicro = ActiveMessageC;
+// LocalTimeMicro = LocalTimeMicroC;
TimeSyncSendMilli = TimeSyncMessageP;
TimeSyncPacketMilli = TimeSyncMessageP;
Packet = TimeSyncMessageP;
TimeSyncMessageP.SubSend -> ActiveMessageC.AMSend;
TimeSyncMessageP.SubPacket -> ActiveMessageC.Packet;
+ TimeSyncMessageP.PacketTimeStamp -> ActiveMessageC;
TimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
+ TimeSyncMessageP.PacketLastTouch -> ActiveMessageC;
+
SplitControl = ActiveMessageC;
Receive = ActiveMessageC.Receive;
Snoop = ActiveMessageC.Snoop;
{
interface AMSend as SubSend[uint8_t id];
interface Packet as SubPacket;
- interface PacketTimeStamp<TMicro,uint32_t>;
+ interface PacketTimeStamp<TMicro,uint16_t>; // TODO: change this to 32-bit
interface PacketLastTouch;
interface LocalTime<TMicro> as LocalTimeMicro;
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));
call PacketLastTouch.request(msg);
- return call SubSend.send[id](addr, msg, len);
+ return call SubSend.send[id](addr, msg, len + sizeof(timesync_footer_t));
}
command error_t TimeSyncSendMicro.cancel[am_id_t id](message_t* msg)
call PacketLastTouch.request(msg);
- return call SubSend.send[id](addr, msg, len);
+ return call SubSend.send[id](addr, msg, len + sizeof(timesync_footer_t));
}
command error_t TimeSyncSendMilli.cancel[am_id_t id](message_t* msg)
interface PacketAcknowledgements;
interface PacketField<uint8_t> as PacketLinkQuality;
interface PacketTimeStamp<TMicro, uint16_t>;
+ interface PacketLastTouch;
}
}
PacketAcknowledgements = MAC;
PacketLinkQuality = MAC;
PacketTimeStamp = MAC;
+ PacketLastTouch = MAC;
}
interface GpioCapture as IRQ;
interface Alarm<TRF230, uint16_t> as Alarm;
- interface LocalTime<TRF230>;
interface HplRF230;
}
components RealMainP;
RealMainP.PlatformInit -> HplRF230P.PlatformInit;
-
- components CounterOne16C;
- components new TransformCounterC(TRF230, uint32_t, TRF230, uint16_t, 0, uint32_t);
- components new CounterToLocalTimeC(TRF230);
-
- LocalTime = CounterToLocalTimeC;
- CounterToLocalTimeC.Counter -> TransformCounterC;
- TransformCounterC.CounterFrom -> CounterOne16C;
}