From: mmaroti Date: Sun, 8 Mar 2009 23:22:41 +0000 (+0000) Subject: rename everything to support the RF212 X-Git-Tag: rc_6_tinyos_2_1_1~475 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=d03b3dc553fa13fffcc3bfd7c4e00bf34e9cbcb8 rename everything to support the RF212 --- diff --git a/apps/tests/rf230/RF230Sniffer/RF230SnifferC.nc b/apps/tests/rf230/RF230Sniffer/RF230SnifferC.nc index 48958393..ce078455 100644 --- a/apps/tests/rf230/RF230Sniffer/RF230SnifferC.nc +++ b/apps/tests/rf230/RF230Sniffer/RF230SnifferC.nc @@ -27,15 +27,15 @@ configuration RF230SnifferC implementation { - components RF230SnifferP, MainC, SerialActiveMessageC, RF230LayerC, RF230ActiveMessageP, IEEE154PacketC, AssertC; + components RF230SnifferP, MainC, SerialActiveMessageC, RF2xxDriverLayerC, RF2xxActiveMessageP, IEEE154PacketC, AssertC; RF230SnifferP.Boot -> MainC; RF230SnifferP.SplitControl -> SerialActiveMessageC; - RF230SnifferP.RadioState -> RF230LayerC; + RF230SnifferP.RadioState -> RF2xxDriverLayerC; - RF230LayerC.RF230Config -> RF230ActiveMessageP; + RF2xxDriverLayerC.RF2xxDriverConfig -> RF2xxActiveMessageP; - RF230ActiveMessageP.IEEE154Packet -> IEEE154PacketC; + RF2xxActiveMessageP.IEEE154Packet -> IEEE154PacketC; // just to avoid a timer compilation bug components new TimerMilliC(); diff --git a/apps/tests/rf230/RF230Sniffer/RF230SnifferP.nc b/apps/tests/rf230/RF230Sniffer/RF230SnifferP.nc index 98bd7f7c..ca82c53f 100644 --- a/apps/tests/rf230/RF230Sniffer/RF230SnifferP.nc +++ b/apps/tests/rf230/RF230Sniffer/RF230SnifferP.nc @@ -21,7 +21,7 @@ * Author: Miklos Maroti */ -#include +#include #include #include diff --git a/apps/tests/rf230/RF230Test/RF230TestC.nc b/apps/tests/rf230/RF230Test/RF230TestC.nc index 27463abf..895e4f66 100644 --- a/apps/tests/rf230/RF230Test/RF230TestC.nc +++ b/apps/tests/rf230/RF230Test/RF230TestC.nc @@ -37,8 +37,8 @@ implementation RF230TestM.SplitControl -> SerialActiveMessageC; RF230TestM.Timer -> TimerMilliC; - components RF230LayerC, RF230ActiveMessageC; + components RF2xxDriverLayerC, RF2xxActiveMessageC; - RF230TestM.RadioState -> RF230LayerC; - RF230TestM.AMSend -> RF230ActiveMessageC; + RF230TestM.RadioState -> RF2xxDriverLayerC; + RF230TestM.AMSend -> RF2xxActiveMessageC; } diff --git a/tos/chips/rf230/RF230.h b/tos/chips/rf230/RF230.h deleted file mode 100644 index 781a1330..00000000 --- a/tos/chips/rf230/RF230.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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 __RF230_H__ -#define __RF230_H__ - -enum rf230_registers_enum -{ - RF230_TRX_STATUS = 0x01, - RF230_TRX_STATE = 0x02, - RF230_TRX_CTRL_0 = 0x03, - RF230_PHY_TX_PWR = 0x05, - RF230_PHY_RSSI = 0x06, - RF230_PHY_ED_LEVEL = 0x07, - RF230_PHY_CC_CCA = 0x08, - RF230_CCA_THRES = 0x09, - RF230_IRQ_MASK = 0x0E, - RF230_IRQ_STATUS = 0x0F, - RF230_VREG_CTRL = 0x10, - RF230_BATMON = 0x11, - RF230_XOSC_CTRL = 0x12, - RF230_PLL_CF = 0x1A, - RF230_PLL_DCU = 0x1B, - RF230_PART_NUM = 0x1C, - RF230_VERSION_NUM = 0x1D, - RF230_MAN_ID_0 = 0x1E, - RF230_MAN_ID_1 = 0x1F, - RF230_SHORT_ADDR_0 = 0x20, - RF230_SHORT_ADDR_1 = 0x21, - RF230_PAN_ID_0 = 0x22, - RF230_PAN_ID_1 = 0x23, - RF230_IEEE_ADDR_0 = 0x24, - RF230_IEEE_ADDR_1 = 0x25, - RF230_IEEE_ADDR_2 = 0x26, - RF230_IEEE_ADDR_3 = 0x27, - RF230_IEEE_ADDR_4 = 0x28, - RF230_IEEE_ADDR_5 = 0x29, - RF230_IEEE_ADDR_6 = 0x2A, - RF230_IEEE_ADDR_7 = 0x2B, - RF230_XAH_CTRL = 0x2C, - RF230_CSMA_SEED_0 = 0x2D, - RF230_CSMA_SEED_1 = 0x2E, -}; - -enum rf230_trx_register_enums -{ - RF230_CCA_DONE = 1 << 7, - RF230_CCA_STATUS = 1 << 6, - RF230_TRX_STATUS_MASK = 0x1F, - RF230_P_ON = 0, - RF230_BUSY_RX = 1, - RF230_BUSY_TX = 2, - RF230_RX_ON = 6, - RF230_TRX_OFF = 8, - RF230_PLL_ON = 9, - RF230_SLEEP = 15, - RF230_BUSY_RX_AACK = 16, - RF230_BUSR_TX_ARET = 17, - RF230_RX_AACK_ON = 22, - RF230_TX_ARET_ON = 25, - RF230_RX_ON_NOCLK = 28, - RF230_AACK_ON_NOCLK = 29, - RF230_BUSY_RX_AACK_NOCLK = 30, - RF230_STATE_TRANSITION_IN_PROGRESS = 31, - RF230_TRAC_STATUS_MASK = 0xE0, - RF230_TRAC_SUCCESS = 0, - RF230_TRAC_CHANNEL_ACCESS_FAILURE = 3 << 5, - RF230_TRAC_NO_ACK = 5 << 5, - RF230_TRX_CMD_MASK = 0x1F, - RF230_NOP = 0, - RF230_TX_START = 2, - RF230_FORCE_TRX_OFF = 3, -}; - -enum rf230_phy_register_enums -{ - RF230_TX_AUTO_CRC_ON = 1 << 7, - RF230_TX_PWR_MASK = 0x0F, - RF230_TX_PWR_DEFAULT = 0, - RF230_RSSI_MASK = 0x1F, - RF230_CCA_REQUEST = 1 << 7, - RF230_CCA_MODE_0 = 0 << 5, - RF230_CCA_MODE_1 = 1 << 5, - RF230_CCA_MODE_2 = 2 << 5, - RF230_CCA_MODE_3 = 3 << 5, - RF230_CHANNEL_DEFAULT = 11, - RF230_CHANNEL_MASK = 0x1F, - RF230_CCA_CS_THRES_SHIFT = 4, - RF230_CCA_ED_THRES_SHIFT = 0, -}; - -enum rf230_irq_register_enums -{ - RF230_IRQ_BAT_LOW = 1 << 7, - RF230_IRQ_TRX_UR = 1 << 6, - RF230_IRQ_TRX_END = 1 << 3, - RF230_IRQ_RX_START = 1 << 2, - RF230_IRQ_PLL_UNLOCK = 1 << 1, - RF230_IRQ_PLL_LOCK = 1 << 0, -}; - -enum rf230_control_register_enums -{ - RF230_AVREG_EXT = 1 << 7, - RF230_AVDD_OK = 1 << 6, - RF230_DVREG_EXT = 1 << 3, - RF230_DVDD_OK = 1 << 2, - RF230_BATMON_OK = 1 << 5, - RF230_BATMON_VHR = 1 << 4, - RF230_BATMON_VTH_MASK = 0x0F, - RF230_XTAL_MODE_OFF = 0 << 4, - RF230_XTAL_MODE_EXTERNAL = 4 << 4, - RF230_XTAL_MODE_INTERNAL = 15 << 4, -}; - -enum rf230_pll_register_enums -{ - RF230_PLL_CF_START = 1 << 7, - RF230_PLL_DCU_START = 1 << 7, -}; - -enum rf230_spi_command_enums -{ - RF230_CMD_REGISTER_READ = 0x80, - RF230_CMD_REGISTER_WRITE = 0xC0, - RF230_CMD_REGISTER_MASK = 0x3F, - RF230_CMD_FRAME_READ = 0x20, - RF230_CMD_FRAME_WRITE = 0x60, - RF230_CMD_SRAM_READ = 0x00, - RF230_CMD_SRAM_WRITE = 0x40, -}; - -#endif//__RF230_H__ diff --git a/tos/chips/rf230/RF230ActiveMessageC.nc b/tos/chips/rf230/RF230ActiveMessageC.nc deleted file mode 100644 index b0b641cc..00000000 --- a/tos/chips/rf230/RF230ActiveMessageC.nc +++ /dev/null @@ -1,148 +0,0 @@ -/* - * 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 - */ - -#include - -configuration RF230ActiveMessageC -{ - provides - { - interface SplitControl; - - interface AMSend[am_id_t id]; - interface Receive[am_id_t id]; - interface Receive as Snoop[am_id_t id]; - - interface Packet; - interface AMPacket; - interface PacketAcknowledgements; - interface LowPowerListening; - interface RadioChannel; - - interface PacketField as PacketLinkQuality; - interface PacketField as PacketTransmitPower; - interface PacketField as PacketRSSI; - - interface PacketTimeStamp as PacketTimeStampRadio; - interface PacketTimeStamp as PacketTimeStampMilli; - } -} - -implementation -{ - components RF230ActiveMessageP, RF230PacketC, IEEE154PacketC, RadioAlarmC; - -#ifdef RF230_DEBUG - components AssertC; -#endif - - RF230ActiveMessageP.IEEE154Packet -> IEEE154PacketC; - RF230ActiveMessageP.Packet -> RF230PacketC; - RF230ActiveMessageP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; - - Packet = RF230PacketC; - AMPacket = RF230PacketC; - PacketAcknowledgements = RF230PacketC; - PacketLinkQuality = RF230PacketC.PacketLinkQuality; - PacketTransmitPower = RF230PacketC.PacketTransmitPower; - PacketRSSI = RF230PacketC.PacketRSSI; - PacketTimeStampRadio = RF230PacketC; - PacketTimeStampMilli = RF230PacketC; - LowPowerListening = LowPowerListeningLayerC; - RadioChannel = MessageBufferLayerC; - - components ActiveMessageLayerC; -#ifdef TFRAMES_ENABLED - components new DummyLayerC() as IEEE154NetworkLayerC; -#else - components IEEE154NetworkLayerC; -#endif -#ifdef LOW_POWER_LISTENING - components LowPowerListeningLayerC; -#else - components new DummyLayerC() as LowPowerListeningLayerC; -#endif - components MessageBufferLayerC; - components UniqueLayerC; - components TrafficMonitorLayerC; -#ifdef RF230_SLOTTED_MAC - components SlottedCollisionLayerC as CollisionAvoidanceLayerC; -#else - components RandomCollisionLayerC as CollisionAvoidanceLayerC; -#endif - components SoftwareAckLayerC; - components new DummyLayerC() as CsmaLayerC; - components RF230LayerC; - - SplitControl = LowPowerListeningLayerC; - AMSend = ActiveMessageLayerC; - Receive = ActiveMessageLayerC.Receive; - Snoop = ActiveMessageLayerC.Snoop; - - ActiveMessageLayerC.Config -> RF230ActiveMessageP; - ActiveMessageLayerC.AMPacket -> IEEE154PacketC; - ActiveMessageLayerC.SubSend -> IEEE154NetworkLayerC; - ActiveMessageLayerC.SubReceive -> IEEE154NetworkLayerC; - - IEEE154NetworkLayerC.SubSend -> UniqueLayerC; - IEEE154NetworkLayerC.SubReceive -> LowPowerListeningLayerC; - - // the UniqueLayer is wired at two points - UniqueLayerC.Config -> RF230ActiveMessageP; - UniqueLayerC.SubSend -> LowPowerListeningLayerC; - - LowPowerListeningLayerC.SubControl -> MessageBufferLayerC; - LowPowerListeningLayerC.SubSend -> MessageBufferLayerC; - LowPowerListeningLayerC.SubReceive -> MessageBufferLayerC; -#ifdef LOW_POWER_LISTENING - LowPowerListeningLayerC.PacketSleepInterval -> RF230PacketC; - LowPowerListeningLayerC.IEEE154Packet -> IEEE154PacketC; - LowPowerListeningLayerC.PacketAcknowledgements -> RF230PacketC; -#endif - - MessageBufferLayerC.Packet -> RF230PacketC; - MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC; - MessageBufferLayerC.RadioReceive -> UniqueLayerC; - MessageBufferLayerC.RadioState -> TrafficMonitorLayerC; - - UniqueLayerC.SubReceive -> TrafficMonitorLayerC; - - TrafficMonitorLayerC.Config -> RF230ActiveMessageP; - TrafficMonitorLayerC.SubSend -> CollisionAvoidanceLayerC; - TrafficMonitorLayerC.SubReceive -> CollisionAvoidanceLayerC; - TrafficMonitorLayerC.SubState -> RF230LayerC; - - CollisionAvoidanceLayerC.Config -> RF230ActiveMessageP; - CollisionAvoidanceLayerC.SubSend -> SoftwareAckLayerC; - CollisionAvoidanceLayerC.SubReceive -> SoftwareAckLayerC; - - SoftwareAckLayerC.Config -> RF230ActiveMessageP; - SoftwareAckLayerC.SubSend -> CsmaLayerC; - SoftwareAckLayerC.SubReceive -> RF230LayerC; - - CsmaLayerC.Config -> RF230ActiveMessageP; - CsmaLayerC -> RF230LayerC.RadioSend; - CsmaLayerC -> RF230LayerC.RadioCCA; - - RF230LayerC.RF230Config -> RF230ActiveMessageP; -} diff --git a/tos/chips/rf230/RF230ActiveMessageP.nc b/tos/chips/rf230/RF230ActiveMessageP.nc deleted file mode 100644 index 23096286..00000000 --- a/tos/chips/rf230/RF230ActiveMessageP.nc +++ /dev/null @@ -1,298 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include - -module RF230ActiveMessageP -{ - provides - { - interface RF230Config; - interface SoftwareAckConfig; - interface UniqueConfig; - interface CsmaConfig; - interface TrafficMonitorConfig; - interface RandomCollisionConfig; - interface SlottedCollisionConfig; - interface ActiveMessageConfig; - interface DummyConfig; - } - - uses - { - interface IEEE154Packet; - interface Packet; - interface RadioAlarm; - } -} - -implementation -{ -/*----------------- RF230Config -----------------*/ - - async command uint8_t RF230Config.getLength(message_t* msg) - { - return call IEEE154Packet.getLength(msg); - } - - async command void RF230Config.setLength(message_t* msg, uint8_t len) - { - call IEEE154Packet.setLength(msg, len); - } - - async command uint8_t* RF230Config.getPayload(message_t* msg) - { - return ((uint8_t*)(call IEEE154Packet.getHeader(msg))) + 1; - } - - inline rf230packet_metadata_t* getMeta(message_t* msg) - { - return (rf230packet_metadata_t*)(msg->metadata); - } - - async command uint8_t RF230Config.getHeaderLength() - { - // we need the fcf, dsn, destpan and dest - return 7; - } - - async command uint8_t RF230Config.getMaxLength() - { - // note, that the ieee154_footer_t is not stored, but we should include it here - return sizeof(rf230packet_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t); - } - - async command uint8_t RF230Config.getDefaultChannel() - { - return RF230_DEF_CHANNEL; - } - - async command bool RF230Config.requiresRssiCca(message_t* msg) - { - return call IEEE154Packet.isDataFrame(msg); - } - -/*----------------- SoftwareAckConfig -----------------*/ - - async command bool SoftwareAckConfig.requiresAckWait(message_t* msg) - { - return call IEEE154Packet.requiresAckWait(msg); - } - - async command bool SoftwareAckConfig.isAckPacket(message_t* msg) - { - return call IEEE154Packet.isAckFrame(msg); - } - - async command bool SoftwareAckConfig.verifyAckPacket(message_t* data, message_t* ack) - { - return call IEEE154Packet.verifyAckReply(data, ack); - } - - async command bool SoftwareAckConfig.requiresAckReply(message_t* msg) - { - return call IEEE154Packet.requiresAckReply(msg); - } - - async command void SoftwareAckConfig.createAckPacket(message_t* data, message_t* ack) - { - call IEEE154Packet.createAckReply(data, ack); - } - - async command void SoftwareAckConfig.setAckReceived(message_t* msg, bool acked) - { - if( acked ) - getMeta(msg)->flags |= RF230PACKET_WAS_ACKED; - else - getMeta(msg)->flags &= ~RF230PACKET_WAS_ACKED; - } - - async command uint16_t SoftwareAckConfig.getAckTimeout() - { - return (uint16_t)(800 * RADIO_ALARM_MICROSEC); - } - - tasklet_async command void SoftwareAckConfig.reportChannelError() - { - signal TrafficMonitorConfig.channelError(); - } - -/*----------------- UniqueConfig -----------------*/ - - async command uint8_t UniqueConfig.getSequenceNumber(message_t* msg) - { - return call IEEE154Packet.getDSN(msg); - } - - async command void UniqueConfig.setSequenceNumber(message_t* msg, uint8_t dsn) - { - call IEEE154Packet.setDSN(msg, dsn); - } - - async command am_addr_t UniqueConfig.getSender(message_t* msg) - { - return call IEEE154Packet.getSrcAddr(msg); - } - - tasklet_async command void UniqueConfig.reportChannelError() - { - signal TrafficMonitorConfig.channelError(); - } - -/*----------------- ActiveMessageConfig -----------------*/ - - command error_t ActiveMessageConfig.checkPacket(message_t* msg) - { - // the user forgot to call clear, we should return EINVAL - if( ! call IEEE154Packet.isDataFrame(msg) ) - call Packet.clear(msg); - - return SUCCESS; - } - -/*----------------- CsmaConfig -----------------*/ - - async command bool CsmaConfig.requiresSoftwareCCA(message_t* msg) - { - return call IEEE154Packet.isDataFrame(msg); - } - -/*----------------- TrafficMonitorConfig -----------------*/ - - enum - { - TRAFFIC_UPDATE_PERIOD = 100, // in milliseconds - TRAFFIC_MAX_BYTES = (uint16_t)(TRAFFIC_UPDATE_PERIOD * 1000UL / 32), // 3125 - }; - - async command uint16_t TrafficMonitorConfig.getUpdatePeriod() - { - return TRAFFIC_UPDATE_PERIOD; - } - - async command uint16_t TrafficMonitorConfig.getChannelTime(message_t* msg) - { - /* We count in bytes, one byte is 32 microsecond. We are conservative here. - * - * pure airtime: preable (4 bytes), SFD (1 byte), length (1 byte), payload + CRC (len bytes) - * frame separation: 5-10 bytes - * ack required: 8-16 byte separation, 11 bytes airtime, 5-10 bytes separation - */ - - uint8_t len = call IEEE154Packet.getLength(msg); - return call IEEE154Packet.getAckRequired(msg) ? len + 6 + 16 + 11 + 10 : len + 6 + 10; - } - - async command am_addr_t TrafficMonitorConfig.getSender(message_t* msg) - { - return call IEEE154Packet.getSrcAddr(msg); - } - - tasklet_async command void TrafficMonitorConfig.timerTick() - { - signal SlottedCollisionConfig.timerTick(); - } - -/*----------------- RandomCollisionConfig -----------------*/ - - /* - * We try to use the same values as in CC2420 - * - * CC2420_MIN_BACKOFF = 10 jiffies = 320 microsec - * CC2420_BACKOFF_PERIOD = 10 jiffies - * initial backoff = 0x1F * CC2420_BACKOFF_PERIOD = 310 jiffies = 9920 microsec - * congestion backoff = 0x7 * CC2420_BACKOFF_PERIOD = 70 jiffies = 2240 microsec - */ - - async command uint16_t RandomCollisionConfig.getMinimumBackoff() - { - return (uint16_t)(320 * RADIO_ALARM_MICROSEC); - } - - async command uint16_t RandomCollisionConfig.getInitialBackoff(message_t* msg) - { - return (uint16_t)(9920 * RADIO_ALARM_MICROSEC); - } - - async command uint16_t RandomCollisionConfig.getCongestionBackoff(message_t* msg) - { - return (uint16_t)(2240 * RADIO_ALARM_MICROSEC); - } - - async command uint16_t RandomCollisionConfig.getTransmitBarrier(message_t* msg) - { - uint16_t time; - - // TODO: maybe we should use the embedded timestamp of the message - time = call RadioAlarm.getNow(); - - // estimated response time (download the message, etc) is 5-8 bytes - if( call IEEE154Packet.requiresAckReply(msg) ) - time += (uint16_t)(32 * (-5 + 16 + 11 + 5) * RADIO_ALARM_MICROSEC); - else - time += (uint16_t)(32 * (-5 + 5) * RADIO_ALARM_MICROSEC); - - return time; - } - - tasklet_async event void RadioAlarm.fired() { } - -/*----------------- SlottedCollisionConfig -----------------*/ - - async command uint16_t SlottedCollisionConfig.getInitialDelay() - { - return 300; - } - - async command uint8_t SlottedCollisionConfig.getScheduleExponent() - { - return 11; - } - - async command uint16_t SlottedCollisionConfig.getTransmitTime(message_t* msg) - { - // TODO: check if the timestamp is correct - return getMeta(msg)->timestamp; - } - - async command uint16_t SlottedCollisionConfig.getCollisionWindowStart(message_t* msg) - { - // the preamble (4 bytes), SFD (1 byte), plus two extra for safety - return getMeta(msg)->timestamp - (uint16_t)(7 * 32 * RADIO_ALARM_MICROSEC); - } - - async command uint16_t SlottedCollisionConfig.getCollisionWindowLength(message_t* msg) - { - return (uint16_t)(2 * 7 * 32 * RADIO_ALARM_MICROSEC); - } - - default tasklet_async event void SlottedCollisionConfig.timerTick() { } - -/*----------------- Dummy -----------------*/ - - async command void DummyConfig.nothing() - { - } -} diff --git a/tos/chips/rf230/RF230Config.nc b/tos/chips/rf230/RF230Config.nc deleted file mode 100644 index 2662a928..00000000 --- a/tos/chips/rf230/RF230Config.nc +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 - */ - -/** - * This interface needs to be implemented by the MAC to control the behaviour - * of the RF230LayerC component. - */ -interface RF230Config -{ - /** - * Returns the length of the PHY payload (including the FCF field). - * This value must be in the range [3, 127]. - */ - async command uint8_t getLength(message_t* msg); - - /** - * Sets the length of the PHY payload. - */ - async command void setLength(message_t* msg, uint8_t len); - - /** - * Returns a pointer to the start of the PHY payload that contains - * getLength()-2 number of bytes. The FCF field (CRC-16) is not stored, - * but automatically appended / verified. - */ - async command uint8_t* getPayload(message_t* msg); - - /** - * 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. The header length must be at least one. - */ - async command uint8_t getHeaderLength(); - - /** - * Returns the maximum PHY length that can be set via the setLength command - */ - async command uint8_t getMaxLength(); - - /** - * This command is used at power up to set the default channel. - * The default CC2420 channel is 26. - */ - async command uint8_t getDefaultChannel(); - - /** - * Returns TRUE if before sending this message we should make sure that - * the channel is clear via a very basic (and quick) RSSI check. - */ - async command bool requiresRssiCca(message_t* msg); -} diff --git a/tos/chips/rf230/RF230LayerC.nc b/tos/chips/rf230/RF230LayerC.nc deleted file mode 100644 index a89a808f..00000000 --- a/tos/chips/rf230/RF230LayerC.nc +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 - */ - -configuration RF230LayerC -{ - provides - { - interface RadioState; - interface RadioSend; - interface RadioReceive; - interface RadioCCA; - } - - uses interface RF230Config; -} - -implementation -{ - components RF230LayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC, RF230PacketC, LocalTimeMicroC as LocalTimeRadioC; - - RadioState = RF230LayerP; - RadioSend = RF230LayerP; - RadioReceive = RF230LayerP; - RadioCCA = RF230LayerP; - - RF230Config = RF230LayerP; - - 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.SELN -> HplRF230C.SELN; - RF230LayerP.SpiResource -> HplRF230C.SpiResource; - RF230LayerP.FastSpiByte -> HplRF230C; - - RF230LayerP.SLP_TR -> HplRF230C.SLP_TR; - RF230LayerP.RSTN -> HplRF230C.RSTN; - - RF230LayerP.IRQ -> HplRF230C.IRQ; - RF230LayerP.Tasklet -> TaskletC; - RF230LayerP.BusyWait -> BusyWaitMicroC; - -#ifdef RF230_DEBUG - components DiagMsgC; - RF230LayerP.DiagMsg -> DiagMsgC; -#endif - - MainC.SoftwareInit -> RF230LayerP.SoftwareInit; - - components RealMainP; - RealMainP.PlatformInit -> RF230LayerP.PlatformInit; -} diff --git a/tos/chips/rf230/RF230LayerP.nc b/tos/chips/rf230/RF230LayerP.nc deleted file mode 100644 index fb429b93..00000000 --- a/tos/chips/rf230/RF230LayerP.nc +++ /dev/null @@ -1,822 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include -#include -#include -#include - -module RF230LayerP -{ - provides - { - interface Init as PlatformInit @exactlyonce(); - interface Init as SoftwareInit @exactlyonce(); - - interface RadioState; - interface RadioSend; - interface RadioReceive; - interface RadioCCA; - } - - uses - { - interface GeneralIO as SELN; - interface Resource as SpiResource; - - interface FastSpiByte; - - interface GeneralIO as SLP_TR; - interface GeneralIO as RSTN; - - interface GpioCapture as IRQ; - - interface BusyWait; - - interface PacketField as PacketLinkQuality; - interface PacketField as PacketTransmitPower; - interface PacketField as PacketRSSI; - interface PacketField as PacketTimeSyncOffset; - - interface PacketTimeStamp; - interface LocalTime; - - interface RF230Config; - interface Tasklet; - interface RadioAlarm; - -#ifdef RF230_DEBUG - interface DiagMsg; -#endif - } -} - -implementation -{ -/*----------------- STATE -----------------*/ - - tasklet_norace uint8_t state; - enum - { - STATE_P_ON = 0, - STATE_SLEEP = 1, - STATE_SLEEP_2_TRX_OFF = 2, - STATE_TRX_OFF = 3, - STATE_TRX_OFF_2_RX_ON = 4, - STATE_RX_ON = 5, - STATE_BUSY_TX_2_RX_ON = 6, - STATE_PLL_ON_2_RX_ON = 7, - }; - - tasklet_norace uint8_t cmd; - enum - { - CMD_NONE = 0, // the state machine has stopped - CMD_TURNOFF = 1, // goto SLEEP state - CMD_STANDBY = 2, // goto TRX_OFF state - CMD_TURNON = 3, // goto RX_ON state - CMD_TRANSMIT = 4, // currently transmitting a message - CMD_RECEIVE = 5, // currently receiving a message - CMD_CCA = 6, // performing clear chanel assesment - CMD_CHANNEL = 7, // changing the channel - CMD_SIGNAL_DONE = 8, // signal the end of the state transition - CMD_DOWNLOAD = 9, // download the received message - }; - - norace bool radioIrq; - - tasklet_norace uint8_t txPower; - tasklet_norace uint8_t channel; - - tasklet_norace message_t* rxMsg; - message_t rxMsgBuffer; - - uint16_t capturedTime; // the current time when the last interrupt has occured - - tasklet_norace uint8_t rssiClear; - tasklet_norace uint8_t rssiBusy; - -/*----------------- REGISTER -----------------*/ - - inline void writeRegister(uint8_t reg, uint8_t value) - { - ASSERT( call SpiResource.isOwner() ); - ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) ); - - call SELN.clr(); - call FastSpiByte.splitWrite(RF230_CMD_REGISTER_WRITE | reg); - call FastSpiByte.splitReadWrite(value); - call FastSpiByte.splitRead(); - call SELN.set(); - } - - inline uint8_t readRegister(uint8_t reg) - { - ASSERT( call SpiResource.isOwner() ); - ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) ); - - call SELN.clr(); - call FastSpiByte.splitWrite(RF230_CMD_REGISTER_READ | reg); - call FastSpiByte.splitReadWrite(0); - reg = call FastSpiByte.splitRead(); - call SELN.set(); - - return reg; - } - -/*----------------- ALARM -----------------*/ - - enum - { - SLEEP_WAKEUP_TIME = (uint16_t)(880 * RADIO_ALARM_MICROSEC), - CCA_REQUEST_TIME = (uint16_t)(140 * RADIO_ALARM_MICROSEC), - - TX_SFD_DELAY = (uint16_t)(176 * RADIO_ALARM_MICROSEC), - RX_SFD_DELAY = (uint16_t)(8 * RADIO_ALARM_MICROSEC), - }; - - tasklet_async event void RadioAlarm.fired() - { - if( state == STATE_SLEEP_2_TRX_OFF ) - state = STATE_TRX_OFF; - else if( cmd == CMD_CCA ) - { - uint8_t cca; - - ASSERT( state == STATE_RX_ON ); - - cmd = CMD_NONE; - cca = readRegister(RF230_TRX_STATUS); - - ASSERT( (cca & RF230_TRX_STATUS_MASK) == RF230_RX_ON ); - - signal RadioCCA.done( (cca & RF230_CCA_DONE) ? ((cca & RF230_CCA_STATUS) ? SUCCESS : EBUSY) : FAIL ); - } - else - ASSERT(FALSE); - - // make sure the rest of the command processing is called - call Tasklet.schedule(); - } - -/*----------------- INIT -----------------*/ - - command error_t PlatformInit.init() - { - call SELN.makeOutput(); - call SELN.set(); - call SLP_TR.makeOutput(); - call SLP_TR.clr(); - call RSTN.makeOutput(); - call RSTN.set(); - - rxMsg = &rxMsgBuffer; - - // these are just good approximates - rssiClear = 0; - rssiBusy = 90; - - return SUCCESS; - } - - command error_t SoftwareInit.init() - { - // for powering up the radio - return call SpiResource.request(); - } - - void initRadio() - { - call BusyWait.wait(510); - - call RSTN.clr(); - call SLP_TR.clr(); - call BusyWait.wait(6); - call RSTN.set(); - - writeRegister(RF230_TRX_CTRL_0, RF230_TRX_CTRL_0_VALUE); - writeRegister(RF230_TRX_STATE, RF230_TRX_OFF); - - call BusyWait.wait(510); - - 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); - - txPower = RF230_TX_PWR_DEFAULT; - channel = call RF230Config.getDefaultChannel() & RF230_CHANNEL_MASK; - writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel); - - call SLP_TR.set(); - state = STATE_SLEEP; - } - -/*----------------- SPI -----------------*/ - - event void SpiResource.granted() - { - call SELN.makeOutput(); - call SELN.set(); - - if( state == STATE_P_ON ) - { - initRadio(); - call SpiResource.release(); - } - else - call Tasklet.schedule(); - } - - bool isSpiAcquired() - { - if( call SpiResource.isOwner() ) - return TRUE; - - if( call SpiResource.immediateRequest() == SUCCESS ) - { - call SELN.makeOutput(); - call SELN.set(); - - return TRUE; - } - - call SpiResource.request(); - return FALSE; - } - -/*----------------- CHANNEL -----------------*/ - - tasklet_async command uint8_t RadioState.getChannel() - { - return channel; - } - - tasklet_async command error_t RadioState.setChannel(uint8_t c) - { - c &= RF230_CHANNEL_MASK; - - if( cmd != CMD_NONE ) - return EBUSY; - else if( channel == c ) - return EALREADY; - - channel = c; - cmd = CMD_CHANNEL; - call Tasklet.schedule(); - - return SUCCESS; - } - - inline void changeChannel() - { - ASSERT( cmd == CMD_CHANNEL ); - ASSERT( state == STATE_SLEEP || state == STATE_TRX_OFF || state == STATE_RX_ON ); - - if( isSpiAcquired() ) - { - writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel); - - if( state == STATE_RX_ON ) - state = STATE_TRX_OFF_2_RX_ON; - else - cmd = CMD_SIGNAL_DONE; - } - } - -/*----------------- TURN ON/OFF -----------------*/ - - inline void changeState() - { - if( (cmd == CMD_STANDBY || cmd == CMD_TURNON) - && state == STATE_SLEEP && call RadioAlarm.isFree() ) - { - call SLP_TR.clr(); - - call RadioAlarm.wait(SLEEP_WAKEUP_TIME); - state = STATE_SLEEP_2_TRX_OFF; - } - else if( cmd == CMD_TURNON && state == STATE_TRX_OFF && isSpiAcquired() ) - { - ASSERT( ! radioIrq ); - - 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; - } - else if( (cmd == CMD_TURNOFF || cmd == CMD_STANDBY) - && state == STATE_RX_ON && isSpiAcquired() ) - { - writeRegister(RF230_TRX_STATE, RF230_FORCE_TRX_OFF); - - call IRQ.disable(); - radioIrq = FALSE; - - state = STATE_TRX_OFF; - } - - if( cmd == CMD_TURNOFF && state == STATE_TRX_OFF ) - { - call SLP_TR.set(); - state = STATE_SLEEP; - cmd = CMD_SIGNAL_DONE; - } - else if( cmd == CMD_STANDBY && state == STATE_TRX_OFF ) - cmd = CMD_SIGNAL_DONE; - } - - tasklet_async command error_t RadioState.turnOff() - { - if( cmd != CMD_NONE ) - return EBUSY; - else if( state == STATE_SLEEP ) - return EALREADY; - - cmd = CMD_TURNOFF; - call Tasklet.schedule(); - - return SUCCESS; - } - - tasklet_async command error_t RadioState.standby() - { - if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) ) - return EBUSY; - else if( state == STATE_TRX_OFF ) - return EALREADY; - - cmd = CMD_STANDBY; - call Tasklet.schedule(); - - return SUCCESS; - } - - tasklet_async command error_t RadioState.turnOn() - { - if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) ) - return EBUSY; - else if( state == STATE_RX_ON ) - return EALREADY; - - cmd = CMD_TURNON; - call Tasklet.schedule(); - - return SUCCESS; - } - - default tasklet_async event void RadioState.done() { } - -/*----------------- TRANSMIT -----------------*/ - - tasklet_async command error_t RadioSend.send(message_t* msg) - { - uint16_t time; - uint8_t length; - uint8_t* data; - uint8_t header; - uint32_t time32; - void* timesync; - - if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq ) - return EBUSY; - - length = (call PacketTransmitPower.isSet(msg) ? - call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK; - - if( length != txPower ) - { - txPower = length; - 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( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_BUSY_RX ); - - state = STATE_PLL_ON_2_RX_ON; - return EBUSY; - } - - atomic - { - call SLP_TR.set(); - time = call RadioAlarm.getNow() + TX_SFD_DELAY; - } - call SLP_TR.clr(); - - ASSERT( ! radioIrq ); - - call SELN.clr(); - 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 FastSpiByte.splitReadWrite(length); - - // the FCS is atomatically generated (2 bytes) - length -= 2; - - header = call RF230Config.getHeaderLength(); - if( header > length ) - header = length; - - length -= header; - - // first upload the header to gain some time - do { - call FastSpiByte.splitReadWrite(*(data++)); - } - while( --header != 0 ); - - time32 += (int16_t)(time) - (int16_t)(time32); - - if( timesync != 0 ) - *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32; - - do { - call FastSpiByte.splitReadWrite(*(data++)); - } - while( --length != 0 ); - - // wait for the SPI transfer to finish - call FastSpiByte.splitRead(); - call SELN.set(); - - /* - * There is a very small window (~1 microsecond) when the RF230 went - * into PLL_ON state but was somehow not properly initialized because - * of an incoming message and could not go into BUSY_TX. I think the - * radio can even receive a message, and generate a TRX_UR interrupt - * because of concurrent access, but that message probably cannot be - * recovered. - * - * TODO: this needs to be verified, and make sure that the chip is - * not locked up in this case. - */ - - // go back to RX_ON state when finished - writeRegister(RF230_TRX_STATE, RF230_RX_ON); - -#ifdef RF230_DEBUG_MESSAGES - if( call DiagMsg.record() ) - { - length = call RF230Config.getLength(msg); - - call DiagMsg.str("tx"); - call DiagMsg.uint16(time); - call DiagMsg.uint8(length); - call DiagMsg.hex8s(data, 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; - - return SUCCESS; - } - - default tasklet_async event void RadioSend.sendDone(error_t error) { } - default tasklet_async event void RadioSend.ready() { } - -/*----------------- CCA -----------------*/ - - tasklet_async command error_t RadioCCA.request() - { - if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || ! call RadioAlarm.isFree() ) - return EBUSY; - - // see Errata B7 of the datasheet - // writeRegister(RF230_TRX_STATE, RF230_PLL_ON); - // writeRegister(RF230_TRX_STATE, RF230_RX_ON); - - writeRegister(RF230_PHY_CC_CCA, RF230_CCA_REQUEST | RF230_CCA_MODE_VALUE | channel); - call RadioAlarm.wait(CCA_REQUEST_TIME); - cmd = CMD_CCA; - - return SUCCESS; - } - - default tasklet_async event void RadioCCA.done(error_t error) { } - -/*----------------- RECEIVE -----------------*/ - - inline void downloadMessage() - { - uint8_t length; - uint16_t crc; - - call SELN.clr(); - call FastSpiByte.write(RF230_CMD_FRAME_READ); - - // read the length byte - length = call FastSpiByte.write(0); - - // if correct length - if( length >= 3 && length <= call RF230Config.getMaxLength() ) - { - uint8_t read; - uint8_t* data; - - // initiate the reading - call FastSpiByte.splitWrite(0); - - call RF230Config.setLength(rxMsg, length); - data = call RF230Config.getPayload(rxMsg); - crc = 0; - - // we do not store the CRC field - length -= 2; - - read = call RF230Config.getHeaderLength(); - if( length < read ) - read = length; - - length -= read; - - do { - crc = RF230_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0)); - } - while( --read != 0 ); - - if( signal RadioReceive.header(rxMsg) ) - { - while( length-- != 0 ) - crc = RF230_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0)); - - crc = RF230_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0)); - crc = RF230_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0)); - - call PacketLinkQuality.set(rxMsg, call FastSpiByte.splitRead()); - } - else - crc = 1; - } - else - crc = 1; - - call SELN.set(); - state = STATE_RX_ON; - -#ifdef RF230_DEBUG_MESSAGES - if( call DiagMsg.record() ) - { - length = call RF230Config.getLength(rxMsg); - - call DiagMsg.str("rx"); - 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 RF230Config.getPayload(rxMsg), length - 2); - call DiagMsg.send(); - } -#endif - - cmd = CMD_NONE; - - // signal only if it has passed the CRC check - if( crc == 0 ) - rxMsg = signal RadioReceive.receive(rxMsg); - } - -/*----------------- IRQ -----------------*/ - - async event void IRQ.captured(uint16_t time) - { - ASSERT( ! radioIrq ); - - atomic - { - capturedTime = time; - radioIrq = TRUE; - } - - call Tasklet.schedule(); - } - - void serviceRadio() - { - if( isSpiAcquired() ) - { - uint16_t time; - uint32_t time32; - uint8_t irq; - uint8_t temp; - - atomic time = capturedTime; - radioIrq = FALSE; - irq = readRegister(RF230_IRQ_STATUS); - -#ifdef RF230_DEBUG - // TODO: handle this interrupt - if( irq & RF230_IRQ_TRX_UR ) - { - if( call DiagMsg.record() ) - { - call DiagMsg.str("assert ur"); - call DiagMsg.uint16(call RadioAlarm.getNow()); - call DiagMsg.hex8(readRegister(RF230_TRX_STATUS)); - call DiagMsg.hex8(readRegister(RF230_TRX_STATE)); - call DiagMsg.hex8(irq); - call DiagMsg.uint8(state); - call DiagMsg.uint8(cmd); - call DiagMsg.send(); - } - } -#endif - - if( irq & RF230_IRQ_PLL_LOCK ) - { - if( cmd == CMD_TURNON || cmd == CMD_CHANNEL ) - { - ASSERT( state == STATE_TRX_OFF_2_RX_ON ); - - state = STATE_RX_ON; - cmd = CMD_SIGNAL_DONE; - } - else if( cmd == CMD_TRANSMIT ) - { - ASSERT( state == STATE_BUSY_TX_2_RX_ON ); - } - else - ASSERT(FALSE); - } - - if( irq & RF230_IRQ_RX_START ) - { - if( cmd == CMD_CCA ) - { - signal RadioCCA.done(FAIL); - cmd = CMD_NONE; - } - - if( cmd == CMD_NONE ) - { - ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON ); - - // the most likely place for busy channel, with no TRX_END interrupt - if( irq == RF230_IRQ_RX_START ) - { - temp = readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK; - rssiBusy += temp - (rssiBusy >> 2); -#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 - * have been a PLL_LOCK because then cmd != CMD_NONE, so we must - * have received a message (and could also have received the - * TRX_END interrupt in the mean time, but that is fine. Also, - * we could not be after a transmission, because then cmd = - * CMD_TRANSMIT. - */ - if( irq == RF230_IRQ_RX_START ) // just to be cautious - { - time32 = call LocalTime.get(); - time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32); - call PacketTimeStamp.set(rxMsg, time32); - } - else - call PacketTimeStamp.clear(rxMsg); - - cmd = CMD_RECEIVE; - } - else - ASSERT( cmd == CMD_TURNOFF ); - } - - if( irq & RF230_IRQ_TRX_END ) - { - if( cmd == CMD_TRANSMIT ) - { - ASSERT( state == STATE_BUSY_TX_2_RX_ON ); - - state = STATE_RX_ON; - cmd = CMD_NONE; - signal RadioSend.sendDone(SUCCESS); - - // TODO: we could have missed a received message - ASSERT( ! (irq & RF230_IRQ_RX_START) ); - } - 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 ); - - writeRegister(RF230_TRX_STATE, RF230_RX_ON); - state = STATE_RX_ON; - } - else - { - // the most likely place for clear channel (hope to avoid acks) - rssiClear += (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) - (rssiClear >> 2); - } - - cmd = CMD_DOWNLOAD; - } - else - ASSERT(FALSE); - } - } - } - - default tasklet_async event bool RadioReceive.header(message_t* msg) - { - return TRUE; - } - - default tasklet_async event message_t* RadioReceive.receive(message_t* msg) - { - return msg; - } - -/*----------------- TASKLET -----------------*/ - - tasklet_async event void Tasklet.run() - { - if( radioIrq ) - serviceRadio(); - - if( cmd != CMD_NONE ) - { - if( cmd == CMD_DOWNLOAD ) - downloadMessage(); - else if( CMD_TURNOFF <= cmd && cmd <= CMD_TURNON ) - changeState(); - else if( cmd == CMD_CHANNEL ) - changeChannel(); - - if( cmd == CMD_SIGNAL_DONE ) - { - cmd = CMD_NONE; - signal RadioState.done(); - } - } - - if( cmd == CMD_NONE && state == STATE_RX_ON && ! radioIrq ) - signal RadioSend.ready(); - - if( cmd == CMD_NONE ) - call SpiResource.release(); - } -} diff --git a/tos/chips/rf230/RF230Packet.h b/tos/chips/rf230/RF230Packet.h deleted file mode 100644 index f12e3e5b..00000000 --- a/tos/chips/rf230/RF230Packet.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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 __RF230PACKET_H__ -#define __RF230PACKET_H__ - -#include - -typedef ieee154_header_t rf230packet_header_t; - -typedef nx_struct rf230packet_footer_t -{ - // the time stamp is not recorded here, time stamped messaged cannot have max length -} rf230packet_footer_t; - -typedef struct rf230packet_metadata_t -{ - uint8_t flags; - uint8_t lqi; - uint8_t power; // shared between TXPOWER and RSSI -#ifdef LOW_POWER_LISTENING - uint16_t lpl_sleepint; -#endif - uint32_t timestamp; -} rf230packet_metadata_t; - -enum rf230packet_metadata_flags -{ - RF230PACKET_WAS_ACKED = 0x01, // PacketAcknowledgements - RF230PACKET_TIMESTAMP = 0x02, // PacketTimeStamp - RF230PACKET_TXPOWER = 0x04, // PacketTransmitPower - RF230PACKET_RSSI = 0x08, // PacketRSSI - RF230PACKET_TIMESYNC = 0x10, // PacketTimeSync (update timesync_footer) - RF230PACKET_LPL_SLEEPINT = 0x20, // LowPowerListening - - RF230PACKET_CLEAR_METADATA = 0x00, -}; - -#endif//__RF230PACKET_H__ diff --git a/tos/chips/rf230/RF230PacketC.nc b/tos/chips/rf230/RF230PacketC.nc deleted file mode 100644 index 9d09b314..00000000 --- a/tos/chips/rf230/RF230PacketC.nc +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 - */ - -configuration RF230PacketC -{ - provides - { - interface Packet; - interface AMPacket; - interface PacketAcknowledgements; - interface PacketField as PacketLinkQuality; - interface PacketField as PacketTransmitPower; - interface PacketField as PacketRSSI; - interface PacketField as PacketSleepInterval; - interface PacketField as PacketTimeSyncOffset; - - interface PacketTimeStamp as PacketTimeStampRadio; - interface PacketTimeStamp as PacketTimeStampMilli; - } -} - -implementation -{ - 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; - PacketTimeSyncOffset = RF230PacketP.PacketTimeSyncOffset; - - PacketTimeStampRadio = RF230PacketP; - PacketTimeStampMilli = RF230PacketP; -} diff --git a/tos/chips/rf230/RF230PacketP.nc b/tos/chips/rf230/RF230PacketP.nc deleted file mode 100644 index 7a8d117a..00000000 --- a/tos/chips/rf230/RF230PacketP.nc +++ /dev/null @@ -1,291 +0,0 @@ -/* - * 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 - */ - -#include -#include - -module RF230PacketP -{ - provides - { - interface PacketAcknowledgements; - interface Packet; - interface PacketField as PacketLinkQuality; - interface PacketField as PacketTransmitPower; - interface PacketField as PacketRSSI; - interface PacketField as PacketSleepInterval; - interface PacketField as PacketTimeSyncOffset; - - interface PacketTimeStamp as PacketTimeStampRadio; - interface PacketTimeStamp as PacketTimeStampMilli; - } - - uses - { - interface IEEE154Packet; - - interface LocalTime as LocalTimeRadio; - interface LocalTime as LocalTimeMilli; - } -} - -implementation -{ - enum - { - 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 - }; - - inline rf230packet_metadata_t* getMeta(message_t* msg) - { - return (rf230packet_metadata_t*)(msg->metadata); - } - -/*----------------- Packet -----------------*/ - - command void Packet.clear(message_t* msg) - { - call IEEE154Packet.createDataFrame(msg); - - getMeta(msg)->flags = RF230PACKET_CLEAR_METADATA; - } - - inline command void Packet.setPayloadLength(message_t* msg, uint8_t len) - { - call IEEE154Packet.setLength(msg, len + PACKET_LENGTH_INCREASE); - } - - inline command uint8_t Packet.payloadLength(message_t* msg) - { - return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE; - } - - inline command uint8_t Packet.maxPayloadLength() - { - return TOSH_DATA_LENGTH; - } - - command void* Packet.getPayload(message_t* msg, uint8_t len) - { - if( len > TOSH_DATA_LENGTH ) - return NULL; - - return msg->data; - } - -/*----------------- PacketAcknowledgements -----------------*/ - - async command error_t PacketAcknowledgements.requestAck(message_t* msg) - { - call IEEE154Packet.setAckRequired(msg, TRUE); - - return SUCCESS; - } - - async command error_t PacketAcknowledgements.noAck(message_t* msg) - { - call IEEE154Packet.setAckRequired(msg, FALSE); - - return SUCCESS; - } - - async command bool PacketAcknowledgements.wasAcked(message_t* msg) - { - return getMeta(msg)->flags & RF230PACKET_WAS_ACKED; - } - -/*----------------- 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; - } - -/*----------------- PacketTimeStampRadio -----------------*/ - - async command bool PacketTimeStampRadio.isValid(message_t* msg) - { - return getMeta(msg)->flags & RF230PACKET_TIMESTAMP; - } - - async command uint32_t PacketTimeStampRadio.timestamp(message_t* msg) - { - return getMeta(msg)->timestamp; - } - - async command void PacketTimeStampRadio.clear(message_t* msg) - { - getMeta(msg)->flags &= ~RF230PACKET_TIMESTAMP; - } - - 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) - { - return getMeta(msg)->flags & RF230PACKET_TXPOWER; - } - - async command uint8_t PacketTransmitPower.get(message_t* msg) - { - return getMeta(msg)->power; - } - - async command void PacketTransmitPower.clear(message_t* msg) - { - getMeta(msg)->flags &= ~RF230PACKET_TXPOWER; - } - - async command void PacketTransmitPower.set(message_t* msg, uint8_t value) - { - getMeta(msg)->flags &= ~RF230PACKET_RSSI; - getMeta(msg)->flags |= RF230PACKET_TXPOWER; - getMeta(msg)->power = value; - } - -/*----------------- PacketRSSI -----------------*/ - - async command bool PacketRSSI.isSet(message_t* msg) - { - return getMeta(msg)->flags & RF230PACKET_RSSI; - } - - async command uint8_t PacketRSSI.get(message_t* msg) - { - return getMeta(msg)->power; - } - - async command void PacketRSSI.clear(message_t* msg) - { - getMeta(msg)->flags &= ~RF230PACKET_RSSI; - } - - async command void PacketRSSI.set(message_t* msg, uint8_t value) - { - getMeta(msg)->flags &= ~RF230PACKET_TXPOWER; - getMeta(msg)->flags |= RF230PACKET_RSSI; - 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_absolute_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; - } - -/*----------------- PacketSleepInterval -----------------*/ - - async command bool PacketSleepInterval.isSet(message_t* msg) - { - return getMeta(msg)->flags & RF230PACKET_LPL_SLEEPINT; - } - - async command uint16_t PacketSleepInterval.get(message_t* msg) - { -#ifdef LOW_POWER_LISTENING - return getMeta(msg)->lpl_sleepint; -#else - return 0; -#endif - } - - async command void PacketSleepInterval.clear(message_t* msg) - { - getMeta(msg)->flags &= ~RF230PACKET_LPL_SLEEPINT; - } - - async command void PacketSleepInterval.set(message_t* msg, uint16_t value) - { - getMeta(msg)->flags |= RF230PACKET_LPL_SLEEPINT; - -#ifdef LOW_POWER_LISTENING - getMeta(msg)->lpl_sleepint = value; -#endif - } -} diff --git a/tos/chips/rf230/RF230TimeSyncMessageC.nc b/tos/chips/rf230/RF230TimeSyncMessageC.nc deleted file mode 100644 index dc321af0..00000000 --- a/tos/chips/rf230/RF230TimeSyncMessageC.nc +++ /dev/null @@ -1,72 +0,0 @@ -/* - * 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 - */ - -#include -#include -#include - -configuration RF230TimeSyncMessageC -{ - provides - { - interface SplitControl; - - interface Receive[uint8_t id]; - interface Receive as Snoop[am_id_t id]; - interface Packet; - interface AMPacket; - - interface TimeSyncAMSend as TimeSyncAMSendRadio[am_id_t id]; - interface TimeSyncPacket as TimeSyncPacketRadio; - - interface TimeSyncAMSend as TimeSyncAMSendMilli[am_id_t id]; - interface TimeSyncPacket as TimeSyncPacketMilli; - } -} - -implementation -{ - components RF230TimeSyncMessageP, RF230ActiveMessageC, LocalTimeMilliC, LocalTimeMicroC as LocalTimeRadioC, RF230PacketC; - - TimeSyncAMSendRadio = RF230TimeSyncMessageP; - TimeSyncPacketRadio = RF230TimeSyncMessageP; - - TimeSyncAMSendMilli = RF230TimeSyncMessageP; - TimeSyncPacketMilli = RF230TimeSyncMessageP; - - Packet = RF230TimeSyncMessageP; - RF230TimeSyncMessageP.SubSend -> RF230ActiveMessageC.AMSend; - RF230TimeSyncMessageP.SubPacket -> RF230ActiveMessageC.Packet; - - RF230TimeSyncMessageP.PacketTimeStampRadio -> RF230ActiveMessageC; - RF230TimeSyncMessageP.PacketTimeStampMilli -> RF230ActiveMessageC; - RF230TimeSyncMessageP.LocalTimeRadio -> LocalTimeRadioC; - RF230TimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC; - - RF230TimeSyncMessageP.PacketTimeSyncOffset -> RF230PacketC.PacketTimeSyncOffset; - - SplitControl = RF230ActiveMessageC; - Receive = RF230ActiveMessageC.Receive; - Snoop = RF230ActiveMessageC.Snoop; - AMPacket = RF230ActiveMessageC; -} diff --git a/tos/chips/rf230/RF230TimeSyncMessageP.nc b/tos/chips/rf230/RF230TimeSyncMessageP.nc deleted file mode 100644 index f60110a4..00000000 --- a/tos/chips/rf230/RF230TimeSyncMessageP.nc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * 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 - */ - -#include -#include - -module RF230TimeSyncMessageP -{ - provides - { - interface TimeSyncAMSend as TimeSyncAMSendRadio[uint8_t id]; - interface TimeSyncAMSend as TimeSyncAMSendMilli[uint8_t id]; - interface Packet; - - interface TimeSyncPacket as TimeSyncPacketRadio; - interface TimeSyncPacket as TimeSyncPacketMilli; - } - - uses - { - interface AMSend as SubSend[uint8_t id]; - interface Packet as SubPacket; - - interface PacketTimeStamp as PacketTimeStampRadio; - interface PacketTimeStamp as PacketTimeStampMilli; - - interface LocalTime as LocalTimeRadio; - interface LocalTime as LocalTimeMilli; - - interface PacketField as PacketTimeSyncOffset; - } -} - -implementation -{ - 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 SubPacket.clear(msg); - } - - command void Packet.setPayloadLength(message_t* msg, uint8_t len) - { - call SubPacket.setPayloadLength(msg, len + sizeof(timesync_relative_t)); - } - - command uint8_t Packet.payloadLength(message_t* msg) - { - return call SubPacket.payloadLength(msg) - sizeof(timesync_relative_t); - } - - command uint8_t Packet.maxPayloadLength() - { - return call SubPacket.maxPayloadLength() - sizeof(timesync_relative_t); - } - - command void* Packet.getPayload(message_t* msg, uint8_t len) - { - return call SubPacket.getPayload(msg, len + sizeof(timesync_relative_t)); - } - -/*----------------- TimeSyncAMSendRadio -----------------*/ - - command error_t TimeSyncAMSendRadio.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time) - { - *(timesync_absolute_t*)(msg->data + len) = event_time; - - call PacketTimeSyncOffset.set(msg, len); - - return call SubSend.send[id](addr, msg, len + sizeof(timesync_relative_t)); - } - - command error_t TimeSyncAMSendRadio.cancel[am_id_t id](message_t* msg) - { - return call SubSend.cancel[id](msg); - } - - default event void TimeSyncAMSendRadio.sendDone[am_id_t id](message_t* msg, error_t error) - { - } - - command uint8_t TimeSyncAMSendRadio.maxPayloadLength[am_id_t id]() - { - return call SubSend.maxPayloadLength[id]() - sizeof(timesync_relative_t); - } - - command void* TimeSyncAMSendRadio.getPayload[am_id_t id](message_t* msg, uint8_t len) - { - return call SubSend.getPayload[id](msg, len + sizeof(timesync_relative_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 = ((int32_t)(event_time - call LocalTimeMilli.get()) << 10) + call LocalTimeRadio.get(); - - return call TimeSyncAMSendRadio.send[id](addr, msg, len, event_time); - } - - command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg) - { - return call TimeSyncAMSendRadio.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 TimeSyncAMSendRadio.maxPayloadLength[id](); - } - - command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len) - { - return call TimeSyncAMSendRadio.getPayload[id](msg, len); - } - - /*----------------- SubSend.sendDone -------------------*/ - - event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error) - { - signal TimeSyncAMSendRadio.sendDone[id](msg, error); - signal TimeSyncAMSendMilli.sendDone[id](msg, error); - } - - /*----------------- TimeSyncPacketRadio -----------------*/ - - command bool TimeSyncPacketRadio.isValid(message_t* msg) - { - timesync_relative_t* timesync = getFooter(msg); - - return call PacketTimeStampRadio.isValid(msg) && *timesync != 0x80000000L; - } - - command uint32_t TimeSyncPacketRadio.eventTime(message_t* msg) - { - timesync_relative_t* timesync = getFooter(msg); - - return (*timesync) + call PacketTimeStampRadio.timestamp(msg); - } - - /*----------------- TimeSyncPacketMilli -----------------*/ - - command bool TimeSyncPacketMilli.isValid(message_t* msg) - { - timesync_relative_t* timesync = getFooter(msg); - - return call PacketTimeStampMilli.isValid(msg) && *timesync != 0x80000000L; - } - - command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg) - { - timesync_relative_t* timesync = getFooter(msg); - - return ((int32_t)(*timesync) >> 10) + call PacketTimeStampMilli.timestamp(msg); - } -} diff --git a/tos/chips/rf230/RF2xx.h b/tos/chips/rf230/RF2xx.h new file mode 100644 index 00000000..8e152ae2 --- /dev/null +++ b/tos/chips/rf230/RF2xx.h @@ -0,0 +1,159 @@ +/* + * 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 __RF2XX_H__ +#define __RF2XX_H__ + +enum rf2xx_chipsets_enum +{ + RF230_CHIPSET = 0, + RF212_CHIPSET = 1, +}; + +enum rf2xx_registers_enum +{ + RF2XX_TRX_STATUS = 0x01, + RF2XX_TRX_STATE = 0x02, + RF2XX_TRX_CTRL_0 = 0x03, + RF2XX_PHY_TX_PWR = 0x05, + RF2XX_PHY_RSSI = 0x06, + RF2XX_PHY_ED_LEVEL = 0x07, + RF2XX_PHY_CC_CCA = 0x08, + RF2XX_CCA_THRES = 0x09, + RF2XX_IRQ_MASK = 0x0E, + RF2XX_IRQ_STATUS = 0x0F, + RF2XX_VREG_CTRL = 0x10, + RF2XX_BATMON = 0x11, + RF2XX_XOSC_CTRL = 0x12, + RF2XX_PLL_CF = 0x1A, + RF2XX_PLL_DCU = 0x1B, + RF2XX_PART_NUM = 0x1C, + RF2XX_VERSION_NUM = 0x1D, + RF2XX_MAN_ID_0 = 0x1E, + RF2XX_MAN_ID_1 = 0x1F, + RF2XX_SHORT_ADDR_0 = 0x20, + RF2XX_SHORT_ADDR_1 = 0x21, + RF2XX_PAN_ID_0 = 0x22, + RF2XX_PAN_ID_1 = 0x23, + RF2XX_IEEE_ADDR_0 = 0x24, + RF2XX_IEEE_ADDR_1 = 0x25, + RF2XX_IEEE_ADDR_2 = 0x26, + RF2XX_IEEE_ADDR_3 = 0x27, + RF2XX_IEEE_ADDR_4 = 0x28, + RF2XX_IEEE_ADDR_5 = 0x29, + RF2XX_IEEE_ADDR_6 = 0x2A, + RF2XX_IEEE_ADDR_7 = 0x2B, + RF2XX_XAH_CTRL = 0x2C, + RF2XX_CSMA_SEED_0 = 0x2D, + RF2XX_CSMA_SEED_1 = 0x2E, +}; + +enum rf2xx_trx_register_enums +{ + RF2XX_CCA_DONE = 1 << 7, + RF2XX_CCA_STATUS = 1 << 6, + RF2XX_TRX_STATUS_MASK = 0x1F, + RF2XX_P_ON = 0, + RF2XX_BUSY_RX = 1, + RF2XX_BUSY_TX = 2, + RF2XX_RX_ON = 6, + RF2XX_TRX_OFF = 8, + RF2XX_PLL_ON = 9, + RF2XX_SLEEP = 15, + RF2XX_BUSY_RX_AACK = 16, + RF2XX_BUSR_TX_ARET = 17, + RF2XX_RX_AACK_ON = 22, + RF2XX_TX_ARET_ON = 25, + RF2XX_RX_ON_NOCLK = 28, + RF2XX_AACK_ON_NOCLK = 29, + RF2XX_BUSY_RX_AACK_NOCLK = 30, + RF2XX_STATE_TRANSITION_IN_PROGRESS = 31, + RF2XX_TRAC_STATUS_MASK = 0xE0, + RF2XX_TRAC_SUCCESS = 0, + RF2XX_TRAC_CHANNEL_ACCESS_FAILURE = 3 << 5, + RF2XX_TRAC_NO_ACK = 5 << 5, + RF2XX_TRX_CMD_MASK = 0x1F, + RF2XX_NOP = 0, + RF2XX_TX_START = 2, + RF2XX_FORCE_TRX_OFF = 3, +}; + +enum rf2xx_phy_register_enums +{ + RF2XX_TX_AUTO_CRC_ON = 1 << 7, + RF2XX_TX_PWR_MASK = 0x0F, + RF2XX_TX_PWR_DEFAULT = 0, + RF2XX_RSSI_MASK = 0x1F, + RF2XX_CCA_REQUEST = 1 << 7, + RF2XX_CCA_MODE_0 = 0 << 5, + RF2XX_CCA_MODE_1 = 1 << 5, + RF2XX_CCA_MODE_2 = 2 << 5, + RF2XX_CCA_MODE_3 = 3 << 5, + RF2XX_CHANNEL_DEFAULT = 11, + RF2XX_CHANNEL_MASK = 0x1F, + RF2XX_CCA_CS_THRES_SHIFT = 4, + RF2XX_CCA_ED_THRES_SHIFT = 0, +}; + +enum rf2xx_irq_register_enums +{ + RF2XX_IRQ_BAT_LOW = 1 << 7, + RF2XX_IRQ_TRX_UR = 1 << 6, + RF2XX_IRQ_TRX_END = 1 << 3, + RF2XX_IRQ_RX_START = 1 << 2, + RF2XX_IRQ_PLL_UNLOCK = 1 << 1, + RF2XX_IRQ_PLL_LOCK = 1 << 0, +}; + +enum rf2xx_control_register_enums +{ + RF2XX_AVREG_EXT = 1 << 7, + RF2XX_AVDD_OK = 1 << 6, + RF2XX_DVREG_EXT = 1 << 3, + RF2XX_DVDD_OK = 1 << 2, + RF2XX_BATMON_OK = 1 << 5, + RF2XX_BATMON_VHR = 1 << 4, + RF2XX_BATMON_VTH_MASK = 0x0F, + RF2XX_XTAL_MODE_OFF = 0 << 4, + RF2XX_XTAL_MODE_EXTERNAL = 4 << 4, + RF2XX_XTAL_MODE_INTERNAL = 15 << 4, +}; + +enum rf2xx_pll_register_enums +{ + RF2XX_PLL_CF_START = 1 << 7, + RF2XX_PLL_DCU_START = 1 << 7, +}; + +enum rf2xx_spi_command_enums +{ + RF2XX_CMD_REGISTER_READ = 0x80, + RF2XX_CMD_REGISTER_WRITE = 0xC0, + RF2XX_CMD_REGISTER_MASK = 0x3F, + RF2XX_CMD_FRAME_READ = 0x20, + RF2XX_CMD_FRAME_WRITE = 0x60, + RF2XX_CMD_SRAM_READ = 0x00, + RF2XX_CMD_SRAM_WRITE = 0x40, +}; + +#endif//__RF2XX_H__ diff --git a/tos/chips/rf230/RF2xxActiveMessageC.nc b/tos/chips/rf230/RF2xxActiveMessageC.nc new file mode 100644 index 00000000..0e58c6e1 --- /dev/null +++ b/tos/chips/rf230/RF2xxActiveMessageC.nc @@ -0,0 +1,148 @@ +/* + * 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 + */ + +#include + +configuration RF2xxActiveMessageC +{ + provides + { + interface SplitControl; + + interface AMSend[am_id_t id]; + interface Receive[am_id_t id]; + interface Receive as Snoop[am_id_t id]; + + interface Packet; + interface AMPacket; + interface PacketAcknowledgements; + interface LowPowerListening; + interface RadioChannel; + + interface PacketField as PacketLinkQuality; + interface PacketField as PacketTransmitPower; + interface PacketField as PacketRSSI; + + interface PacketTimeStamp as PacketTimeStampRadio; + interface PacketTimeStamp as PacketTimeStampMilli; + } +} + +implementation +{ + components RF2xxActiveMessageP, RF2xxPacketC, IEEE154PacketC, RadioAlarmC; + +#ifdef RF2XX_DEBUG + components AssertC; +#endif + + RF2xxActiveMessageP.IEEE154Packet -> IEEE154PacketC; + RF2xxActiveMessageP.Packet -> RF2xxPacketC; + RF2xxActiveMessageP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; + + Packet = RF2xxPacketC; + AMPacket = RF2xxPacketC; + PacketAcknowledgements = RF2xxPacketC; + PacketLinkQuality = RF2xxPacketC.PacketLinkQuality; + PacketTransmitPower = RF2xxPacketC.PacketTransmitPower; + PacketRSSI = RF2xxPacketC.PacketRSSI; + PacketTimeStampRadio = RF2xxPacketC; + PacketTimeStampMilli = RF2xxPacketC; + LowPowerListening = LowPowerListeningLayerC; + RadioChannel = MessageBufferLayerC; + + components ActiveMessageLayerC; +#ifdef TFRAMES_ENABLED + components new DummyLayerC() as IEEE154NetworkLayerC; +#else + components IEEE154NetworkLayerC; +#endif +#ifdef LOW_POWER_LISTENING + components LowPowerListeningLayerC; +#else + components new DummyLayerC() as LowPowerListeningLayerC; +#endif + components MessageBufferLayerC; + components UniqueLayerC; + components TrafficMonitorLayerC; +#ifdef RF2XX_SLOTTED_MAC + components SlottedCollisionLayerC as CollisionAvoidanceLayerC; +#else + components RandomCollisionLayerC as CollisionAvoidanceLayerC; +#endif + components SoftwareAckLayerC; + components new DummyLayerC() as CsmaLayerC; + components RF2xxDriverLayerC; + + SplitControl = LowPowerListeningLayerC; + AMSend = ActiveMessageLayerC; + Receive = ActiveMessageLayerC.Receive; + Snoop = ActiveMessageLayerC.Snoop; + + ActiveMessageLayerC.Config -> RF2xxActiveMessageP; + ActiveMessageLayerC.AMPacket -> IEEE154PacketC; + ActiveMessageLayerC.SubSend -> IEEE154NetworkLayerC; + ActiveMessageLayerC.SubReceive -> IEEE154NetworkLayerC; + + IEEE154NetworkLayerC.SubSend -> UniqueLayerC; + IEEE154NetworkLayerC.SubReceive -> LowPowerListeningLayerC; + + // the UniqueLayer is wired at two points + UniqueLayerC.Config -> RF2xxActiveMessageP; + UniqueLayerC.SubSend -> LowPowerListeningLayerC; + + LowPowerListeningLayerC.SubControl -> MessageBufferLayerC; + LowPowerListeningLayerC.SubSend -> MessageBufferLayerC; + LowPowerListeningLayerC.SubReceive -> MessageBufferLayerC; +#ifdef LOW_POWER_LISTENING + LowPowerListeningLayerC.PacketSleepInterval -> RF2xxPacketC; + LowPowerListeningLayerC.IEEE154Packet -> IEEE154PacketC; + LowPowerListeningLayerC.PacketAcknowledgements -> RF2xxPacketC; +#endif + + MessageBufferLayerC.Packet -> RF2xxPacketC; + MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC; + MessageBufferLayerC.RadioReceive -> UniqueLayerC; + MessageBufferLayerC.RadioState -> TrafficMonitorLayerC; + + UniqueLayerC.SubReceive -> TrafficMonitorLayerC; + + TrafficMonitorLayerC.Config -> RF2xxActiveMessageP; + TrafficMonitorLayerC.SubSend -> CollisionAvoidanceLayerC; + TrafficMonitorLayerC.SubReceive -> CollisionAvoidanceLayerC; + TrafficMonitorLayerC.SubState -> RF2xxDriverLayerC; + + CollisionAvoidanceLayerC.Config -> RF2xxActiveMessageP; + CollisionAvoidanceLayerC.SubSend -> SoftwareAckLayerC; + CollisionAvoidanceLayerC.SubReceive -> SoftwareAckLayerC; + + SoftwareAckLayerC.Config -> RF2xxActiveMessageP; + SoftwareAckLayerC.SubSend -> CsmaLayerC; + SoftwareAckLayerC.SubReceive -> RF2xxDriverLayerC; + + CsmaLayerC.Config -> RF2xxActiveMessageP; + CsmaLayerC -> RF2xxDriverLayerC.RadioSend; + CsmaLayerC -> RF2xxDriverLayerC.RadioCCA; + + RF2xxDriverLayerC.RF2xxDriverConfig -> RF2xxActiveMessageP; +} diff --git a/tos/chips/rf230/RF2xxActiveMessageP.nc b/tos/chips/rf230/RF2xxActiveMessageP.nc new file mode 100644 index 00000000..edc5b8f6 --- /dev/null +++ b/tos/chips/rf230/RF2xxActiveMessageP.nc @@ -0,0 +1,299 @@ +/* + * 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 + */ + +#include +#include +#include +#include + +module RF2xxActiveMessageP +{ + provides + { + interface RF2xxDriverConfig; + interface SoftwareAckConfig; + interface UniqueConfig; + interface CsmaConfig; + interface TrafficMonitorConfig; + interface RandomCollisionConfig; + interface SlottedCollisionConfig; + interface ActiveMessageConfig; + interface DummyConfig; + } + + uses + { + interface IEEE154Packet; + interface Packet; + interface RadioAlarm; + } +} + +implementation +{ +/*----------------- RF2xxDriverConfig -----------------*/ + + async command uint8_t RF2xxDriverConfig.getLength(message_t* msg) + { + return call IEEE154Packet.getLength(msg); + } + + async command void RF2xxDriverConfig.setLength(message_t* msg, uint8_t len) + { + call IEEE154Packet.setLength(msg, len); + } + + async command uint8_t* RF2xxDriverConfig.getPayload(message_t* msg) + { + return ((uint8_t*)(call IEEE154Packet.getHeader(msg))) + 1; + } + + inline rf2xxpacket_metadata_t* getMeta(message_t* msg) + { + return (rf2xxpacket_metadata_t*)(msg->metadata); + } + + async command uint8_t RF2xxDriverConfig.getHeaderLength() + { + // we need the fcf, dsn, destpan and dest + return 7; + } + + async command uint8_t RF2xxDriverConfig.getMaxLength() + { + // note, that the ieee154_footer_t is not stored, but we should include it here + return sizeof(rf2xxpacket_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t); + } + + async command uint8_t RF2xxDriverConfig.getDefaultChannel() + { + return RF2XX_DEF_CHANNEL; + } + + async command bool RF2xxDriverConfig.requiresRssiCca(message_t* msg) + { + return call IEEE154Packet.isDataFrame(msg); + } + +/*----------------- SoftwareAckConfig -----------------*/ + + async command bool SoftwareAckConfig.requiresAckWait(message_t* msg) + { + return call IEEE154Packet.requiresAckWait(msg); + } + + async command bool SoftwareAckConfig.isAckPacket(message_t* msg) + { + return call IEEE154Packet.isAckFrame(msg); + } + + async command bool SoftwareAckConfig.verifyAckPacket(message_t* data, message_t* ack) + { + return call IEEE154Packet.verifyAckReply(data, ack); + } + + async command bool SoftwareAckConfig.requiresAckReply(message_t* msg) + { + return call IEEE154Packet.requiresAckReply(msg); + } + + async command void SoftwareAckConfig.createAckPacket(message_t* data, message_t* ack) + { + call IEEE154Packet.createAckReply(data, ack); + } + + async command void SoftwareAckConfig.setAckReceived(message_t* msg, bool acked) + { + if( acked ) + getMeta(msg)->flags |= RF2XXPACKET_WAS_ACKED; + else + getMeta(msg)->flags &= ~RF2XXPACKET_WAS_ACKED; + } + + async command uint16_t SoftwareAckConfig.getAckTimeout() + { + return (uint16_t)(800 * RADIO_ALARM_MICROSEC); + } + + tasklet_async command void SoftwareAckConfig.reportChannelError() + { + signal TrafficMonitorConfig.channelError(); + } + +/*----------------- UniqueConfig -----------------*/ + + async command uint8_t UniqueConfig.getSequenceNumber(message_t* msg) + { + return call IEEE154Packet.getDSN(msg); + } + + async command void UniqueConfig.setSequenceNumber(message_t* msg, uint8_t dsn) + { + call IEEE154Packet.setDSN(msg, dsn); + } + + async command am_addr_t UniqueConfig.getSender(message_t* msg) + { + return call IEEE154Packet.getSrcAddr(msg); + } + + tasklet_async command void UniqueConfig.reportChannelError() + { + signal TrafficMonitorConfig.channelError(); + } + +/*----------------- ActiveMessageConfig -----------------*/ + + command error_t ActiveMessageConfig.checkPacket(message_t* msg) + { + // the user forgot to call clear, we should return EINVAL + if( ! call IEEE154Packet.isDataFrame(msg) ) + call Packet.clear(msg); + + return SUCCESS; + } + +/*----------------- CsmaConfig -----------------*/ + + async command bool CsmaConfig.requiresSoftwareCCA(message_t* msg) + { + return call IEEE154Packet.isDataFrame(msg); + } + +/*----------------- TrafficMonitorConfig -----------------*/ + + enum + { + TRAFFIC_UPDATE_PERIOD = 100, // in milliseconds + TRAFFIC_MAX_BYTES = (uint16_t)(TRAFFIC_UPDATE_PERIOD * 1000UL / 32), // 3125 + }; + + async command uint16_t TrafficMonitorConfig.getUpdatePeriod() + { + return TRAFFIC_UPDATE_PERIOD; + } + + async command uint16_t TrafficMonitorConfig.getChannelTime(message_t* msg) + { + /* We count in bytes, one byte is 32 microsecond. We are conservative here. + * + * pure airtime: preable (4 bytes), SFD (1 byte), length (1 byte), payload + CRC (len bytes) + * frame separation: 5-10 bytes + * ack required: 8-16 byte separation, 11 bytes airtime, 5-10 bytes separation + */ + + uint8_t len = call IEEE154Packet.getLength(msg); + return call IEEE154Packet.getAckRequired(msg) ? len + 6 + 16 + 11 + 10 : len + 6 + 10; + } + + async command am_addr_t TrafficMonitorConfig.getSender(message_t* msg) + { + return call IEEE154Packet.getSrcAddr(msg); + } + + tasklet_async command void TrafficMonitorConfig.timerTick() + { + signal SlottedCollisionConfig.timerTick(); + } + +/*----------------- RandomCollisionConfig -----------------*/ + + /* + * We try to use the same values as in CC2420 + * + * CC2420_MIN_BACKOFF = 10 jiffies = 320 microsec + * CC2420_BACKOFF_PERIOD = 10 jiffies + * initial backoff = 0x1F * CC2420_BACKOFF_PERIOD = 310 jiffies = 9920 microsec + * congestion backoff = 0x7 * CC2420_BACKOFF_PERIOD = 70 jiffies = 2240 microsec + */ + + async command uint16_t RandomCollisionConfig.getMinimumBackoff() + { + return (uint16_t)(320 * RADIO_ALARM_MICROSEC); + } + + async command uint16_t RandomCollisionConfig.getInitialBackoff(message_t* msg) + { + return (uint16_t)(9920 * RADIO_ALARM_MICROSEC); + } + + async command uint16_t RandomCollisionConfig.getCongestionBackoff(message_t* msg) + { + return (uint16_t)(2240 * RADIO_ALARM_MICROSEC); + } + + async command uint16_t RandomCollisionConfig.getTransmitBarrier(message_t* msg) + { + uint16_t time; + + // TODO: maybe we should use the embedded timestamp of the message + time = call RadioAlarm.getNow(); + + // estimated response time (download the message, etc) is 5-8 bytes + if( call IEEE154Packet.requiresAckReply(msg) ) + time += (uint16_t)(32 * (-5 + 16 + 11 + 5) * RADIO_ALARM_MICROSEC); + else + time += (uint16_t)(32 * (-5 + 5) * RADIO_ALARM_MICROSEC); + + return time; + } + + tasklet_async event void RadioAlarm.fired() { } + +/*----------------- SlottedCollisionConfig -----------------*/ + + async command uint16_t SlottedCollisionConfig.getInitialDelay() + { + return 300; + } + + async command uint8_t SlottedCollisionConfig.getScheduleExponent() + { + return 11; + } + + async command uint16_t SlottedCollisionConfig.getTransmitTime(message_t* msg) + { + // TODO: check if the timestamp is correct + return getMeta(msg)->timestamp; + } + + async command uint16_t SlottedCollisionConfig.getCollisionWindowStart(message_t* msg) + { + // the preamble (4 bytes), SFD (1 byte), plus two extra for safety + return getMeta(msg)->timestamp - (uint16_t)(7 * 32 * RADIO_ALARM_MICROSEC); + } + + async command uint16_t SlottedCollisionConfig.getCollisionWindowLength(message_t* msg) + { + return (uint16_t)(2 * 7 * 32 * RADIO_ALARM_MICROSEC); + } + + default tasklet_async event void SlottedCollisionConfig.timerTick() { } + +/*----------------- Dummy -----------------*/ + + async command void DummyConfig.nothing() + { + } +} diff --git a/tos/chips/rf230/RF2xxDriverConfig.nc b/tos/chips/rf230/RF2xxDriverConfig.nc new file mode 100644 index 00000000..47f73378 --- /dev/null +++ b/tos/chips/rf230/RF2xxDriverConfig.nc @@ -0,0 +1,71 @@ +/* + * 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 + */ + +/** + * This interface needs to be implemented by the MAC to control the behaviour + * of the RF2xxDriverLayerC component. + */ +interface RF2xxDriverConfig +{ + /** + * Returns the length of the PHY payload (including the FCF field). + * This value must be in the range [3, 127]. + */ + async command uint8_t getLength(message_t* msg); + + /** + * Sets the length of the PHY payload. + */ + async command void setLength(message_t* msg, uint8_t len); + + /** + * Returns a pointer to the start of the PHY payload that contains + * getLength()-2 number of bytes. The FCF field (CRC-16) is not stored, + * but automatically appended / verified. + */ + async command uint8_t* getPayload(message_t* msg); + + /** + * 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. The header length must be at least one. + */ + async command uint8_t getHeaderLength(); + + /** + * Returns the maximum PHY length that can be set via the setLength command + */ + async command uint8_t getMaxLength(); + + /** + * This command is used at power up to set the default channel. + * The default CC2420 channel is 26. + */ + async command uint8_t getDefaultChannel(); + + /** + * Returns TRUE if before sending this message we should make sure that + * the channel is clear via a very basic (and quick) RSSI check. + */ + async command bool requiresRssiCca(message_t* msg); +} diff --git a/tos/chips/rf230/RF2xxDriverLayerC.nc b/tos/chips/rf230/RF2xxDriverLayerC.nc new file mode 100644 index 00000000..5ce75ebf --- /dev/null +++ b/tos/chips/rf230/RF2xxDriverLayerC.nc @@ -0,0 +1,78 @@ +/* + * 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 + */ + +configuration RF2xxDriverLayerC +{ + provides + { + interface RadioState; + interface RadioSend; + interface RadioReceive; + interface RadioCCA; + } + + uses interface RF2xxDriverConfig; +} + +implementation +{ + components RF2xxDriverLayerP, HplRF2xxC, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC, RF2xxPacketC, LocalTimeMicroC as LocalTimeRadioC; + + RadioState = RF2xxDriverLayerP; + RadioSend = RF2xxDriverLayerP; + RadioReceive = RF2xxDriverLayerP; + RadioCCA = RF2xxDriverLayerP; + + RF2xxDriverConfig = RF2xxDriverLayerP; + + RF2xxDriverLayerP.PacketLinkQuality -> RF2xxPacketC.PacketLinkQuality; + RF2xxDriverLayerP.PacketTransmitPower -> RF2xxPacketC.PacketTransmitPower; + RF2xxDriverLayerP.PacketRSSI -> RF2xxPacketC.PacketRSSI; + RF2xxDriverLayerP.PacketTimeSyncOffset -> RF2xxPacketC.PacketTimeSyncOffset; + RF2xxDriverLayerP.PacketTimeStamp -> RF2xxPacketC; + RF2xxDriverLayerP.LocalTime -> LocalTimeRadioC; + + RF2xxDriverLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; + RadioAlarmC.Alarm -> HplRF2xxC.Alarm; + + RF2xxDriverLayerP.SELN -> HplRF2xxC.SELN; + RF2xxDriverLayerP.SpiResource -> HplRF2xxC.SpiResource; + RF2xxDriverLayerP.FastSpiByte -> HplRF2xxC; + + RF2xxDriverLayerP.SLP_TR -> HplRF2xxC.SLP_TR; + RF2xxDriverLayerP.RSTN -> HplRF2xxC.RSTN; + + RF2xxDriverLayerP.IRQ -> HplRF2xxC.IRQ; + RF2xxDriverLayerP.Tasklet -> TaskletC; + RF2xxDriverLayerP.BusyWait -> BusyWaitMicroC; + +#ifdef RF2XX_DEBUG + components DiagMsgC; + RF2xxDriverLayerP.DiagMsg -> DiagMsgC; +#endif + + MainC.SoftwareInit -> RF2xxDriverLayerP.SoftwareInit; + + components RealMainP; + RealMainP.PlatformInit -> RF2xxDriverLayerP.PlatformInit; +} diff --git a/tos/chips/rf230/RF2xxDriverLayerP.nc b/tos/chips/rf230/RF2xxDriverLayerP.nc new file mode 100644 index 00000000..c23a8222 --- /dev/null +++ b/tos/chips/rf230/RF2xxDriverLayerP.nc @@ -0,0 +1,822 @@ +/* + * 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 + */ + +#include +#include +#include +#include +#include +#include + +module RF2xxDriverLayerP +{ + provides + { + interface Init as PlatformInit @exactlyonce(); + interface Init as SoftwareInit @exactlyonce(); + + interface RadioState; + interface RadioSend; + interface RadioReceive; + interface RadioCCA; + } + + uses + { + interface GeneralIO as SELN; + interface Resource as SpiResource; + + interface FastSpiByte; + + interface GeneralIO as SLP_TR; + interface GeneralIO as RSTN; + + interface GpioCapture as IRQ; + + interface BusyWait; + + interface PacketField as PacketLinkQuality; + interface PacketField as PacketTransmitPower; + interface PacketField as PacketRSSI; + interface PacketField as PacketTimeSyncOffset; + + interface PacketTimeStamp; + interface LocalTime; + + interface RF2xxDriverConfig; + interface Tasklet; + interface RadioAlarm; + +#ifdef RF2XX_DEBUG + interface DiagMsg; +#endif + } +} + +implementation +{ +/*----------------- STATE -----------------*/ + + tasklet_norace uint8_t state; + enum + { + STATE_P_ON = 0, + STATE_SLEEP = 1, + STATE_SLEEP_2_TRX_OFF = 2, + STATE_TRX_OFF = 3, + STATE_TRX_OFF_2_RX_ON = 4, + STATE_RX_ON = 5, + STATE_BUSY_TX_2_RX_ON = 6, + STATE_PLL_ON_2_RX_ON = 7, + }; + + tasklet_norace uint8_t cmd; + enum + { + CMD_NONE = 0, // the state machine has stopped + CMD_TURNOFF = 1, // goto SLEEP state + CMD_STANDBY = 2, // goto TRX_OFF state + CMD_TURNON = 3, // goto RX_ON state + CMD_TRANSMIT = 4, // currently transmitting a message + CMD_RECEIVE = 5, // currently receiving a message + CMD_CCA = 6, // performing clear chanel assesment + CMD_CHANNEL = 7, // changing the channel + CMD_SIGNAL_DONE = 8, // signal the end of the state transition + CMD_DOWNLOAD = 9, // download the received message + }; + + norace bool radioIrq; + + tasklet_norace uint8_t txPower; + tasklet_norace uint8_t channel; + + tasklet_norace message_t* rxMsg; + message_t rxMsgBuffer; + + uint16_t capturedTime; // the current time when the last interrupt has occured + + tasklet_norace uint8_t rssiClear; + tasklet_norace uint8_t rssiBusy; + +/*----------------- REGISTER -----------------*/ + + inline void writeRegister(uint8_t reg, uint8_t value) + { + ASSERT( call SpiResource.isOwner() ); + ASSERT( reg == (reg & RF2XX_CMD_REGISTER_MASK) ); + + call SELN.clr(); + call FastSpiByte.splitWrite(RF2XX_CMD_REGISTER_WRITE | reg); + call FastSpiByte.splitReadWrite(value); + call FastSpiByte.splitRead(); + call SELN.set(); + } + + inline uint8_t readRegister(uint8_t reg) + { + ASSERT( call SpiResource.isOwner() ); + ASSERT( reg == (reg & RF2XX_CMD_REGISTER_MASK) ); + + call SELN.clr(); + call FastSpiByte.splitWrite(RF2XX_CMD_REGISTER_READ | reg); + call FastSpiByte.splitReadWrite(0); + reg = call FastSpiByte.splitRead(); + call SELN.set(); + + return reg; + } + +/*----------------- ALARM -----------------*/ + + enum + { + SLEEP_WAKEUP_TIME = (uint16_t)(880 * RADIO_ALARM_MICROSEC), + CCA_REQUEST_TIME = (uint16_t)(140 * RADIO_ALARM_MICROSEC), + + TX_SFD_DELAY = (uint16_t)(176 * RADIO_ALARM_MICROSEC), + RX_SFD_DELAY = (uint16_t)(8 * RADIO_ALARM_MICROSEC), + }; + + tasklet_async event void RadioAlarm.fired() + { + if( state == STATE_SLEEP_2_TRX_OFF ) + state = STATE_TRX_OFF; + else if( cmd == CMD_CCA ) + { + uint8_t cca; + + ASSERT( state == STATE_RX_ON ); + + cmd = CMD_NONE; + cca = readRegister(RF2XX_TRX_STATUS); + + ASSERT( (cca & RF2XX_TRX_STATUS_MASK) == RF2XX_RX_ON ); + + signal RadioCCA.done( (cca & RF2XX_CCA_DONE) ? ((cca & RF2XX_CCA_STATUS) ? SUCCESS : EBUSY) : FAIL ); + } + else + ASSERT(FALSE); + + // make sure the rest of the command processing is called + call Tasklet.schedule(); + } + +/*----------------- INIT -----------------*/ + + command error_t PlatformInit.init() + { + call SELN.makeOutput(); + call SELN.set(); + call SLP_TR.makeOutput(); + call SLP_TR.clr(); + call RSTN.makeOutput(); + call RSTN.set(); + + rxMsg = &rxMsgBuffer; + + // these are just good approximates + rssiClear = 0; + rssiBusy = 90; + + return SUCCESS; + } + + command error_t SoftwareInit.init() + { + // for powering up the radio + return call SpiResource.request(); + } + + void initRadio() + { + call BusyWait.wait(510); + + call RSTN.clr(); + call SLP_TR.clr(); + call BusyWait.wait(6); + call RSTN.set(); + + writeRegister(RF2XX_TRX_CTRL_0, RF2XX_TRX_CTRL_0_VALUE); + writeRegister(RF2XX_TRX_STATE, RF2XX_TRX_OFF); + + call BusyWait.wait(510); + + writeRegister(RF2XX_IRQ_MASK, RF2XX_IRQ_TRX_UR | RF2XX_IRQ_PLL_LOCK | RF2XX_IRQ_TRX_END | RF2XX_IRQ_RX_START); + writeRegister(RF2XX_CCA_THRES, RF2XX_CCA_THRES_VALUE); + writeRegister(RF2XX_PHY_TX_PWR, RF2XX_TX_AUTO_CRC_ON | RF2XX_TX_PWR_DEFAULT); + + txPower = RF2XX_TX_PWR_DEFAULT; + channel = call RF2xxDriverConfig.getDefaultChannel() & RF2XX_CHANNEL_MASK; + writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_MODE_VALUE | channel); + + call SLP_TR.set(); + state = STATE_SLEEP; + } + +/*----------------- SPI -----------------*/ + + event void SpiResource.granted() + { + call SELN.makeOutput(); + call SELN.set(); + + if( state == STATE_P_ON ) + { + initRadio(); + call SpiResource.release(); + } + else + call Tasklet.schedule(); + } + + bool isSpiAcquired() + { + if( call SpiResource.isOwner() ) + return TRUE; + + if( call SpiResource.immediateRequest() == SUCCESS ) + { + call SELN.makeOutput(); + call SELN.set(); + + return TRUE; + } + + call SpiResource.request(); + return FALSE; + } + +/*----------------- CHANNEL -----------------*/ + + tasklet_async command uint8_t RadioState.getChannel() + { + return channel; + } + + tasklet_async command error_t RadioState.setChannel(uint8_t c) + { + c &= RF2XX_CHANNEL_MASK; + + if( cmd != CMD_NONE ) + return EBUSY; + else if( channel == c ) + return EALREADY; + + channel = c; + cmd = CMD_CHANNEL; + call Tasklet.schedule(); + + return SUCCESS; + } + + inline void changeChannel() + { + ASSERT( cmd == CMD_CHANNEL ); + ASSERT( state == STATE_SLEEP || state == STATE_TRX_OFF || state == STATE_RX_ON ); + + if( isSpiAcquired() ) + { + writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_MODE_VALUE | channel); + + if( state == STATE_RX_ON ) + state = STATE_TRX_OFF_2_RX_ON; + else + cmd = CMD_SIGNAL_DONE; + } + } + +/*----------------- TURN ON/OFF -----------------*/ + + inline void changeState() + { + if( (cmd == CMD_STANDBY || cmd == CMD_TURNON) + && state == STATE_SLEEP && call RadioAlarm.isFree() ) + { + call SLP_TR.clr(); + + call RadioAlarm.wait(SLEEP_WAKEUP_TIME); + state = STATE_SLEEP_2_TRX_OFF; + } + else if( cmd == CMD_TURNON && state == STATE_TRX_OFF && isSpiAcquired() ) + { + ASSERT( ! radioIrq ); + + readRegister(RF2XX_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(RF2XX_PHY_CC_CCA, RF2XX_CCA_MODE_VALUE | channel); + + writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON); + state = STATE_TRX_OFF_2_RX_ON; + } + else if( (cmd == CMD_TURNOFF || cmd == CMD_STANDBY) + && state == STATE_RX_ON && isSpiAcquired() ) + { + writeRegister(RF2XX_TRX_STATE, RF2XX_FORCE_TRX_OFF); + + call IRQ.disable(); + radioIrq = FALSE; + + state = STATE_TRX_OFF; + } + + if( cmd == CMD_TURNOFF && state == STATE_TRX_OFF ) + { + call SLP_TR.set(); + state = STATE_SLEEP; + cmd = CMD_SIGNAL_DONE; + } + else if( cmd == CMD_STANDBY && state == STATE_TRX_OFF ) + cmd = CMD_SIGNAL_DONE; + } + + tasklet_async command error_t RadioState.turnOff() + { + if( cmd != CMD_NONE ) + return EBUSY; + else if( state == STATE_SLEEP ) + return EALREADY; + + cmd = CMD_TURNOFF; + call Tasklet.schedule(); + + return SUCCESS; + } + + tasklet_async command error_t RadioState.standby() + { + if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) ) + return EBUSY; + else if( state == STATE_TRX_OFF ) + return EALREADY; + + cmd = CMD_STANDBY; + call Tasklet.schedule(); + + return SUCCESS; + } + + tasklet_async command error_t RadioState.turnOn() + { + if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) ) + return EBUSY; + else if( state == STATE_RX_ON ) + return EALREADY; + + cmd = CMD_TURNON; + call Tasklet.schedule(); + + return SUCCESS; + } + + default tasklet_async event void RadioState.done() { } + +/*----------------- TRANSMIT -----------------*/ + + tasklet_async command error_t RadioSend.send(message_t* msg) + { + uint16_t time; + uint8_t length; + uint8_t* data; + uint8_t header; + uint32_t time32; + void* timesync; + + if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq ) + return EBUSY; + + length = (call PacketTransmitPower.isSet(msg) ? + call PacketTransmitPower.get(msg) : RF2XX_DEF_RFPOWER) & RF2XX_TX_PWR_MASK; + + if( length != txPower ) + { + txPower = length; + writeRegister(RF2XX_PHY_TX_PWR, RF2XX_TX_AUTO_CRC_ON | txPower); + } + + if( call RF2xxDriverConfig.requiresRssiCca(msg) + && (readRegister(RF2XX_PHY_RSSI) & RF2XX_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) ) + return EBUSY; + + writeRegister(RF2XX_TRX_STATE, RF2XX_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(RF2XX_TRX_STATUS) & RF2XX_TRX_STATUS_MASK) != RF2XX_PLL_ON ) + { + ASSERT( (readRegister(RF2XX_TRX_STATUS) & RF2XX_TRX_STATUS_MASK) == RF2XX_BUSY_RX ); + + state = STATE_PLL_ON_2_RX_ON; + return EBUSY; + } + + atomic + { + call SLP_TR.set(); + time = call RadioAlarm.getNow() + TX_SFD_DELAY; + } + call SLP_TR.clr(); + + ASSERT( ! radioIrq ); + + call SELN.clr(); + call FastSpiByte.splitWrite(RF2XX_CMD_FRAME_WRITE); + + length = call RF2xxDriverConfig.getLength(msg); + data = call RF2xxDriverConfig.getPayload(msg); + + // length | data[0] ... data[length-3] | automatically generated FCS + call FastSpiByte.splitReadWrite(length); + + // the FCS is atomatically generated (2 bytes) + length -= 2; + + header = call RF2xxDriverConfig.getHeaderLength(); + if( header > length ) + header = length; + + length -= header; + + // first upload the header to gain some time + do { + call FastSpiByte.splitReadWrite(*(data++)); + } + while( --header != 0 ); + + time32 += (int16_t)(time) - (int16_t)(time32); + + if( timesync != 0 ) + *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32; + + do { + call FastSpiByte.splitReadWrite(*(data++)); + } + while( --length != 0 ); + + // wait for the SPI transfer to finish + call FastSpiByte.splitRead(); + call SELN.set(); + + /* + * There is a very small window (~1 microsecond) when the RF2xx went + * into PLL_ON state but was somehow not properly initialized because + * of an incoming message and could not go into BUSY_TX. I think the + * radio can even receive a message, and generate a TRX_UR interrupt + * because of concurrent access, but that message probably cannot be + * recovered. + * + * TODO: this needs to be verified, and make sure that the chip is + * not locked up in this case. + */ + + // go back to RX_ON state when finished + writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON); + +#ifdef RF2XX_DEBUG_MESSAGES + if( call DiagMsg.record() ) + { + length = call RF2xxDriverConfig.getLength(msg); + + call DiagMsg.str("tx"); + call DiagMsg.uint16(time); + call DiagMsg.uint8(length); + call DiagMsg.hex8s(data, 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; + + return SUCCESS; + } + + default tasklet_async event void RadioSend.sendDone(error_t error) { } + default tasklet_async event void RadioSend.ready() { } + +/*----------------- CCA -----------------*/ + + tasklet_async command error_t RadioCCA.request() + { + if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || ! call RadioAlarm.isFree() ) + return EBUSY; + + // see Errata B7 of the datasheet + // writeRegister(RF2XX_TRX_STATE, RF2XX_PLL_ON); + // writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON); + + writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_REQUEST | RF2XX_CCA_MODE_VALUE | channel); + call RadioAlarm.wait(CCA_REQUEST_TIME); + cmd = CMD_CCA; + + return SUCCESS; + } + + default tasklet_async event void RadioCCA.done(error_t error) { } + +/*----------------- RECEIVE -----------------*/ + + inline void downloadMessage() + { + uint8_t length; + uint16_t crc; + + call SELN.clr(); + call FastSpiByte.write(RF2XX_CMD_FRAME_READ); + + // read the length byte + length = call FastSpiByte.write(0); + + // if correct length + if( length >= 3 && length <= call RF2xxDriverConfig.getMaxLength() ) + { + uint8_t read; + uint8_t* data; + + // initiate the reading + call FastSpiByte.splitWrite(0); + + call RF2xxDriverConfig.setLength(rxMsg, length); + data = call RF2xxDriverConfig.getPayload(rxMsg); + crc = 0; + + // we do not store the CRC field + length -= 2; + + read = call RF2xxDriverConfig.getHeaderLength(); + if( length < read ) + read = length; + + length -= read; + + do { + crc = RF2XX_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0)); + } + while( --read != 0 ); + + if( signal RadioReceive.header(rxMsg) ) + { + while( length-- != 0 ) + crc = RF2XX_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0)); + + crc = RF2XX_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0)); + crc = RF2XX_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0)); + + call PacketLinkQuality.set(rxMsg, call FastSpiByte.splitRead()); + } + else + crc = 1; + } + else + crc = 1; + + call SELN.set(); + state = STATE_RX_ON; + +#ifdef RF2XX_DEBUG_MESSAGES + if( call DiagMsg.record() ) + { + length = call RF2xxDriverConfig.getLength(rxMsg); + + call DiagMsg.str("rx"); + 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 RF2xxDriverConfig.getPayload(rxMsg), length - 2); + call DiagMsg.send(); + } +#endif + + cmd = CMD_NONE; + + // signal only if it has passed the CRC check + if( crc == 0 ) + rxMsg = signal RadioReceive.receive(rxMsg); + } + +/*----------------- IRQ -----------------*/ + + async event void IRQ.captured(uint16_t time) + { + ASSERT( ! radioIrq ); + + atomic + { + capturedTime = time; + radioIrq = TRUE; + } + + call Tasklet.schedule(); + } + + void serviceRadio() + { + if( isSpiAcquired() ) + { + uint16_t time; + uint32_t time32; + uint8_t irq; + uint8_t temp; + + atomic time = capturedTime; + radioIrq = FALSE; + irq = readRegister(RF2XX_IRQ_STATUS); + +#ifdef RF2XX_DEBUG + // TODO: handle this interrupt + if( irq & RF2XX_IRQ_TRX_UR ) + { + if( call DiagMsg.record() ) + { + call DiagMsg.str("assert ur"); + call DiagMsg.uint16(call RadioAlarm.getNow()); + call DiagMsg.hex8(readRegister(RF2XX_TRX_STATUS)); + call DiagMsg.hex8(readRegister(RF2XX_TRX_STATE)); + call DiagMsg.hex8(irq); + call DiagMsg.uint8(state); + call DiagMsg.uint8(cmd); + call DiagMsg.send(); + } + } +#endif + + if( irq & RF2XX_IRQ_PLL_LOCK ) + { + if( cmd == CMD_TURNON || cmd == CMD_CHANNEL ) + { + ASSERT( state == STATE_TRX_OFF_2_RX_ON ); + + state = STATE_RX_ON; + cmd = CMD_SIGNAL_DONE; + } + else if( cmd == CMD_TRANSMIT ) + { + ASSERT( state == STATE_BUSY_TX_2_RX_ON ); + } + else + ASSERT(FALSE); + } + + if( irq & RF2XX_IRQ_RX_START ) + { + if( cmd == CMD_CCA ) + { + signal RadioCCA.done(FAIL); + cmd = CMD_NONE; + } + + if( cmd == CMD_NONE ) + { + ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON ); + + // the most likely place for busy channel, with no TRX_END interrupt + if( irq == RF2XX_IRQ_RX_START ) + { + temp = readRegister(RF2XX_PHY_RSSI) & RF2XX_RSSI_MASK; + rssiBusy += temp - (rssiBusy >> 2); +#ifndef RF2XX_RSSI_ENERGY + call PacketRSSI.set(rxMsg, temp); + } + else + { + call PacketRSSI.clear(rxMsg); +#endif + } + + /* + * The timestamp corresponds to the first event which could not + * have been a PLL_LOCK because then cmd != CMD_NONE, so we must + * have received a message (and could also have received the + * TRX_END interrupt in the mean time, but that is fine. Also, + * we could not be after a transmission, because then cmd = + * CMD_TRANSMIT. + */ + if( irq == RF2XX_IRQ_RX_START ) // just to be cautious + { + time32 = call LocalTime.get(); + time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32); + call PacketTimeStamp.set(rxMsg, time32); + } + else + call PacketTimeStamp.clear(rxMsg); + + cmd = CMD_RECEIVE; + } + else + ASSERT( cmd == CMD_TURNOFF ); + } + + if( irq & RF2XX_IRQ_TRX_END ) + { + if( cmd == CMD_TRANSMIT ) + { + ASSERT( state == STATE_BUSY_TX_2_RX_ON ); + + state = STATE_RX_ON; + cmd = CMD_NONE; + signal RadioSend.sendDone(SUCCESS); + + // TODO: we could have missed a received message + ASSERT( ! (irq & RF2XX_IRQ_RX_START) ); + } + else if( cmd == CMD_RECEIVE ) + { + ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON ); +#ifdef RF2XX_RSSI_ENERGY + if( irq == RF2XX_IRQ_TRX_END ) + call PacketRSSI.set(rxMsg, readRegister(RF2XX_PHY_ED_LEVEL)); + else + call PacketRSSI.clear(rxMsg); +#endif + if( state == STATE_PLL_ON_2_RX_ON ) + { + ASSERT( (readRegister(RF2XX_TRX_STATUS) & RF2XX_TRX_STATUS_MASK) == RF2XX_PLL_ON ); + + writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON); + state = STATE_RX_ON; + } + else + { + // the most likely place for clear channel (hope to avoid acks) + rssiClear += (readRegister(RF2XX_PHY_RSSI) & RF2XX_RSSI_MASK) - (rssiClear >> 2); + } + + cmd = CMD_DOWNLOAD; + } + else + ASSERT(FALSE); + } + } + } + + default tasklet_async event bool RadioReceive.header(message_t* msg) + { + return TRUE; + } + + default tasklet_async event message_t* RadioReceive.receive(message_t* msg) + { + return msg; + } + +/*----------------- TASKLET -----------------*/ + + tasklet_async event void Tasklet.run() + { + if( radioIrq ) + serviceRadio(); + + if( cmd != CMD_NONE ) + { + if( cmd == CMD_DOWNLOAD ) + downloadMessage(); + else if( CMD_TURNOFF <= cmd && cmd <= CMD_TURNON ) + changeState(); + else if( cmd == CMD_CHANNEL ) + changeChannel(); + + if( cmd == CMD_SIGNAL_DONE ) + { + cmd = CMD_NONE; + signal RadioState.done(); + } + } + + if( cmd == CMD_NONE && state == STATE_RX_ON && ! radioIrq ) + signal RadioSend.ready(); + + if( cmd == CMD_NONE ) + call SpiResource.release(); + } +} diff --git a/tos/chips/rf230/RF2xxPacket.h b/tos/chips/rf230/RF2xxPacket.h new file mode 100644 index 00000000..d3b6898b --- /dev/null +++ b/tos/chips/rf230/RF2xxPacket.h @@ -0,0 +1,59 @@ +/* + * 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 __RF2XXPACKET_H__ +#define __RF2XXPACKET_H__ + +#include + +typedef ieee154_header_t rf2xxpacket_header_t; + +typedef nx_struct rf2xxpacket_footer_t +{ + // the time stamp is not recorded here, time stamped messaged cannot have max length +} rf2xxpacket_footer_t; + +typedef struct rf2xxpacket_metadata_t +{ + uint8_t flags; + uint8_t lqi; + uint8_t power; // shared between TXPOWER and RSSI +#ifdef LOW_POWER_LISTENING + uint16_t lpl_sleepint; +#endif + uint32_t timestamp; +} rf2xxpacket_metadata_t; + +enum rf2xxpacket_metadata_flags +{ + RF2XXPACKET_WAS_ACKED = 0x01, // PacketAcknowledgements + RF2XXPACKET_TIMESTAMP = 0x02, // PacketTimeStamp + RF2XXPACKET_TXPOWER = 0x04, // PacketTransmitPower + RF2XXPACKET_RSSI = 0x08, // PacketRSSI + RF2XXPACKET_TIMESYNC = 0x10, // PacketTimeSync (update timesync_footer) + RF2XXPACKET_LPL_SLEEPINT = 0x20, // LowPowerListening + + RF2XXPACKET_CLEAR_METADATA = 0x00, +}; + +#endif//__RF2XXPACKET_H__ diff --git a/tos/chips/rf230/RF2xxPacketC.nc b/tos/chips/rf230/RF2xxPacketC.nc new file mode 100644 index 00000000..70b9add2 --- /dev/null +++ b/tos/chips/rf230/RF2xxPacketC.nc @@ -0,0 +1,62 @@ +/* + * 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 + */ + +configuration RF2xxPacketC +{ + provides + { + interface Packet; + interface AMPacket; + interface PacketAcknowledgements; + interface PacketField as PacketLinkQuality; + interface PacketField as PacketTransmitPower; + interface PacketField as PacketRSSI; + interface PacketField as PacketSleepInterval; + interface PacketField as PacketTimeSyncOffset; + + interface PacketTimeStamp as PacketTimeStampRadio; + interface PacketTimeStamp as PacketTimeStampMilli; + } +} + +implementation +{ + components RF2xxPacketP, IEEE154PacketC, LocalTimeMicroC, LocalTimeMilliC; + + RF2xxPacketP.IEEE154Packet -> IEEE154PacketC; + RF2xxPacketP.LocalTimeRadio -> LocalTimeMicroC; + RF2xxPacketP.LocalTimeMilli -> LocalTimeMilliC; + + Packet = RF2xxPacketP; + AMPacket = IEEE154PacketC; + + PacketAcknowledgements = RF2xxPacketP; + PacketLinkQuality = RF2xxPacketP.PacketLinkQuality; + PacketTransmitPower = RF2xxPacketP.PacketTransmitPower; + PacketRSSI = RF2xxPacketP.PacketRSSI; + PacketSleepInterval = RF2xxPacketP.PacketSleepInterval; + PacketTimeSyncOffset = RF2xxPacketP.PacketTimeSyncOffset; + + PacketTimeStampRadio = RF2xxPacketP; + PacketTimeStampMilli = RF2xxPacketP; +} diff --git a/tos/chips/rf230/RF2xxPacketP.nc b/tos/chips/rf230/RF2xxPacketP.nc new file mode 100644 index 00000000..5a727575 --- /dev/null +++ b/tos/chips/rf230/RF2xxPacketP.nc @@ -0,0 +1,291 @@ +/* + * 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 + */ + +#include +#include + +module RF2xxPacketP +{ + provides + { + interface PacketAcknowledgements; + interface Packet; + interface PacketField as PacketLinkQuality; + interface PacketField as PacketTransmitPower; + interface PacketField as PacketRSSI; + interface PacketField as PacketSleepInterval; + interface PacketField as PacketTimeSyncOffset; + + interface PacketTimeStamp as PacketTimeStampRadio; + interface PacketTimeStamp as PacketTimeStampMilli; + } + + uses + { + interface IEEE154Packet; + + interface LocalTime as LocalTimeRadio; + interface LocalTime as LocalTimeMilli; + } +} + +implementation +{ + enum + { + PACKET_LENGTH_INCREASE = + sizeof(rf2xxpacket_header_t) - 1 // the 8-bit length field is not counted + + sizeof(ieee154_footer_t), // the CRC is not stored in memory + }; + + inline rf2xxpacket_metadata_t* getMeta(message_t* msg) + { + return (rf2xxpacket_metadata_t*)(msg->metadata); + } + +/*----------------- Packet -----------------*/ + + command void Packet.clear(message_t* msg) + { + call IEEE154Packet.createDataFrame(msg); + + getMeta(msg)->flags = RF2XXPACKET_CLEAR_METADATA; + } + + inline command void Packet.setPayloadLength(message_t* msg, uint8_t len) + { + call IEEE154Packet.setLength(msg, len + PACKET_LENGTH_INCREASE); + } + + inline command uint8_t Packet.payloadLength(message_t* msg) + { + return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE; + } + + inline command uint8_t Packet.maxPayloadLength() + { + return TOSH_DATA_LENGTH; + } + + command void* Packet.getPayload(message_t* msg, uint8_t len) + { + if( len > TOSH_DATA_LENGTH ) + return NULL; + + return msg->data; + } + +/*----------------- PacketAcknowledgements -----------------*/ + + async command error_t PacketAcknowledgements.requestAck(message_t* msg) + { + call IEEE154Packet.setAckRequired(msg, TRUE); + + return SUCCESS; + } + + async command error_t PacketAcknowledgements.noAck(message_t* msg) + { + call IEEE154Packet.setAckRequired(msg, FALSE); + + return SUCCESS; + } + + async command bool PacketAcknowledgements.wasAcked(message_t* msg) + { + return getMeta(msg)->flags & RF2XXPACKET_WAS_ACKED; + } + +/*----------------- 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; + } + +/*----------------- PacketTimeStampRadio -----------------*/ + + async command bool PacketTimeStampRadio.isValid(message_t* msg) + { + return getMeta(msg)->flags & RF2XXPACKET_TIMESTAMP; + } + + async command uint32_t PacketTimeStampRadio.timestamp(message_t* msg) + { + return getMeta(msg)->timestamp; + } + + async command void PacketTimeStampRadio.clear(message_t* msg) + { + getMeta(msg)->flags &= ~RF2XXPACKET_TIMESTAMP; + } + + async command void PacketTimeStampRadio.set(message_t* msg, uint32_t value) + { + getMeta(msg)->flags |= RF2XXPACKET_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) + { + return getMeta(msg)->flags & RF2XXPACKET_TXPOWER; + } + + async command uint8_t PacketTransmitPower.get(message_t* msg) + { + return getMeta(msg)->power; + } + + async command void PacketTransmitPower.clear(message_t* msg) + { + getMeta(msg)->flags &= ~RF2XXPACKET_TXPOWER; + } + + async command void PacketTransmitPower.set(message_t* msg, uint8_t value) + { + getMeta(msg)->flags &= ~RF2XXPACKET_RSSI; + getMeta(msg)->flags |= RF2XXPACKET_TXPOWER; + getMeta(msg)->power = value; + } + +/*----------------- PacketRSSI -----------------*/ + + async command bool PacketRSSI.isSet(message_t* msg) + { + return getMeta(msg)->flags & RF2XXPACKET_RSSI; + } + + async command uint8_t PacketRSSI.get(message_t* msg) + { + return getMeta(msg)->power; + } + + async command void PacketRSSI.clear(message_t* msg) + { + getMeta(msg)->flags &= ~RF2XXPACKET_RSSI; + } + + async command void PacketRSSI.set(message_t* msg, uint8_t value) + { + getMeta(msg)->flags &= ~RF2XXPACKET_TXPOWER; + getMeta(msg)->flags |= RF2XXPACKET_RSSI; + getMeta(msg)->power = value; + } + +/*----------------- PacketTimeSyncOffset -----------------*/ + + async command bool PacketTimeSyncOffset.isSet(message_t* msg) + { + return getMeta(msg)->flags & RF2XXPACKET_TIMESYNC; + } + + async command uint8_t PacketTimeSyncOffset.get(message_t* msg) + { + return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE - sizeof(timesync_absolute_t); + } + + async command void PacketTimeSyncOffset.clear(message_t* msg) + { + getMeta(msg)->flags &= ~RF2XXPACKET_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 |= RF2XXPACKET_TIMESYNC; + } + +/*----------------- PacketSleepInterval -----------------*/ + + async command bool PacketSleepInterval.isSet(message_t* msg) + { + return getMeta(msg)->flags & RF2XXPACKET_LPL_SLEEPINT; + } + + async command uint16_t PacketSleepInterval.get(message_t* msg) + { +#ifdef LOW_POWER_LISTENING + return getMeta(msg)->lpl_sleepint; +#else + return 0; +#endif + } + + async command void PacketSleepInterval.clear(message_t* msg) + { + getMeta(msg)->flags &= ~RF2XXPACKET_LPL_SLEEPINT; + } + + async command void PacketSleepInterval.set(message_t* msg, uint16_t value) + { + getMeta(msg)->flags |= RF2XXPACKET_LPL_SLEEPINT; + +#ifdef LOW_POWER_LISTENING + getMeta(msg)->lpl_sleepint = value; +#endif + } +} diff --git a/tos/chips/rf230/RF2xxTimeSyncMessageC.nc b/tos/chips/rf230/RF2xxTimeSyncMessageC.nc new file mode 100644 index 00000000..88da07e5 --- /dev/null +++ b/tos/chips/rf230/RF2xxTimeSyncMessageC.nc @@ -0,0 +1,72 @@ +/* + * 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 + */ + +#include +#include +#include + +configuration RF2xxTimeSyncMessageC +{ + provides + { + interface SplitControl; + + interface Receive[uint8_t id]; + interface Receive as Snoop[am_id_t id]; + interface Packet; + interface AMPacket; + + interface TimeSyncAMSend as TimeSyncAMSendRadio[am_id_t id]; + interface TimeSyncPacket as TimeSyncPacketRadio; + + interface TimeSyncAMSend as TimeSyncAMSendMilli[am_id_t id]; + interface TimeSyncPacket as TimeSyncPacketMilli; + } +} + +implementation +{ + components RF2xxTimeSyncMessageP, RF2xxActiveMessageC, LocalTimeMilliC, LocalTimeMicroC as LocalTimeRadioC, RF2xxPacketC; + + TimeSyncAMSendRadio = RF2xxTimeSyncMessageP; + TimeSyncPacketRadio = RF2xxTimeSyncMessageP; + + TimeSyncAMSendMilli = RF2xxTimeSyncMessageP; + TimeSyncPacketMilli = RF2xxTimeSyncMessageP; + + Packet = RF2xxTimeSyncMessageP; + RF2xxTimeSyncMessageP.SubSend -> RF2xxActiveMessageC.AMSend; + RF2xxTimeSyncMessageP.SubPacket -> RF2xxActiveMessageC.Packet; + + RF2xxTimeSyncMessageP.PacketTimeStampRadio -> RF2xxActiveMessageC; + RF2xxTimeSyncMessageP.PacketTimeStampMilli -> RF2xxActiveMessageC; + RF2xxTimeSyncMessageP.LocalTimeRadio -> LocalTimeRadioC; + RF2xxTimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC; + + RF2xxTimeSyncMessageP.PacketTimeSyncOffset -> RF2xxPacketC.PacketTimeSyncOffset; + + SplitControl = RF2xxActiveMessageC; + Receive = RF2xxActiveMessageC.Receive; + Snoop = RF2xxActiveMessageC.Snoop; + AMPacket = RF2xxActiveMessageC; +} diff --git a/tos/chips/rf230/RF2xxTimeSyncMessageP.nc b/tos/chips/rf230/RF2xxTimeSyncMessageP.nc new file mode 100644 index 00000000..fd5dfc88 --- /dev/null +++ b/tos/chips/rf230/RF2xxTimeSyncMessageP.nc @@ -0,0 +1,187 @@ +/* + * 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 + */ + +#include +#include + +module RF2xxTimeSyncMessageP +{ + provides + { + interface TimeSyncAMSend as TimeSyncAMSendRadio[uint8_t id]; + interface TimeSyncAMSend as TimeSyncAMSendMilli[uint8_t id]; + interface Packet; + + interface TimeSyncPacket as TimeSyncPacketRadio; + interface TimeSyncPacket as TimeSyncPacketMilli; + } + + uses + { + interface AMSend as SubSend[uint8_t id]; + interface Packet as SubPacket; + + interface PacketTimeStamp as PacketTimeStampRadio; + interface PacketTimeStamp as PacketTimeStampMilli; + + interface LocalTime as LocalTimeRadio; + interface LocalTime as LocalTimeMilli; + + interface PacketField as PacketTimeSyncOffset; + } +} + +implementation +{ + 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 SubPacket.clear(msg); + } + + command void Packet.setPayloadLength(message_t* msg, uint8_t len) + { + call SubPacket.setPayloadLength(msg, len + sizeof(timesync_relative_t)); + } + + command uint8_t Packet.payloadLength(message_t* msg) + { + return call SubPacket.payloadLength(msg) - sizeof(timesync_relative_t); + } + + command uint8_t Packet.maxPayloadLength() + { + return call SubPacket.maxPayloadLength() - sizeof(timesync_relative_t); + } + + command void* Packet.getPayload(message_t* msg, uint8_t len) + { + return call SubPacket.getPayload(msg, len + sizeof(timesync_relative_t)); + } + +/*----------------- TimeSyncAMSendRadio -----------------*/ + + command error_t TimeSyncAMSendRadio.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time) + { + *(timesync_absolute_t*)(msg->data + len) = event_time; + + call PacketTimeSyncOffset.set(msg, len); + + return call SubSend.send[id](addr, msg, len + sizeof(timesync_relative_t)); + } + + command error_t TimeSyncAMSendRadio.cancel[am_id_t id](message_t* msg) + { + return call SubSend.cancel[id](msg); + } + + default event void TimeSyncAMSendRadio.sendDone[am_id_t id](message_t* msg, error_t error) + { + } + + command uint8_t TimeSyncAMSendRadio.maxPayloadLength[am_id_t id]() + { + return call SubSend.maxPayloadLength[id]() - sizeof(timesync_relative_t); + } + + command void* TimeSyncAMSendRadio.getPayload[am_id_t id](message_t* msg, uint8_t len) + { + return call SubSend.getPayload[id](msg, len + sizeof(timesync_relative_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 = ((int32_t)(event_time - call LocalTimeMilli.get()) << 10) + call LocalTimeRadio.get(); + + return call TimeSyncAMSendRadio.send[id](addr, msg, len, event_time); + } + + command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg) + { + return call TimeSyncAMSendRadio.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 TimeSyncAMSendRadio.maxPayloadLength[id](); + } + + command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len) + { + return call TimeSyncAMSendRadio.getPayload[id](msg, len); + } + + /*----------------- SubSend.sendDone -------------------*/ + + event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error) + { + signal TimeSyncAMSendRadio.sendDone[id](msg, error); + signal TimeSyncAMSendMilli.sendDone[id](msg, error); + } + + /*----------------- TimeSyncPacketRadio -----------------*/ + + command bool TimeSyncPacketRadio.isValid(message_t* msg) + { + timesync_relative_t* timesync = getFooter(msg); + + return call PacketTimeStampRadio.isValid(msg) && *timesync != 0x80000000L; + } + + command uint32_t TimeSyncPacketRadio.eventTime(message_t* msg) + { + timesync_relative_t* timesync = getFooter(msg); + + return (*timesync) + call PacketTimeStampRadio.timestamp(msg); + } + + /*----------------- TimeSyncPacketMilli -----------------*/ + + command bool TimeSyncPacketMilli.isValid(message_t* msg) + { + timesync_relative_t* timesync = getFooter(msg); + + return call PacketTimeStampMilli.isValid(msg) && *timesync != 0x80000000L; + } + + command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg) + { + timesync_relative_t* timesync = getFooter(msg); + + return ((int32_t)(*timesync) >> 10) + call PacketTimeStampMilli.timestamp(msg); + } +} diff --git a/tos/platforms/iris/ActiveMessageC.nc b/tos/platforms/iris/ActiveMessageC.nc index ef6a2c3d..f16da57a 100644 --- a/tos/platforms/iris/ActiveMessageC.nc +++ b/tos/platforms/iris/ActiveMessageC.nc @@ -43,7 +43,7 @@ configuration ActiveMessageC implementation { - components RF230ActiveMessageC as MAC; + components RF2xxActiveMessageC as MAC; SplitControl = MAC; AMSend = MAC; diff --git a/tos/platforms/iris/TimeSyncMessageC.nc b/tos/platforms/iris/TimeSyncMessageC.nc index c0f0a61e..4bca9f68 100644 --- a/tos/platforms/iris/TimeSyncMessageC.nc +++ b/tos/platforms/iris/TimeSyncMessageC.nc @@ -21,7 +21,7 @@ * Author: Miklos Maroti */ -#include +#include configuration TimeSyncMessageC { @@ -44,17 +44,17 @@ configuration TimeSyncMessageC implementation { - components RF230TimeSyncMessageC; + components RF2xxTimeSyncMessageC; - SplitControl = RF230TimeSyncMessageC; + SplitControl = RF2xxTimeSyncMessageC; - Receive = RF230TimeSyncMessageC.Receive; - Snoop = RF230TimeSyncMessageC.Snoop; - Packet = RF230TimeSyncMessageC; - AMPacket = RF230TimeSyncMessageC; + Receive = RF2xxTimeSyncMessageC.Receive; + Snoop = RF2xxTimeSyncMessageC.Snoop; + Packet = RF2xxTimeSyncMessageC; + AMPacket = RF2xxTimeSyncMessageC; - TimeSyncAMSendRadio = RF230TimeSyncMessageC; - TimeSyncPacketRadio = RF230TimeSyncMessageC; - TimeSyncAMSendMilli = RF230TimeSyncMessageC; - TimeSyncPacketMilli = RF230TimeSyncMessageC; + TimeSyncAMSendRadio = RF2xxTimeSyncMessageC; + TimeSyncPacketRadio = RF2xxTimeSyncMessageC; + TimeSyncAMSendMilli = RF2xxTimeSyncMessageC; + TimeSyncPacketMilli = RF2xxTimeSyncMessageC; } diff --git a/tos/platforms/iris/chips/rf230/HplRF230.h b/tos/platforms/iris/chips/rf230/HplRF230.h deleted file mode 100644 index 63ae9db6..00000000 --- a/tos/platforms/iris/chips/rf230/HplRF230.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * 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 __HPLRF230_H__ -#define __HPLRF230_H__ - -#include -#include - -enum -{ - /** - * This is the value of the TRX_CTRL_0 register - * which configures the output pin currents and the CLKM clock - */ - RF230_TRX_CTRL_0_VALUE = 0, - - /** - * This is the default value of the CCA_MODE field in the PHY_CC_CCA register - * which is used to configure the default mode of the clear channel assesment - */ - RF230_CCA_MODE_VALUE = RF230_CCA_MODE_3, - - /** - * This is the value of the CCA_THRES register that controls the - * energy levels used for clear channel assesment - */ - RF230_CCA_THRES_VALUE = 0xC7, -}; - -/* This is the default value of the TX_PWR field of the PHY_TX_PWR register. */ -#ifndef RF230_DEF_RFPOWER -#define RF230_DEF_RFPOWER 0 -#endif - -/* This is the default value of the CHANNEL field of the PHY_CC_CCA register. */ -#ifndef RF230_DEF_CHANNEL -#define RF230_DEF_CHANNEL 11 -#endif - -// TODO: Check why the default crcByte implementation is in a different endianness -inline uint16_t RF230_CRCBYTE_COMMAND(uint16_t crc, uint8_t data) -{ - return _crc_ccitt_update(crc, data); -} - -#endif//__HPLRF230_H__ diff --git a/tos/platforms/iris/chips/rf230/HplRF230C.nc b/tos/platforms/iris/chips/rf230/HplRF230C.nc deleted file mode 100644 index 5ef56e04..00000000 --- a/tos/platforms/iris/chips/rf230/HplRF230C.nc +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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 - */ - -#include - -configuration HplRF230C -{ - provides - { - interface GeneralIO as SELN; - interface Resource as SpiResource; - interface FastSpiByte; - - interface GeneralIO as SLP_TR; - interface GeneralIO as RSTN; - - interface GpioCapture as IRQ; - interface Alarm as Alarm; - } -} - -implementation -{ - components HplRF230P; - IRQ = HplRF230P.IRQ; - - HplRF230P.PortCLKM -> IO.PortD6; - HplRF230P.PortIRQ -> IO.PortD4; - - components Atm128SpiC as SpiC; - SpiResource = SpiC.Resource[unique("Atm128SpiC.Resource")]; - - FastSpiByte = HplRF230P; - - components HplAtm128GeneralIOC as IO; - SLP_TR = IO.PortB7; - RSTN = IO.PortA6; - SELN = IO.PortB0; - - components HplAtm128Timer1C as TimerC; - HplRF230P.Capture -> TimerC.Capture; - - components new AlarmOne16C() as AlarmC; - Alarm = AlarmC; - - components RealMainP; - RealMainP.PlatformInit -> HplRF230P.PlatformInit; -} diff --git a/tos/platforms/iris/chips/rf230/HplRF230P.nc b/tos/platforms/iris/chips/rf230/HplRF230P.nc deleted file mode 100644 index 652c60a7..00000000 --- a/tos/platforms/iris/chips/rf230/HplRF230P.nc +++ /dev/null @@ -1,126 +0,0 @@ -/* - * 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 - */ - -#include -#include "Atm128Spi.h" - -module HplRF230P -{ - provides - { - interface GpioCapture as IRQ; - interface Init as PlatformInit; - - interface FastSpiByte; - } - - uses - { - interface HplAtm128Capture as Capture; - interface GeneralIO as PortCLKM; - interface GeneralIO as PortIRQ; - } -} - -implementation -{ - command error_t PlatformInit.init() - { - call PortCLKM.makeInput(); - call PortCLKM.clr(); - call PortIRQ.makeInput(); - call PortIRQ.clr(); - call Capture.stop(); - - return SUCCESS; - } - - async event void Capture.captured(uint16_t time) - { - time = call Capture.get(); // TODO: ask Cory why time is not the captured time - signal IRQ.captured(time); - } - - default async event void IRQ.captured(uint16_t time) - { - } - - async command error_t IRQ.captureRisingEdge() - { - call Capture.setEdge(TRUE); - call Capture.reset(); - call Capture.start(); - - return SUCCESS; - } - - async command error_t IRQ.captureFallingEdge() - { - // falling edge comes when the IRQ_STATUS register of the RF230 is read - return FAIL; - } - - async command void IRQ.disable() - { - call Capture.stop(); - } - - inline async command void FastSpiByte.splitWrite(uint8_t data) - { - // the SPI must have been started, so do not waste time here - // SET_BIT(SPCR, SPE); - - SPDR = data; - } - - inline async command uint8_t FastSpiByte.splitRead() - { - while( !( SPSR & 0x80 ) ) - ; - return SPDR; - } - - inline async command uint8_t FastSpiByte.splitReadWrite(uint8_t data) - { - uint8_t b; - - while( !( SPSR & 0x80 ) ) - ; - b = SPDR; - SPDR = data; - - return b; - } - - inline async command uint8_t FastSpiByte.write(uint8_t data) - { - // the SPI must have been started, so do not waste time here - // SET_BIT(SPCR, SPE); - - SPDR = data; - while( !( SPSR & 0x80 ) ) - ; - - return SPDR; - } -} diff --git a/tos/platforms/iris/chips/rf230/HplRF2xx.h b/tos/platforms/iris/chips/rf230/HplRF2xx.h new file mode 100644 index 00000000..6f9e21c8 --- /dev/null +++ b/tos/platforms/iris/chips/rf230/HplRF2xx.h @@ -0,0 +1,79 @@ +/* + * 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 __HPLRF2XX_H__ +#define __HPLRF2XX_H__ + +#include +#include + +enum +{ + /** + * This is an RF230 chip + */ + RF2XX_CHIPSET = RF230_CHIPSET, + + /** + * This is the value of the TRX_CTRL_0 register + * which configures the output pin currents and the CLKM clock + */ + RF2XX_TRX_CTRL_0_VALUE = 0, + + /** + * This is the default value of the CCA_MODE field in the PHY_CC_CCA register + * which is used to configure the default mode of the clear channel assesment + */ + RF2XX_CCA_MODE_VALUE = RF2XX_CCA_MODE_3, + + /** + * This is the value of the CCA_THRES register that controls the + * energy levels used for clear channel assesment + */ + RF2XX_CCA_THRES_VALUE = 0xC7, +}; + +/* This is the default value of the TX_PWR field of the PHY_TX_PWR register. */ +#ifndef RF230_DEF_RFPOWER +#define RF230_DEF_RFPOWER 0 +#endif + +#define RF2XX_DEF_RFPOWER RF230_DEF_RFPOWER + +/* This is the default value of the CHANNEL field of the PHY_CC_CCA register. */ +#ifndef RF230_DEF_CHANNEL +#define RF230_DEF_CHANNEL 11 +#endif + +#define RF2XX_DEF_CHANNEL RF230_DEF_CHANNEL + +/* + * This is the command used to calculate the CRC for the RF230 chip. + * TODO: Check why the default crcByte implementation is in a different endianness + */ +inline uint16_t RF2XX_CRCBYTE_COMMAND(uint16_t crc, uint8_t data) +{ + return _crc_ccitt_update(crc, data); +} + +#endif//__HPLRF2XX_H__ diff --git a/tos/platforms/iris/chips/rf230/HplRF2xxC.nc b/tos/platforms/iris/chips/rf230/HplRF2xxC.nc new file mode 100644 index 00000000..cc3c1cf9 --- /dev/null +++ b/tos/platforms/iris/chips/rf230/HplRF2xxC.nc @@ -0,0 +1,68 @@ +/* + * 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 + */ + +#include + +configuration HplRF2xxC +{ + provides + { + interface GeneralIO as SELN; + interface Resource as SpiResource; + interface FastSpiByte; + + interface GeneralIO as SLP_TR; + interface GeneralIO as RSTN; + + interface GpioCapture as IRQ; + interface Alarm as Alarm; + } +} + +implementation +{ + components HplRF2xxP; + IRQ = HplRF2xxP.IRQ; + + HplRF2xxP.PortCLKM -> IO.PortD6; + HplRF2xxP.PortIRQ -> IO.PortD4; + + components Atm128SpiC as SpiC; + SpiResource = SpiC.Resource[unique("Atm128SpiC.Resource")]; + + FastSpiByte = HplRF2xxP; + + components HplAtm128GeneralIOC as IO; + SLP_TR = IO.PortB7; + RSTN = IO.PortA6; + SELN = IO.PortB0; + + components HplAtm128Timer1C as TimerC; + HplRF2xxP.Capture -> TimerC.Capture; + + components new AlarmOne16C() as AlarmC; + Alarm = AlarmC; + + components RealMainP; + RealMainP.PlatformInit -> HplRF2xxP.PlatformInit; +} diff --git a/tos/platforms/iris/chips/rf230/HplRF2xxP.nc b/tos/platforms/iris/chips/rf230/HplRF2xxP.nc new file mode 100644 index 00000000..a97f81c6 --- /dev/null +++ b/tos/platforms/iris/chips/rf230/HplRF2xxP.nc @@ -0,0 +1,125 @@ +/* + * 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 + */ + +#include "Atm128Spi.h" + +module HplRF2xxP +{ + provides + { + interface GpioCapture as IRQ; + interface Init as PlatformInit; + + interface FastSpiByte; + } + + uses + { + interface HplAtm128Capture as Capture; + interface GeneralIO as PortCLKM; + interface GeneralIO as PortIRQ; + } +} + +implementation +{ + command error_t PlatformInit.init() + { + call PortCLKM.makeInput(); + call PortCLKM.clr(); + call PortIRQ.makeInput(); + call PortIRQ.clr(); + call Capture.stop(); + + return SUCCESS; + } + + async event void Capture.captured(uint16_t time) + { + time = call Capture.get(); // TODO: ask Cory why time is not the captured time + signal IRQ.captured(time); + } + + default async event void IRQ.captured(uint16_t time) + { + } + + async command error_t IRQ.captureRisingEdge() + { + call Capture.setEdge(TRUE); + call Capture.reset(); + call Capture.start(); + + return SUCCESS; + } + + async command error_t IRQ.captureFallingEdge() + { + // falling edge comes when the IRQ_STATUS register of the RF230 is read + return FAIL; + } + + async command void IRQ.disable() + { + call Capture.stop(); + } + + inline async command void FastSpiByte.splitWrite(uint8_t data) + { + // the SPI must have been started, so do not waste time here + // SET_BIT(SPCR, SPE); + + SPDR = data; + } + + inline async command uint8_t FastSpiByte.splitRead() + { + while( !( SPSR & 0x80 ) ) + ; + return SPDR; + } + + inline async command uint8_t FastSpiByte.splitReadWrite(uint8_t data) + { + uint8_t b; + + while( !( SPSR & 0x80 ) ) + ; + b = SPDR; + SPDR = data; + + return b; + } + + inline async command uint8_t FastSpiByte.write(uint8_t data) + { + // the SPI must have been started, so do not waste time here + // SET_BIT(SPCR, SPE); + + SPDR = data; + while( !( SPSR & 0x80 ) ) + ; + + return SPDR; + } +} diff --git a/tos/platforms/iris/chips/rf230/RadioAlarm.h b/tos/platforms/iris/chips/rf230/RadioAlarm.h index 18976592..42b3d53c 100644 --- a/tos/platforms/iris/chips/rf230/RadioAlarm.h +++ b/tos/platforms/iris/chips/rf230/RadioAlarm.h @@ -32,8 +32,8 @@ typedef TOne TRadio; /** - * The number of radio alarm ticks per one microsecond (0.9216). We use integers - * and no parentheses just to make deputy happy. + * The number of radio alarm ticks per one microsecond (0.9216). + * We use integers and no parentheses just to make deputy happy. */ #define RADIO_ALARM_MICROSEC (7372800UL / MHZ / 32) * (1 << MICA_DIVIDE_ONE_FOR_32KHZ_LOG2) / 1000000UL diff --git a/tos/platforms/iris/platform_message.h b/tos/platforms/iris/platform_message.h index 9bc04c4a..cdf078ae 100644 --- a/tos/platforms/iris/platform_message.h +++ b/tos/platforms/iris/platform_message.h @@ -1,32 +1,3 @@ -/* $Id$ - * "Copyright (c) 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) 2002-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. - */ - /* * Copyright (c) 2007, Vanderbilt University * All rights reserved. @@ -49,33 +20,23 @@ * */ -/** - * Defining the platform-independently named packet structures to be the - * chip-specific CC1000 packet structures. - * - * @author Philip Levis - * @date May 16 2005 - * Revision: $Revision$ - */ - - #ifndef PLATFORM_MESSAGE_H #define PLATFORM_MESSAGE_H -#include +#include #include typedef union message_header { - rf230packet_header_t rf230; + rf2xxpacket_header_t rf2xx; serial_header_t serial; } message_header_t; typedef union message_footer { - rf230packet_footer_t rf230; + rf2xxpacket_footer_t rf2xx; } message_footer_t; typedef union message_metadata { - rf230packet_metadata_t rf230; + rf2xxpacket_metadata_t rf2xx; } message_metadata_t; #endif