X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=tos%2Fchips%2Frf2xx%2Frf230%2FRF230DriverLayerP.nc;h=114ac13dd4f4b206534b44330deb726662b11b96;hb=3c311f1b2729f43a356b02542a7001db623395e1;hp=c7e59fb2f89e0a1657f79a572839f773c6fa0877;hpb=7cb3053eaa216416d4833656f2ffbee14a5c0970;p=tinyos-2.x.git diff --git a/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc b/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc index c7e59fb2..114ac13d 100644 --- a/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc +++ b/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc @@ -21,10 +21,10 @@ * Author: Miklos Maroti */ -#include +#include #include #include -#include +#include #include module RF230DriverLayerP @@ -38,6 +38,12 @@ module RF230DriverLayerP interface RadioSend; interface RadioReceive; interface RadioCCA; + interface RadioPacket; + + interface PacketField as PacketTransmitPower; + interface PacketField as PacketRSSI; + interface PacketField as PacketTimeSyncOffset; + interface PacketField as PacketLinkQuality; } uses @@ -53,16 +59,16 @@ module RF230DriverLayerP interface GpioCapture as IRQ; interface BusyWait; + interface LocalTime; - interface PacketField as PacketLinkQuality; - interface PacketField as PacketTransmitPower; - interface PacketField as PacketRSSI; - interface PacketField as PacketTimeSyncOffset; + interface RF230DriverConfig as Config; + + interface PacketFlag as TransmitPowerFlag; + interface PacketFlag as RSSIFlag; + interface PacketFlag as TimeSyncFlag; interface PacketTimeStamp; - interface LocalTime; - interface RF230DriverConfig; interface Tasklet; interface RadioAlarm; @@ -74,6 +80,21 @@ module RF230DriverLayerP implementation { + rf230_header_t* getHeader(message_t* msg) + { + return ((void*)msg) + call Config.headerLength(msg); + } + + void* getPayload(message_t* msg) + { + return ((void*)msg) + call RadioPacket.headerLength(msg); + } + + rf230_metadata_t* getMeta(message_t* msg) + { + return ((void*)msg) + sizeof(message_t) - call RadioPacket.metadataLength(msg); + } + /*----------------- STATE -----------------*/ tasklet_norace uint8_t state; @@ -222,10 +243,10 @@ implementation writeRegister(RF230_IRQ_MASK, RF230_IRQ_TRX_UR | RF230_IRQ_PLL_LOCK | RF230_IRQ_TRX_END | RF230_IRQ_RX_START); writeRegister(RF230_CCA_THRES, RF230_CCA_THRES_VALUE); - writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | RF230_TX_PWR_DEFAULT); + writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | (RF230_DEF_RFPOWER & RF230_TX_PWR_MASK)); - txPower = RF230_TX_PWR_DEFAULT; - channel = call RF230DriverConfig.getDefaultChannel() & RF230_CHANNEL_MASK; + txPower = RF230_DEF_RFPOWER & RF230_TX_PWR_MASK; + channel = RF230_DEF_CHANNEL & RF230_CHANNEL_MASK; writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel); call SLP_TR.set(); @@ -414,7 +435,7 @@ implementation writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower); } - if( call RF230DriverConfig.requiresRssiCca(msg) + if( call Config.requiresRssiCca(msg) && (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) ) return EBUSY; @@ -422,7 +443,7 @@ implementation // do something useful, just to wait a little time32 = call LocalTime.get(); - timesync = call PacketTimeSyncOffset.isSet(msg) ? msg->data + call PacketTimeSyncOffset.get(msg) : 0; + timesync = call PacketTimeSyncOffset.isSet(msg) ? ((void*)msg) + 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 ) @@ -433,20 +454,22 @@ implementation return EBUSY; } +#ifndef RF230_SLOW_SPI atomic { call SLP_TR.set(); - time = call RadioAlarm.getNow() + TX_SFD_DELAY; + time = call RadioAlarm.getNow(); } call SLP_TR.clr(); +#endif ASSERT( ! radioIrq ); call SELN.clr(); call FastSpiByte.splitWrite(RF230_CMD_FRAME_WRITE); - length = call RF230DriverConfig.getLength(msg); - data = call RF230DriverConfig.getPayload(msg); + data = getPayload(msg); + length = getHeader(msg)->length; // length | data[0] ... data[length-3] | automatically generated FCS call FastSpiByte.splitReadWrite(length); @@ -454,7 +477,7 @@ implementation // the FCS is atomatically generated (2 bytes) length -= 2; - header = call RF230DriverConfig.getHeaderLength(); + header = call Config.headerPreloadLength(); if( header > length ) header = length; @@ -466,15 +489,22 @@ implementation } while( --header != 0 ); - time32 += (int16_t)(time) - (int16_t)(time32); +#ifdef RF230_SLOW_SPI + atomic + { + call SLP_TR.set(); + time = call RadioAlarm.getNow(); + } + call SLP_TR.clr(); +#endif + + time32 += (int16_t)(time + TX_SFD_DELAY) - (int16_t)(time32); if( timesync != 0 ) *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32; - do { + while( length-- != 0 ) call FastSpiByte.splitReadWrite(*(data++)); - } - while( --length != 0 ); // wait for the SPI transfer to finish call FastSpiByte.splitRead(); @@ -495,24 +525,25 @@ implementation // go back to RX_ON state when finished writeRegister(RF230_TRX_STATE, RF230_RX_ON); + if( timesync != 0 ) + *(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32; + + call PacketTimeStamp.set(msg, time32); + #ifdef RADIO_DEBUG_MESSAGES if( call DiagMsg.record() ) { - length = call RF230DriverConfig.getLength(msg); + length = getHeader(msg)->length; - call DiagMsg.str("tx"); - call DiagMsg.uint16(time); - call DiagMsg.uint8(length); - call DiagMsg.hex8s(data, length - 2); + call DiagMsg.chr('t'); + call DiagMsg.uint32(call PacketTimeStamp.isValid(rxMsg) ? call PacketTimeStamp.timestamp(rxMsg) : 0); + call DiagMsg.uint16(call RadioAlarm.getNow()); + call DiagMsg.int8(length); + call DiagMsg.hex8s(getPayload(msg), length - 2); call DiagMsg.send(); } #endif - if( timesync != 0 ) - *(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32; - - call PacketTimeStamp.set(msg, time32); - // wait for the TRX_END interrupt state = STATE_BUSY_TX_2_RX_ON; cmd = CMD_TRANSMIT; @@ -557,7 +588,7 @@ implementation length = call FastSpiByte.write(0); // if correct length - if( length >= 3 && length <= call RF230DriverConfig.getMaxLength() ) + if( length >= 3 && length <= call RadioPacket.maxPayloadLength() + 2 ) { uint8_t read; uint8_t* data; @@ -565,14 +596,14 @@ implementation // initiate the reading call FastSpiByte.splitWrite(0); - call RF230DriverConfig.setLength(rxMsg, length); - data = call RF230DriverConfig.getPayload(rxMsg); + data = getPayload(rxMsg); + getHeader(rxMsg)->length = length; crc = 0; // we do not store the CRC field length -= 2; - read = call RF230DriverConfig.getHeaderLength(); + read = call Config.headerPreloadLength(); if( length < read ) read = length; @@ -605,14 +636,15 @@ implementation #ifdef RADIO_DEBUG_MESSAGES if( call DiagMsg.record() ) { - length = call RF230DriverConfig.getLength(rxMsg); + length = getHeader(rxMsg)->length; - call DiagMsg.str("rx"); + call DiagMsg.chr('r'); 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); - call DiagMsg.hex8s(call RF230DriverConfig.getPayload(rxMsg), length - 2); + call DiagMsg.int8(crc == 0 ? length : -length); + call DiagMsg.hex8s(getPayload(rxMsg), length - 2); + call DiagMsg.int8(call PacketRSSI.isSet(rxMsg) ? call PacketRSSI.get(rxMsg) : -1); + call DiagMsg.uint8(call PacketLinkQuality.isSet(rxMsg) ? call PacketLinkQuality.get(rxMsg) : 0); call DiagMsg.send(); } #endif @@ -670,6 +702,17 @@ implementation } #endif +#ifdef RF230_RSSI_ENERGY + if( irq & RF230_IRQ_TRX_END ) + { + if( irq == RF230_IRQ_TRX_END || + (irq == (RF230_IRQ_RX_START | RF230_IRQ_TRX_END) && cmd == CMD_NONE) ) + call PacketRSSI.set(rxMsg, readRegister(RF230_PHY_ED_LEVEL)); + else + call PacketRSSI.clear(rxMsg); + } +#endif + if( irq & RF230_IRQ_PLL_LOCK ) { if( cmd == CMD_TURNON || cmd == CMD_CHANNEL ) @@ -752,12 +795,7 @@ implementation 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 ); @@ -818,4 +856,137 @@ implementation if( cmd == CMD_NONE ) call SpiResource.release(); } + +/*----------------- RadioPacket -----------------*/ + + async command uint8_t RadioPacket.headerLength(message_t* msg) + { + return call Config.headerLength(msg) + sizeof(rf230_header_t); + } + + async command uint8_t RadioPacket.payloadLength(message_t* msg) + { + return getHeader(msg)->length - 2; + } + + async command void RadioPacket.setPayloadLength(message_t* msg, uint8_t length) + { + ASSERT( 1 <= length && length <= 125 ); + ASSERT( call RadioPacket.headerLength(msg) + length + call RadioPacket.metadataLength(msg) <= sizeof(message_t) ); + + // we add the length of the CRC, which is automatically generated + getHeader(msg)->length = length + 2; + } + + async command uint8_t RadioPacket.maxPayloadLength() + { + ASSERT( call Config.maxPayloadLength() <= 125 ); + + return call Config.maxPayloadLength() - sizeof(rf230_header_t); + } + + async command uint8_t RadioPacket.metadataLength(message_t* msg) + { + return call Config.metadataLength(msg) + sizeof(rf230_metadata_t); + } + + async command void RadioPacket.clear(message_t* msg) + { + // all flags are automatically cleared + } + +/*----------------- PacketTransmitPower -----------------*/ + + async command bool PacketTransmitPower.isSet(message_t* msg) + { + return call TransmitPowerFlag.get(msg); + } + + async command uint8_t PacketTransmitPower.get(message_t* msg) + { + return getMeta(msg)->power; + } + + async command void PacketTransmitPower.clear(message_t* msg) + { + call TransmitPowerFlag.clear(msg); + } + + async command void PacketTransmitPower.set(message_t* msg, uint8_t value) + { + call TransmitPowerFlag.set(msg); + getMeta(msg)->power = value; + } + +/*----------------- PacketRSSI -----------------*/ + + async command bool PacketRSSI.isSet(message_t* msg) + { + return call RSSIFlag.get(msg); + } + + async command uint8_t PacketRSSI.get(message_t* msg) + { + return getMeta(msg)->rssi; + } + + async command void PacketRSSI.clear(message_t* msg) + { + call RSSIFlag.clear(msg); + } + + async command void PacketRSSI.set(message_t* msg, uint8_t value) + { + // just to be safe if the user fails to clear the packet + call TransmitPowerFlag.clear(msg); + + call RSSIFlag.set(msg); + getMeta(msg)->rssi = value; + } + +/*----------------- PacketTimeSyncOffset -----------------*/ + + async command bool PacketTimeSyncOffset.isSet(message_t* msg) + { + return call TimeSyncFlag.get(msg); + } + + async command uint8_t PacketTimeSyncOffset.get(message_t* msg) + { + return call RadioPacket.headerLength(msg) + call RadioPacket.payloadLength(msg) - sizeof(timesync_absolute_t); + } + + async command void PacketTimeSyncOffset.clear(message_t* msg) + { + call TimeSyncFlag.clear(msg); + } + + async command void PacketTimeSyncOffset.set(message_t* msg, uint8_t value) + { + // we do not store the value, the time sync field is always the last 4 bytes + ASSERT( call PacketTimeSyncOffset.get(msg) == value ); + + call TimeSyncFlag.set(msg); + } + +/*----------------- 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; + } }