#include <HplRF230.h>
#include <Tasklet.h>
#include <RadioAssert.h>
+#include <TimeSyncMessage.h>
module RF230LayerP
{
interface GeneralIO as SELN;
interface Resource as SpiResource;
- interface SpiByte;
+ interface FastSpiByte;
interface HplRF230;
interface GeneralIO as SLP_TR;
interface PacketField<uint8_t> as PacketRSSI;
interface PacketField<uint8_t> as PacketTimeSyncOffset;
- interface PacketTimeStamp<TRF230, uint32_t>;
- interface LocalTime<TRF230>;
+ interface PacketTimeStamp<TRadio, uint32_t>;
+ interface LocalTime<TRadio>;
interface RF230Config;
interface Tasklet;
ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) );
call SELN.clr();
- call HplRF230.spiSplitWrite(RF230_CMD_REGISTER_WRITE | reg);
- call HplRF230.spiSplitReadWrite(value);
- call HplRF230.spiSplitRead();
+ call FastSpiByte.splitWrite(RF230_CMD_REGISTER_WRITE | reg);
+ call FastSpiByte.splitReadWrite(value);
+ call FastSpiByte.splitRead();
call SELN.set();
}
ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) );
call SELN.clr();
- call HplRF230.spiSplitWrite(RF230_CMD_REGISTER_READ | reg);
- call HplRF230.spiSplitReadWrite(0);
- reg = call HplRF230.spiSplitRead();
+ call FastSpiByte.splitWrite(RF230_CMD_REGISTER_READ | reg);
+ call FastSpiByte.splitReadWrite(0);
+ reg = call FastSpiByte.splitRead();
call SELN.set();
return reg;
enum
{
- SLEEP_WAKEUP_TIME = (uint16_t)(880 * RF230_ALARM_MICROSEC),
- CCA_REQUEST_TIME = (uint16_t)(140 * RF230_ALARM_MICROSEC),
+ SLEEP_WAKEUP_TIME = (uint16_t)(880 * RF230_ALARM_SEC / 1000000UL),
+ CCA_REQUEST_TIME = (uint16_t)(140 * RF230_ALARM_SEC / 1000000UL),
- TX_SFD_DELAY = (uint16_t)(176 * RF230_ALARM_MICROSEC),
- RX_SFD_DELAY = (uint16_t)(8 * RF230_ALARM_MICROSEC),
+ TX_SFD_DELAY = (uint16_t)(176 * RF230_ALARM_SEC / 1000000UL),
+ RX_SFD_DELAY = (uint16_t)(8 * RF230_ALARM_SEC / 1000000UL),
};
tasklet_async event void RadioAlarm.fired()
/*----------------- CHANNEL -----------------*/
+ tasklet_async command uint8_t RadioState.getChannel()
+ {
+ return channel;
+ }
+
tasklet_async command error_t RadioState.setChannel(uint8_t c)
{
c &= RF230_CHANNEL_MASK;
readRegister(RF230_IRQ_STATUS); // clear the interrupt register
call IRQ.captureRisingEdge();
+ // setChannel was ignored in SLEEP because the SPI was not working, so do it here
+ writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel);
+
writeRegister(RF230_TRX_STATE, RF230_RX_ON);
state = STATE_TRX_OFF_2_RX_ON;
}
uint8_t* data;
uint8_t header;
uint32_t time32;
+ void* timesync;
if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq )
return EBUSY;
- if( call RF230Config.requiresRssiCca(msg)
- && (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) )
- return EBUSY;
-
- writeRegister(RF230_TRX_STATE, RF230_PLL_ON);
-
- // do something useful, just to wait a little
length = (call PacketTransmitPower.isSet(msg) ?
call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK;
writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower);
}
+ if( call RF230Config.requiresRssiCca(msg)
+ && (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) )
+ return EBUSY;
+
+ writeRegister(RF230_TRX_STATE, RF230_PLL_ON);
+
+ // do something useful, just to wait a little
time32 = call LocalTime.get();
+ timesync = call PacketTimeSyncOffset.isSet(msg) ? msg->data + call PacketTimeSyncOffset.get(msg) : 0;
// we have missed an incoming message in this short amount of time
if( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) != RF230_PLL_ON )
ASSERT( ! radioIrq );
call SELN.clr();
- call HplRF230.spiSplitWrite(RF230_CMD_FRAME_WRITE);
+ call FastSpiByte.splitWrite(RF230_CMD_FRAME_WRITE);
length = call RF230Config.getLength(msg);
data = call RF230Config.getPayload(msg);
// length | data[0] ... data[length-3] | automatically generated FCS
- call HplRF230.spiSplitReadWrite(length);
+ call FastSpiByte.splitReadWrite(length);
// the FCS is atomatically generated (2 bytes)
length -= 2;
// first upload the header to gain some time
do {
- call HplRF230.spiSplitReadWrite(*(data++));
+ call FastSpiByte.splitReadWrite(*(data++));
}
while( --header != 0 );
time32 += (int16_t)(time) - (int16_t)(time32);
- if( call PacketTimeSyncOffset.isSet(msg) )
- ((timesync_footer_t*)(msg->data + call PacketTimeSyncOffset.get(msg)))->time_offset += time32;
+ if( timesync != 0 )
+ *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32;
do {
- call HplRF230.spiSplitReadWrite(*(data++));
+ call FastSpiByte.splitReadWrite(*(data++));
}
while( --length != 0 );
// wait for the SPI transfer to finish
- call HplRF230.spiSplitRead();
+ call FastSpiByte.splitRead();
call SELN.set();
/*
}
#endif
- if( call PacketTimeSyncOffset.isSet(msg) )
- ((timesync_footer_t*)(msg->data + call PacketTimeSyncOffset.get(msg)))->time_offset -= time32;
+ if( timesync != 0 )
+ *(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32;
call PacketTimeStamp.set(msg, time32);
uint16_t crc;
call SELN.clr();
- call HplRF230.spiWrite(RF230_CMD_FRAME_READ);
+ call FastSpiByte.write(RF230_CMD_FRAME_READ);
// read the length byte
- length = call HplRF230.spiWrite(0);
+ length = call FastSpiByte.write(0);
// if correct length
if( length >= 3 && length <= call RF230Config.getMaxLength() )
uint8_t* data;
// initiate the reading
- call HplRF230.spiSplitWrite(0);
+ call FastSpiByte.splitWrite(0);
call RF230Config.setLength(rxMsg, length);
data = call RF230Config.getPayload(rxMsg);
length -= read;
do {
- crc = call HplRF230.crcByte(crc, *(data++) = call HplRF230.spiSplitReadWrite(0));
+ crc = call HplRF230.crcByte(crc, *(data++) = call FastSpiByte.splitReadWrite(0));
}
while( --read != 0 );
if( signal RadioReceive.header(rxMsg) )
{
while( length-- != 0 )
- crc = call HplRF230.crcByte(crc, *(data++) = call HplRF230.spiSplitReadWrite(0));
+ crc = call HplRF230.crcByte(crc, *(data++) = call FastSpiByte.splitReadWrite(0));
- crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));
- crc = call HplRF230.crcByte(crc, call HplRF230.spiSplitReadWrite(0));
+ crc = call HplRF230.crcByte(crc, call FastSpiByte.splitReadWrite(0));
+ crc = call HplRF230.crcByte(crc, call FastSpiByte.splitReadWrite(0));
- call PacketLinkQuality.set(rxMsg, call HplRF230.spiSplitRead());
+ call PacketLinkQuality.set(rxMsg, call FastSpiByte.splitRead());
}
else
crc = 1;
length = call RF230Config.getLength(rxMsg);
call DiagMsg.str("rx");
- call DiagMsg.uint32(call PacketTimeStamp.isSet(rxMsg) ? call PacketTimeStamp.get(rxMsg) : 0);
+ call DiagMsg.uint32(call PacketTimeStamp.isValid(rxMsg) ? call PacketTimeStamp.timestamp(rxMsg) : 0);
call DiagMsg.uint16(call RadioAlarm.getNow());
call DiagMsg.uint8(crc != 0);
call DiagMsg.uint8(length);
if( isSpiAcquired() )
{
uint16_t time;
+ uint32_t time32;
uint8_t irq;
uint8_t temp;
if( irq == RF230_IRQ_RX_START )
{
temp = readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK;
-
rssiBusy += temp - (rssiBusy >> 2);
-
-#ifdef RF230_RSSI_ENERGY
- temp = readRegister(RF230_PHY_ED_LEVEL);
-#endif
-
+#ifndef RF230_RSSI_ENERGY
call PacketRSSI.set(rxMsg, temp);
}
else
+ {
call PacketRSSI.clear(rxMsg);
+#endif
+ }
/*
* The timestamp corresponds to the first event which could not
* CMD_TRANSMIT.
*/
if( irq == RF230_IRQ_RX_START ) // just to be cautious
- call PacketTimeStamp.set(rxMsg, time - RX_SFD_DELAY);
+ {
+ time32 = call LocalTime.get();
+ time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32);
+ call PacketTimeStamp.set(rxMsg, time32);
+ }
else
call PacketTimeStamp.clear(rxMsg);
else if( cmd == CMD_RECEIVE )
{
ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );
-
+#ifdef RF230_RSSI_ENERGY
+ if( irq == RF230_IRQ_TRX_END )
+ call PacketRSSI.set(rxMsg, readRegister(RF230_PHY_ED_LEVEL));
+ else
+ call PacketRSSI.clear(rxMsg);
+#endif
if( state == STATE_PLL_ON_2_RX_ON )
{
ASSERT( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_PLL_ON );