From: mmaroti Date: Tue, 10 Mar 2009 20:37:58 +0000 (+0000) Subject: moving files from rf230 to rf2xx, prepare the support of rf212 X-Git-Tag: rc_6_tinyos_2_1_1~461 X-Git-Url: https://oss.titaniummirror.com/gitweb/?p=tinyos-2.x.git;a=commitdiff_plain;h=7cb3053eaa216416d4833656f2ffbee14a5c0970 moving files from rf230 to rf2xx, prepare the support of rf212 --- diff --git a/tos/chips/rf230/ActiveMessageConfig.nc b/tos/chips/rf230/ActiveMessageConfig.nc deleted file mode 100644 index e47f0e8b..00000000 --- a/tos/chips/rf230/ActiveMessageConfig.nc +++ /dev/null @@ -1,32 +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 - */ - -interface ActiveMessageConfig -{ - /** - * This command is called when the message first enters the radio stack - * via the Send.send command. This should clear the packet if the user - * forgot to do so (or return EINVAL to be strict). - */ - command error_t checkPacket(message_t* msg); -} diff --git a/tos/chips/rf230/ActiveMessageLayerC.nc b/tos/chips/rf230/ActiveMessageLayerC.nc deleted file mode 100644 index f635a9c6..00000000 --- a/tos/chips/rf230/ActiveMessageLayerC.nc +++ /dev/null @@ -1,107 +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 - */ - -module ActiveMessageLayerC -{ - provides - { - interface AMSend[am_id_t id]; - interface Receive[am_id_t id]; - interface Receive as Snoop[am_id_t id]; - } - uses - { - interface Send as SubSend; - interface Receive as SubReceive; - interface AMPacket; - interface ActiveMessageConfig as Config; - } -} - -implementation -{ -/*----------------- Send -----------------*/ - - command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len) - { - error_t error; - - error = call Config.checkPacket(msg); - if( error != SUCCESS ) - return error; - - call AMPacket.setSource(msg, call AMPacket.address()); - call AMPacket.setGroup(msg, call AMPacket.localGroup()); - call AMPacket.setType(msg, id); - call AMPacket.setDestination(msg, addr); - - return call SubSend.send(msg, len); - } - - inline event void SubSend.sendDone(message_t* msg, error_t error) - { - signal AMSend.sendDone[call AMPacket.type(msg)](msg, error); - } - - inline command error_t AMSend.cancel[am_id_t id](message_t* msg) - { - return call SubSend.cancel(msg); - } - - default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error) - { - } - - inline command uint8_t AMSend.maxPayloadLength[am_id_t id]() - { - return call SubSend.maxPayloadLength(); - } - - inline command void* AMSend.getPayload[am_id_t id](message_t* msg, uint8_t len) - { - return call SubSend.getPayload(msg, len); - } - -/*----------------- Receive -----------------*/ - - event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) - { - am_id_t type = call AMPacket.type(msg); - - msg = call AMPacket.isForMe(msg) - ? signal Receive.receive[type](msg, payload, len) - : signal Snoop.receive[type](msg, payload, len); - - return msg; - } - - default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) - { - return msg; - } - - default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) - { - return msg; - } -} diff --git a/tos/chips/rf230/CsmaConfig.nc b/tos/chips/rf230/CsmaConfig.nc deleted file mode 100644 index 9d453767..00000000 --- a/tos/chips/rf230/CsmaConfig.nc +++ /dev/null @@ -1,31 +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 - */ - -interface CsmaConfig -{ - /** - * This command is called when the message is transmitted to - * check if it needs software clear channel assesment. - */ - async command bool requiresSoftwareCCA(message_t* msg); -} diff --git a/tos/chips/rf230/CsmaLayerC.nc b/tos/chips/rf230/CsmaLayerC.nc deleted file mode 100644 index e0ddc262..00000000 --- a/tos/chips/rf230/CsmaLayerC.nc +++ /dev/null @@ -1,47 +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 CsmaLayerC -{ - provides - { - interface RadioSend; - } - uses - { - interface RadioSend as SubSend; - interface RadioCCA as SubCCA; - - interface CsmaConfig as Config; - } -} - -implementation -{ - components CsmaLayerP; - - RadioSend = CsmaLayerP; - SubSend = CsmaLayerP; - SubCCA = CsmaLayerP; - Config = CsmaLayerP; -} diff --git a/tos/chips/rf230/CsmaLayerP.nc b/tos/chips/rf230/CsmaLayerP.nc deleted file mode 100644 index 5bd1aa41..00000000 --- a/tos/chips/rf230/CsmaLayerP.nc +++ /dev/null @@ -1,103 +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 CsmaLayerP -{ - provides - { - interface RadioSend; - } - - uses - { - interface CsmaConfig as Config; - - interface RadioSend as SubSend; - interface RadioCCA as SubCCA; - } -} - -implementation -{ - tasklet_norace message_t *txMsg; - - tasklet_norace uint8_t state; - enum - { - STATE_READY = 0, - STATE_CCA_WAIT = 1, - STATE_SEND = 2, - }; - - tasklet_async event void SubSend.ready() - { - if( state == STATE_READY ) - signal RadioSend.ready(); - } - - tasklet_async command error_t RadioSend.send(message_t* msg) - { - error_t error; - - if( state == STATE_READY ) - { - if( call Config.requiresSoftwareCCA(msg) ) - { - txMsg = msg; - - if( (error = call SubCCA.request()) == SUCCESS ) - state = STATE_CCA_WAIT; - } - else if( (error = call SubSend.send(msg)) == SUCCESS ) - state = STATE_SEND; - } - else - error = EBUSY; - - return error; - } - - tasklet_async event void SubCCA.done(error_t error) - { - ASSERT( state == STATE_CCA_WAIT ); - - if( error == SUCCESS && (error = call SubSend.send(txMsg)) == SUCCESS ) - state = STATE_SEND; - else - { - state = STATE_READY; - signal RadioSend.sendDone(EBUSY); - } - } - - tasklet_async event void SubSend.sendDone(error_t error) - { - ASSERT( state == STATE_SEND ); - - state = STATE_READY; - signal RadioSend.sendDone(error); - } -} diff --git a/tos/chips/rf230/DummyConfig.nc b/tos/chips/rf230/DummyConfig.nc deleted file mode 100644 index c76631e6..00000000 --- a/tos/chips/rf230/DummyConfig.nc +++ /dev/null @@ -1,30 +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 - */ - -interface DummyConfig -{ - /** - * We need to put something here, but this is not going to get called - */ - async command void nothing(); -} diff --git a/tos/chips/rf230/DummyLayerC.nc b/tos/chips/rf230/DummyLayerC.nc deleted file mode 100644 index e3c55dea..00000000 --- a/tos/chips/rf230/DummyLayerC.nc +++ /dev/null @@ -1,70 +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 - */ - -generic configuration DummyLayerC() -{ - provides - { - interface SplitControl; - interface Send; - interface Receive; - interface LowPowerListening; - - interface RadioState; - interface RadioSend; - interface RadioReceive; - interface RadioCCA; - - interface DummyConfig as UnconnectedConfig; - } - - uses - { - interface RadioState as SubState; - interface RadioSend as SubRadioSend; - interface RadioReceive as SubRadioReceive; - interface RadioCCA as SubRadioCCA; - interface SplitControl as SubControl; - interface Send as SubSend; - interface Receive as SubReceive; - - interface DummyConfig as Config; - } -} - -implementation -{ - RadioState = SubState; - RadioSend = SubRadioSend; - RadioReceive = SubRadioReceive; - RadioCCA = SubRadioCCA; - - SplitControl = SubControl; - Send = SubSend; - Receive = SubReceive; - - Config = UnconnectedConfig; - - components DummyLayerP; - LowPowerListening = DummyLayerP.LowPowerListening; -} diff --git a/tos/chips/rf230/DummyLayerP.nc b/tos/chips/rf230/DummyLayerP.nc deleted file mode 100644 index 8ce32610..00000000 --- a/tos/chips/rf230/DummyLayerP.nc +++ /dev/null @@ -1,50 +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 - */ - -module DummyLayerP -{ - provides interface LowPowerListening; -} - -implementation -{ - command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { } - - command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; } - - command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { } - - command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; } - - command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { } - - command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; } - - command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { } - - command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; } - - command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; } - - command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; } -} diff --git a/tos/chips/rf230/IEEE154NetworkLayerC.nc b/tos/chips/rf230/IEEE154NetworkLayerC.nc deleted file mode 100644 index 2cfd690e..00000000 --- a/tos/chips/rf230/IEEE154NetworkLayerC.nc +++ /dev/null @@ -1,53 +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 IEEE154NetworkLayerC -{ - provides - { - interface SplitControl; - interface Send; - interface Receive; - } - uses - { - interface SplitControl as SubControl; - interface Send as SubSend; - interface Receive as SubReceive; - } -} - -implementation -{ - components IEEE154NetworkLayerP, IEEE154PacketC; - - SplitControl = SubControl; - - Send = IEEE154NetworkLayerP; - Receive = IEEE154NetworkLayerP; - - SubSend = IEEE154NetworkLayerP; - SubReceive = IEEE154NetworkLayerP; - - IEEE154NetworkLayerP.IEEE154Packet -> IEEE154PacketC; -} diff --git a/tos/chips/rf230/IEEE154NetworkLayerP.nc b/tos/chips/rf230/IEEE154NetworkLayerP.nc deleted file mode 100644 index f4abf636..00000000 --- a/tos/chips/rf230/IEEE154NetworkLayerP.nc +++ /dev/null @@ -1,87 +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 - */ - -module IEEE154NetworkLayerP -{ - provides - { - interface Send; - interface Receive; - interface Receive as NonTinyosReceive[uint8_t network]; - } - - uses - { - interface Send as SubSend; - interface Receive as SubReceive; - - interface IEEE154Packet; - } -} - -implementation -{ -#ifndef TINYOS_6LOWPAN_NETWORK_ID -#define TINYOS_6LOWPAN_NETWORK_ID 0x3f -#endif - - command error_t Send.send(message_t* msg, uint8_t len) - { - call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID); - return call SubSend.send(msg, len); - } - - command error_t Send.cancel(message_t* msg) - { - return call SubSend.cancel(msg); - } - - command uint8_t Send.maxPayloadLength() - { - return call SubSend.maxPayloadLength(); - } - - command void* Send.getPayload(message_t* msg, uint8_t len) - { - return call SubSend.getPayload(msg, len); - } - - event void SubSend.sendDone(message_t* msg, error_t error) - { - signal Send.sendDone(msg, error); - } - - event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len) - { - uint8_t network = call IEEE154Packet.get6LowPan(msg); - if( network == TINYOS_6LOWPAN_NETWORK_ID ) - return signal Receive.receive(msg, payload, len); - else - return signal NonTinyosReceive.receive[network](msg, payload, len); - } - - default event message_t *NonTinyosReceive.receive[uint8_t network](message_t *msg, void *payload, uint8_t len) - { - return msg; - } -} diff --git a/tos/chips/rf230/IEEE154Packet.h b/tos/chips/rf230/IEEE154Packet.h deleted file mode 100644 index 62fe16b0..00000000 --- a/tos/chips/rf230/IEEE154Packet.h +++ /dev/null @@ -1,75 +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 __IEEE154PACKET_H__ -#define __IEEE154PACKET_H__ - -typedef nx_struct ieee154_header_t -{ - nxle_uint8_t length; - nxle_uint16_t fcf; - nxle_uint8_t dsn; - nxle_uint16_t destpan; - nxle_uint16_t dest; - nxle_uint16_t src; - -// I-Frame 6LowPAN interoperability byte -#ifndef TFRAMES_ENABLED - nxle_uint8_t network; -#endif - - nxle_uint8_t type; -} ieee154_header_t; - -// the actual radio driver might not use this -typedef nx_struct ieee154_footer_t -{ - nxle_uint16_t crc; -} ieee154_footer_t; - -enum ieee154_fcf_enums { - IEEE154_FCF_FRAME_TYPE = 0, - IEEE154_FCF_SECURITY_ENABLED = 3, - IEEE154_FCF_FRAME_PENDING = 4, - IEEE154_FCF_ACK_REQ = 5, - IEEE154_FCF_INTRAPAN = 6, - IEEE154_FCF_DEST_ADDR_MODE = 10, - IEEE154_FCF_SRC_ADDR_MODE = 14, -}; - -enum ieee154_fcf_type_enums { - IEEE154_TYPE_BEACON = 0, - IEEE154_TYPE_DATA = 1, - IEEE154_TYPE_ACK = 2, - IEEE154_TYPE_MAC_CMD = 3, - IEEE154_TYPE_MASK = 7, -}; - -enum iee154_fcf_addr_mode_enums { - IEEE154_ADDR_NONE = 0, - IEEE154_ADDR_SHORT = 2, - IEEE154_ADDR_EXT = 3, - IEEE154_ADDR_MASK = 3, -}; - -#endif//__IEEE154PACKET_H__ diff --git a/tos/chips/rf230/IEEE154Packet.nc b/tos/chips/rf230/IEEE154Packet.nc deleted file mode 100644 index fd171743..00000000 --- a/tos/chips/rf230/IEEE154Packet.nc +++ /dev/null @@ -1,197 +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 - -/** - * This interface encapsulates IEEE 802.15.4 intrapan data frames with - * 16-bit destination pan, source and destination addresses. It also - * supports 6LowPan interoperability mode, and acknowledgement frames. - * Note, that this interface does not support the CRC-16 value, which - * should be verified before the data can be trusted. - */ -interface IEEE154Packet -{ - /** - * Returns the IEEE 802.15.4 header including the length field. - */ - async command ieee154_header_t* getHeader(message_t* msg); - - /** - * Returns the raw value (unadjusted) of the length field - */ - async command uint8_t getLength(message_t* msg); - - /** - * Sets the length field - */ - async command void setLength(message_t* msg, uint8_t length); - - /** - * Returns the frame control field. This method should not be used, - * isDataFrame and isAckFrame should be used instead. - */ - async command uint16_t getFCF(message_t* msg); - - /** - * Sets the frame control field. This method should not be used, - * createDataFrame and createAckFrame should be used instead. - */ - async command void setFCF(message_t* msg, uint16_t fcf); - - /** - * Returns TRUE if the message is a data frame supported by - * this interface (based on the value of the FCF). - */ - async command bool isDataFrame(message_t* msg); - - /** - * Sets the FCF to create a data frame supported by this interface. - * You may call setAckRequired and setFramePending commands after this. - */ - async command void createDataFrame(message_t* msg); - - /** - * Returns TRUE if the message is an acknowledgement frame supported - * by this interface (based on the value of the FCF). - */ - async command bool isAckFrame(message_t* msg); - - /** - * Sets the FCF to create an acknowledgement frame supported by - * this interface. You may call setFramePending after this. - */ - async command void createAckFrame(message_t* msg); - - /** - * Creates an acknowledgement packet for the given data packet. - * This also sets the DSN value. The data message must be a - * data frame, the ack message will be overwritten. - */ - async command void createAckReply(message_t* data, message_t* ack); - - /** - * Returns TRUE if the acknowledgement packet corresponds to the - * data packet. The data message must be a data packet. - */ - async command bool verifyAckReply(message_t* data, message_t* ack); - - /** - * Returns TRUE if the ACK required field is set in the FCF. - */ - async command bool getAckRequired(message_t* msg); - - /** - * Sets the ACK required field in the FCF, should never be set - * for acknowledgement frames. - */ - async command void setAckRequired(message_t* msg, bool ack); - - /** - * Returns TRUE if the frame pending field is set in the FCF. - */ - async command bool getFramePending(message_t* msg); - - /** - * Sets the frame pending field in the FCF. - */ - async command void setFramePending(message_t* msg, bool pending); - - /** - * Returns the data sequence number - */ - async command uint8_t getDSN(message_t* msg); - - /** - * Sets the data sequence number - */ - async command void setDSN(message_t* msg, uint8_t dsn); - - /** - * returns the destination PAN id, values <= 255 are tinyos groups, - * valid only for data frames - */ - async command uint16_t getDestPan(message_t* msg); - - /** - * Sets the destination PAN id, valid only for data frames - */ - async command void setDestPan(message_t* msg, uint16_t pan); - - /** - * Returns the destination address, valid only for data frames - */ - async command uint16_t getDestAddr(message_t* msg); - - /** - * Sets the destination address, valid only for data frames - */ - async command void setDestAddr(message_t* msg, uint16_t addr); - - /** - * Returns the source address, valid only for data frames - */ - async command uint16_t getSrcAddr(message_t* msg); - - /** - * Sets the source address, valid only for data frames - */ - async command void setSrcAddr(message_t* msg, uint16_t addr); - -#ifndef TFRAMES_ENABLED - - /** - * Returns the value of the 6LowPan network field. - */ - async command uint8_t get6LowPan(message_t* msg); - - /** - * Sets the value of the 6LowPan network field. - */ - async command void set6LowPan(message_t* msg, uint8_t network); - -#endif - - /** - * Returns the active message type of the message - */ - async command am_id_t getType(message_t* msg); - - /** - * Sets the active message type - */ - async command void setType(message_t* msg, am_id_t type); - - /** - * Returns TRUE if the packet is a data packet, the ACK_REQ field - * is set and the destination address is not the broadcast address. - */ - async command bool requiresAckWait(message_t* msg); - - /** - * Returns TRUE if the packet is a data packet, the ACK_REQ field - * is set and the destionation address is this node. - */ - async command bool requiresAckReply(message_t* msg); -} diff --git a/tos/chips/rf230/IEEE154PacketC.nc b/tos/chips/rf230/IEEE154PacketC.nc deleted file mode 100644 index 2ea8ffeb..00000000 --- a/tos/chips/rf230/IEEE154PacketC.nc +++ /dev/null @@ -1,40 +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 IEEE154PacketC -{ - provides - { - interface IEEE154Packet; - interface AMPacket; - } -} - -implementation -{ - components IEEE154PacketP, ActiveMessageAddressC; - IEEE154PacketP.ActiveMessageAddress -> ActiveMessageAddressC; - - IEEE154Packet = IEEE154PacketP; - AMPacket = IEEE154PacketP; -} diff --git a/tos/chips/rf230/IEEE154PacketP.nc b/tos/chips/rf230/IEEE154PacketP.nc deleted file mode 100644 index cb898244..00000000 --- a/tos/chips/rf230/IEEE154PacketP.nc +++ /dev/null @@ -1,294 +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 - -module IEEE154PacketP -{ - provides - { - interface IEEE154Packet; - interface AMPacket; - } - - uses interface ActiveMessageAddress; -} - -implementation -{ -/*----------------- IEEE154Packet -----------------*/ - - enum - { - IEEE154_DATA_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE) - | (1 << IEEE154_FCF_INTRAPAN) - | (IEEE154_ADDR_MASK << IEEE154_FCF_DEST_ADDR_MODE) - | (IEEE154_ADDR_MASK << IEEE154_FCF_SRC_ADDR_MODE), - - IEEE154_DATA_FRAME_VALUE = (IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE) - | (1 << IEEE154_FCF_INTRAPAN) - | (IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE) - | (IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE), - - IEEE154_ACK_FRAME_LENGTH = 5, // includes the FCF, DSN and FCS - IEEE154_ACK_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE), - IEEE154_ACK_FRAME_VALUE = (IEEE154_TYPE_ACK << IEEE154_FCF_FRAME_TYPE), - }; - - inline ieee154_header_t* getHeader(message_t* msg) - { - return (ieee154_header_t*)(msg->data - sizeof(ieee154_header_t)); - } - - inline async command ieee154_header_t* IEEE154Packet.getHeader(message_t* msg) - { - return getHeader(msg); - } - - inline async command uint8_t IEEE154Packet.getLength(message_t* msg) - { - return getHeader(msg)->length; - } - - inline async command void IEEE154Packet.setLength(message_t* msg, uint8_t length) - { - getHeader(msg)->length = length; - } - - inline async command uint16_t IEEE154Packet.getFCF(message_t* msg) - { - return getHeader(msg)->fcf; - } - - inline async command void IEEE154Packet.setFCF(message_t* msg, uint16_t fcf) - { - getHeader(msg)->fcf = fcf; - } - - inline async command bool IEEE154Packet.isDataFrame(message_t* msg) - { - return (getHeader(msg)->fcf & IEEE154_DATA_FRAME_MASK) == IEEE154_DATA_FRAME_VALUE; - } - - inline async command void IEEE154Packet.createDataFrame(message_t* msg) - { - getHeader(msg)->fcf = IEEE154_DATA_FRAME_VALUE; - } - - inline async command bool IEEE154Packet.isAckFrame(message_t* msg) - { - return (getHeader(msg)->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE; - } - - inline async command void IEEE154Packet.createAckFrame(message_t* msg) - { - ieee154_header_t* header = getHeader(msg); - - header->length = IEEE154_ACK_FRAME_LENGTH; - header->fcf = IEEE154_ACK_FRAME_VALUE; - } - - inline async command void IEEE154Packet.createAckReply(message_t* data, message_t* ack) - { - ieee154_header_t* header = getHeader(ack); - - header->length = IEEE154_ACK_FRAME_LENGTH; - header->fcf = IEEE154_ACK_FRAME_VALUE; - header->dsn = getHeader(data)->dsn; - } - - inline async command bool IEEE154Packet.verifyAckReply(message_t* data, message_t* ack) - { - ieee154_header_t* header = getHeader(ack); - - return header->dsn == getHeader(data)->dsn - && (header->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE; - } - - inline async command bool IEEE154Packet.getAckRequired(message_t* msg) - { - return getHeader(msg)->fcf & (1 << IEEE154_FCF_ACK_REQ); - } - - inline async command void IEEE154Packet.setAckRequired(message_t* msg, bool ack) - { - if( ack ) - getHeader(msg)->fcf |= (1 << IEEE154_FCF_ACK_REQ); - else - getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_ACK_REQ); - } - - inline async command bool IEEE154Packet.getFramePending(message_t* msg) - { - return getHeader(msg)->fcf & (1 << IEEE154_FCF_FRAME_PENDING); - } - - inline async command void IEEE154Packet.setFramePending(message_t* msg, bool pending) - { - if( pending ) - getHeader(msg)->fcf |= (1 << IEEE154_FCF_FRAME_PENDING); - else - getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_FRAME_PENDING); - } - - inline async command uint8_t IEEE154Packet.getDSN(message_t* msg) - { - return getHeader(msg)->dsn; - } - - inline async command void IEEE154Packet.setDSN(message_t* msg, uint8_t dsn) - { - getHeader(msg)->dsn = dsn; - } - - inline async command uint16_t IEEE154Packet.getDestPan(message_t* msg) - { - return getHeader(msg)->destpan; - } - - inline async command void IEEE154Packet.setDestPan(message_t* msg, uint16_t pan) - { - getHeader(msg)->destpan = pan; - } - - inline async command uint16_t IEEE154Packet.getDestAddr(message_t* msg) - { - return getHeader(msg)->dest; - } - - inline async command void IEEE154Packet.setDestAddr(message_t* msg, uint16_t addr) - { - getHeader(msg)->dest = addr; - } - - inline async command uint16_t IEEE154Packet.getSrcAddr(message_t* msg) - { - return getHeader(msg)->src; - } - - inline async command void IEEE154Packet.setSrcAddr(message_t* msg, uint16_t addr) - { - getHeader(msg)->src = addr; - } - -#ifndef TFRAMES_ENABLED - - inline async command uint8_t IEEE154Packet.get6LowPan(message_t* msg) - { - return getHeader(msg)->network; - } - - inline async command void IEEE154Packet.set6LowPan(message_t* msg, uint8_t network) - { - getHeader(msg)->network = network; - } - -#endif - - inline async command am_id_t IEEE154Packet.getType(message_t* msg) - { - return getHeader(msg)->type; - } - - inline async command void IEEE154Packet.setType(message_t* msg, am_id_t type) - { - getHeader(msg)->type = type; - } - - async command bool IEEE154Packet.requiresAckWait(message_t* msg) - { - return call IEEE154Packet.getAckRequired(msg) - && call IEEE154Packet.isDataFrame(msg) - && call IEEE154Packet.getDestAddr(msg) != 0xFFFF; - } - - async command bool IEEE154Packet.requiresAckReply(message_t* msg) - { - return call IEEE154Packet.getAckRequired(msg) - && call IEEE154Packet.isDataFrame(msg) - && call IEEE154Packet.getDestAddr(msg) == call ActiveMessageAddress.amAddress(); - } - - inline async event void ActiveMessageAddress.changed() - { - } - -/*----------------- AMPacket -----------------*/ - - inline command am_addr_t AMPacket.address() - { - return call ActiveMessageAddress.amAddress(); - } - - inline command am_group_t AMPacket.localGroup() - { - // TODO: check if this is correct - return call ActiveMessageAddress.amGroup(); - } - - inline command am_addr_t AMPacket.destination(message_t* msg) - { - return call IEEE154Packet.getDestAddr(msg); - } - - inline command am_addr_t AMPacket.source(message_t* msg) - { - return call IEEE154Packet.getSrcAddr(msg); - } - - inline command void AMPacket.setDestination(message_t* msg, am_addr_t addr) - { - call IEEE154Packet.setDestAddr(msg, addr); - } - - inline command void AMPacket.setSource(message_t* msg, am_addr_t addr) - { - call IEEE154Packet.setSrcAddr(msg, addr); - } - - inline command bool AMPacket.isForMe(message_t* msg) - { - am_addr_t addr = call AMPacket.destination(msg); - return addr == call AMPacket.address() || addr == AM_BROADCAST_ADDR; - } - - inline command am_id_t AMPacket.type(message_t* msg) - { - return call IEEE154Packet.getType(msg); - } - - inline command void AMPacket.setType(message_t* msg, am_id_t type) - { - call IEEE154Packet.setType(msg, type); - } - - inline command am_group_t AMPacket.group(message_t* msg) - { - return call IEEE154Packet.getDestPan(msg); - } - - inline command void AMPacket.setGroup(message_t* msg, am_group_t grp) - { - call IEEE154Packet.setDestPan(msg, grp); - } -} diff --git a/tos/chips/rf230/LowPowerListeningLayerC.nc b/tos/chips/rf230/LowPowerListeningLayerC.nc deleted file mode 100644 index b1efca25..00000000 --- a/tos/chips/rf230/LowPowerListeningLayerC.nc +++ /dev/null @@ -1,65 +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 - */ - -#warning "*** USING LOW POWER LISTENING LAYER" - -configuration LowPowerListeningLayerC -{ - provides - { - interface SplitControl; - interface Send; - interface Receive; - - interface LowPowerListening; - } - uses - { - interface SplitControl as SubControl; - interface Send as SubSend; - interface Receive as SubReceive; - - interface PacketField as PacketSleepInterval; - interface IEEE154Packet; - interface PacketAcknowledgements; - } -} - -implementation -{ - components LowPowerListeningLayerP, new TimerMilliC(); - - SplitControl = LowPowerListeningLayerP; - Send = LowPowerListeningLayerP; - Receive = LowPowerListeningLayerP; - LowPowerListening = LowPowerListeningLayerP; - - SubControl = LowPowerListeningLayerP; - SubSend = LowPowerListeningLayerP; - SubReceive = LowPowerListeningLayerP; - PacketSleepInterval = LowPowerListeningLayerP; - IEEE154Packet = LowPowerListeningLayerP; - PacketAcknowledgements = LowPowerListeningLayerP; - - LowPowerListeningLayerP.Timer -> TimerMilliC; -} diff --git a/tos/chips/rf230/LowPowerListeningLayerP.nc b/tos/chips/rf230/LowPowerListeningLayerP.nc deleted file mode 100644 index ef4bac56..00000000 --- a/tos/chips/rf230/LowPowerListeningLayerP.nc +++ /dev/null @@ -1,443 +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 - -module LowPowerListeningLayerP -{ - provides - { - interface SplitControl; - interface Send; - interface Receive; - - interface LowPowerListening; - } - - uses - { - interface SplitControl as SubControl; - interface Send as SubSend; - interface Receive as SubReceive; - - interface PacketField as PacketSleepInterval; - interface IEEE154Packet; - interface PacketAcknowledgements; - interface Timer; - } -} - -implementation -{ - enum - { - // minimum wakeup time to catch a transmission in milliseconds - LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535 - - // extra wakeup time after receiving a message in milliseconds - AFTER_RECEIVE = 10U, - - // extra wakeup time after transmitting a message in milliseconds - AFTER_TRANSMIT = 10U, - - MIN_SLEEP = 2, // the minimum sleep interval in milliseconds - MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds - MIN_DUTY = 2, // the minimum duty cycle - }; - - uint16_t sleepInterval; - - message_t* txMsg; - uint8_t txLen; - error_t txError; - -/*----------------- state machine -----------------*/ - - enum - { - OFF = 0, - OFF_SUBSTOP = 1, // must have consecutive indices - OFF_SUBSTOP_DONE = 2, // must have consecutive indices - OFF_STOP_END = 3, // must have consecutive indices - OFF_START_END = 4, - - LISTEN_SUBSTART = 5, // must have consecutive indices - LISTEN_SUBSTART_DONE = 6, // must have consecutive indices - LISTEN_TIMER = 7, // must have consecutive indices - LISTEN = 8, // must have consecutive indices - - SLEEP_SUBSTOP = 9, // must have consecutive indices - SLEEP_SUBSTOP_DONE = 10, // must have consecutive indices - SLEEP_TIMER = 11, // must have consecutive indices - SLEEP = 12, // must have consecutive indices - - SEND_SUBSTART = 13, // must have consecutive indices - SEND_SUBSTART_DONE = 14, // must have consecutive indices - SEND_TIMER = 15, // must have consecutive indices - SEND_SUBSEND= 16, - SEND_SUBSEND_DONE = 17, - SEND_SUBSEND_DONE_LAST = 18, - SEND_DONE = 19, - }; - - uint8_t state; - - task void transition() - { - error_t error; - uint16_t transmitInterval; - - if( state == LISTEN_SUBSTART || state == SEND_SUBSTART ) - { - error = call SubControl.start(); - ASSERT( error == SUCCESS || error == EBUSY ); - - if( error == SUCCESS ) - ++state; - else - post transition(); - } - else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP ) - { - error = call SubControl.stop(); - ASSERT( error == SUCCESS || error == EBUSY ); - - if( error == SUCCESS ) - ++state; - else - post transition(); - } - else if( state == OFF_START_END ) - { - state = LISTEN_SUBSTART; - post transition(); - - signal SplitControl.startDone(SUCCESS); - } - else if( state == OFF_STOP_END ) - { - state = OFF; - signal SplitControl.stopDone(SUCCESS); - } - else if( state == LISTEN_TIMER ) - { - state = LISTEN; - if( sleepInterval > 0 ) - call Timer.startOneShot(LISTEN_WAKEUP); - } - else if( state == SLEEP_TIMER ) - { - if( sleepInterval > 0 ) - { - state = SLEEP; - call Timer.startOneShot(sleepInterval); - } - else - { - state = LISTEN_SUBSTART; - post transition(); - } - } - else if( state == SEND_TIMER ) - { - transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg); - - if( transmitInterval > 0 ) - call Timer.startOneShot(transmitInterval); - - state = SEND_SUBSEND; - post transition(); - } - else if( state == SEND_SUBSEND) - { - txError = call SubSend.send(txMsg, txLen); - - if( txError == SUCCESS ) - state = SEND_SUBSEND_DONE; - else - { - state = SEND_DONE; - post transition(); - } - } - else if( state == SEND_DONE ) - { - state = LISTEN; - if( sleepInterval > 0 ) - call Timer.startOneShot(AFTER_TRANSMIT); - - signal Send.sendDone(txMsg, txError); - } - } - - command error_t SplitControl.start() - { - if( state == OFF_START_END ) - return EBUSY; - else if( state != OFF ) - return EALREADY; - - state = OFF_START_END; - post transition(); - - return SUCCESS; - } - - event void SubControl.startDone(error_t error) - { - ASSERT( error == SUCCESS || error == EBUSY ); - ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE ); - - if( error == SUCCESS ) - ++state; - else - --state; - - post transition(); - } - - command error_t SplitControl.stop() - { - if( state == SLEEP || state == LISTEN ) - { - call Timer.stop(); - post transition(); - } - - if( state == LISTEN_TIMER || state == LISTEN || state == SLEEP_SUBSTOP ) - state = OFF_SUBSTOP; - else if( state == SLEEP_SUBSTOP_DONE ) - state = OFF_SUBSTOP_DONE; - else if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP ) - state = OFF_STOP_END; - else if( state == OFF ) - return EALREADY; - else - return EBUSY; - - return SUCCESS; - } - - event void SubControl.stopDone(error_t error) - { - ASSERT( error == SUCCESS || error == EBUSY ); - ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE ); - - if( error == SUCCESS ) - ++state; - else - --state; - - post transition(); - } - - event void Timer.fired() - { - ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND || state == SEND_SUBSEND_DONE ); - - if( state == LISTEN ) - state = SLEEP_SUBSTOP; - else if( state == SLEEP ) - state = LISTEN_SUBSTART; - else if( state == SEND_SUBSEND_DONE ) - state = SEND_SUBSEND_DONE_LAST; - else if( state == SEND_SUBSEND) - state = SEND_DONE; - - post transition(); - } - - event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) - { - if( state == SLEEP_SUBSTOP ) - state = LISTEN; - - if( state == LISTEN && sleepInterval > 0 ) - call Timer.startOneShot(AFTER_RECEIVE); - - return signal Receive.receive(msg, payload, len); - } - - command error_t Send.send(message_t* msg, uint8_t len) - { - if( state == LISTEN || state == SLEEP ) - { - call Timer.stop(); - post transition(); - } - - if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP ) - state = SEND_SUBSTART; - else if( state == LISTEN_SUBSTART_DONE ) - state = SEND_SUBSTART_DONE; - else if( state == LISTEN_TIMER || state == SLEEP_SUBSTOP || state == LISTEN ) - state = SEND_TIMER; - else - return EBUSY; - - txMsg = msg; - txLen = len; - txError = FAIL; - - return SUCCESS; - } - - command error_t Send.cancel(message_t* msg) - { - if( state == SEND_SUBSEND ) - { - call Timer.stop(); - state = SEND_DONE; - txError = ECANCEL; - post transition(); - - return SUCCESS; - } - else if( state == SEND_SUBSEND_DONE ) - { - // we stop sending the message even if SubSend.cancel was not succesfull - state = SEND_SUBSEND_DONE_LAST; - - return call SubSend.cancel(txMsg); - } - else - return FAIL; - } - - event void SubSend.sendDone(message_t* msg, error_t error) - { - ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST ); - ASSERT( msg == txMsg ); - - txError = error; - - // TODO: extend the PacketAcknowledgements interface with getAckRequired - if( error != SUCCESS - || call LowPowerListening.getRxSleepInterval(msg) == 0 - || state == SEND_SUBSEND_DONE_LAST - || (call IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) ) - { - call Timer.stop(); - state = SEND_DONE; - } - else - state = SEND_SUBSEND; - - post transition(); - } - - command uint8_t Send.maxPayloadLength() - { - return call SubSend.maxPayloadLength(); - } - - command void* Send.getPayload(message_t* msg, uint8_t len) - { - return call SubSend.getPayload(msg, len); - } - -/*----------------- LowPowerListening -----------------*/ - - command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) - { - if( dutyCycle >= 10000 ) - return 0; - else if( dutyCycle <= MIN_DUTY ) - return MAX_SLEEP; - - return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP; - } - - command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval) - { - if( interval < MIN_SLEEP ) - return 10000; - else if( interval >= MAX_SLEEP ) - return MIN_DUTY; - - return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval); - } - - command void LowPowerListening.setLocalSleepInterval(uint16_t interval) - { - if( interval < MIN_SLEEP ) - interval = 0; - else if( interval > MAX_SLEEP ) - interval = MAX_SLEEP; - - sleepInterval = interval; - - if( (state == LISTEN && sleepInterval == 0) || state == SLEEP ) - { - call Timer.stop(); - --state; - post transition(); - } - } - - command uint16_t LowPowerListening.getLocalSleepInterval() - { - return sleepInterval; - } - - command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) - { - call LowPowerListening.setLocalSleepInterval( - call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); - } - - command uint16_t LowPowerListening.getLocalDutyCycle() - { - return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval); - } - - command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval) - { - if( interval < MIN_SLEEP ) - interval = 0; - else if( interval > MAX_SLEEP ) - interval = MAX_SLEEP; - - call PacketSleepInterval.set(msg, interval); - } - - command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) - { - if( ! call PacketSleepInterval.isSet(msg) ) - return sleepInterval; - - return call PacketSleepInterval.get(msg); - } - - command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) - { - call LowPowerListening.setRxSleepInterval(msg, - call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); - } - - command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) - { - return call LowPowerListening.sleepIntervalToDutyCycle( - call LowPowerListening.getRxSleepInterval(msg)); - } -} diff --git a/tos/chips/rf230/MessageBufferLayerC.nc b/tos/chips/rf230/MessageBufferLayerC.nc deleted file mode 100644 index 90402c35..00000000 --- a/tos/chips/rf230/MessageBufferLayerC.nc +++ /dev/null @@ -1,60 +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 MessageBufferLayerC -{ - provides - { - interface SplitControl; - interface Send; - interface Receive; - interface RadioChannel; - } - uses - { - interface RadioState; - interface RadioSend; - interface RadioReceive; - - interface Packet; - } -} - -implementation -{ - components MessageBufferLayerP, MainC, TaskletC; - - MainC.SoftwareInit -> MessageBufferLayerP; - - SplitControl = MessageBufferLayerP; - Send = MessageBufferLayerP; - Receive = MessageBufferLayerP; - RadioChannel = MessageBufferLayerP; - - RadioState = MessageBufferLayerP; - MessageBufferLayerP.Tasklet -> TaskletC; - RadioSend = MessageBufferLayerP; - RadioReceive = MessageBufferLayerP; - - Packet = MessageBufferLayerP; -} diff --git a/tos/chips/rf230/MessageBufferLayerP.nc b/tos/chips/rf230/MessageBufferLayerP.nc deleted file mode 100644 index 374edaad..00000000 --- a/tos/chips/rf230/MessageBufferLayerP.nc +++ /dev/null @@ -1,360 +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 MessageBufferLayerP -{ - provides - { - interface SplitControl; - interface Init as SoftwareInit; - - interface Send; - interface Receive; - interface RadioChannel; - } - uses - { - interface RadioState; - interface Tasklet; - interface RadioSend; - interface RadioReceive; - - interface Packet; - } -} - -implementation -{ -/*----------------- State -----------------*/ - - norace uint8_t state; // written only from tasks - enum - { - STATE_READY = 0, - STATE_TX_PENDING = 1, - STATE_TX_SEND = 2, - STATE_TX_DONE = 3, - STATE_TURN_ON = 4, - STATE_TURN_OFF = 5, - STATE_CHANNEL = 6, - }; - - command error_t SplitControl.start() - { - error_t error; - - call Tasklet.suspend(); - - if( state != STATE_READY ) - error = EBUSY; - else - error = call RadioState.turnOn(); - - if( error == SUCCESS ) - state = STATE_TURN_ON; - - call Tasklet.resume(); - - return error; - } - - command error_t SplitControl.stop() - { - error_t error; - - call Tasklet.suspend(); - - if( state != STATE_READY ) - error = EBUSY; - else - error = call RadioState.turnOff(); - - if( error == SUCCESS ) - state = STATE_TURN_OFF; - - call Tasklet.resume(); - - return error; - } - - command error_t RadioChannel.setChannel(uint8_t channel) - { - error_t error; - - call Tasklet.suspend(); - - if( state != STATE_READY ) - error = EBUSY; - else - error = call RadioState.setChannel(channel); - - if( error == SUCCESS ) - state = STATE_CHANNEL; - - call Tasklet.resume(); - - return error; - } - - command uint8_t RadioChannel.getChannel() - { - return call RadioState.getChannel(); - } - - task void stateDoneTask() - { - uint8_t s; - - s = state; - - // change the state before so we can be reentered from the event - state = STATE_READY; - - if( s == STATE_TURN_ON ) - signal SplitControl.startDone(SUCCESS); - else if( s == STATE_TURN_OFF ) - signal SplitControl.stopDone(SUCCESS); - else if( s == STATE_CHANNEL ) - signal RadioChannel.setChannelDone(); - else // not our event, ignore it - state = s; - } - - tasklet_async event void RadioState.done() - { - post stateDoneTask(); - } - - default event void SplitControl.startDone(error_t error) - { - } - - default event void SplitControl.stopDone(error_t error) - { - } - - default event void RadioChannel.setChannelDone() - { - } - -/*----------------- Send -----------------*/ - - message_t* txMsg; - error_t txError; - uint8_t retries; - - // Many EBUSY replies from RadioSend are normal if the channel is cognested - enum { MAX_RETRIES = 5 }; - - task void sendTask() - { - error_t error; - - ASSERT( state == STATE_TX_PENDING || state == STATE_TX_SEND ); - - atomic error = txError; - if( (state == STATE_TX_SEND && error == SUCCESS) || ++retries > MAX_RETRIES ) - state = STATE_TX_DONE; - else - { - call Tasklet.suspend(); - - error = call RadioSend.send(txMsg); - if( error == SUCCESS ) - state = STATE_TX_SEND; - else if( retries == MAX_RETRIES ) - state = STATE_TX_DONE; - else - state = STATE_TX_PENDING; - - call Tasklet.resume(); - } - - if( state == STATE_TX_DONE ) - { - state = STATE_READY; - signal Send.sendDone(txMsg, error); - } - } - - tasklet_async event void RadioSend.sendDone(error_t error) - { - ASSERT( state == STATE_TX_SEND ); - - atomic txError = error; - post sendTask(); - } - - command error_t Send.send(message_t* msg, uint8_t len) - { - if( len > call Packet.maxPayloadLength() ) - return EINVAL; - else if( state != STATE_READY ) - return EBUSY; - - call Packet.setPayloadLength(msg, len); - - txMsg = msg; - state = STATE_TX_PENDING; - retries = 0; - post sendTask(); - - return SUCCESS; - } - - tasklet_async event void RadioSend.ready() - { - if( state == STATE_TX_PENDING ) - post sendTask(); - } - - tasklet_async event void Tasklet.run() - { - } - - command error_t Send.cancel(message_t* msg) - { - if( state == STATE_TX_PENDING ) - { - state = STATE_READY; - - // TODO: check if sendDone can be called before cancel returns - signal Send.sendDone(msg, ECANCEL); - - return SUCCESS; - } - else - return FAIL; - } - - default event void Send.sendDone(message_t* msg, error_t error) - { - } - - inline command uint8_t Send.maxPayloadLength() - { - return call Packet.maxPayloadLength(); - } - - inline command void* Send.getPayload(message_t* msg, uint8_t len) - { - return call Packet.getPayload(msg, len); - } - -/*----------------- Receive -----------------*/ - - enum - { - RECEIVE_QUEUE_SIZE = 3, - }; - - message_t receiveQueueData[RECEIVE_QUEUE_SIZE]; - message_t* receiveQueue[RECEIVE_QUEUE_SIZE]; - - uint8_t receiveQueueHead; - uint8_t receiveQueueSize; - - command error_t SoftwareInit.init() - { - uint8_t i; - - for(i = 0; i < RECEIVE_QUEUE_SIZE; ++i) - receiveQueue[i] = receiveQueueData + i; - - return SUCCESS; - } - - tasklet_async event bool RadioReceive.header(message_t* msg) - { - bool notFull; - - // this prevents undeliverable messages to be acknowledged - atomic notFull = receiveQueueSize < RECEIVE_QUEUE_SIZE; - - return notFull; - } - - task void deliverTask() - { - // get rid of as many messages as possible without interveining tasks - for(;;) - { - message_t* msg; - - atomic - { - if( receiveQueueSize == 0 ) - return; - - msg = receiveQueue[receiveQueueHead]; - } - - msg = signal Receive.receive(msg, - call Packet.getPayload(msg, call Packet.maxPayloadLength()), - call Packet.payloadLength(msg)); - - atomic - { - receiveQueue[receiveQueueHead] = msg; - - if( ++receiveQueueHead >= RECEIVE_QUEUE_SIZE ) - receiveQueueHead = 0; - - --receiveQueueSize; - } - } - } - - tasklet_async event message_t* RadioReceive.receive(message_t* msg) - { - message_t *m; - - atomic - { - if( receiveQueueSize >= RECEIVE_QUEUE_SIZE ) - m = msg; - else - { - uint8_t index = receiveQueueHead + receiveQueueSize; - if( index >= RECEIVE_QUEUE_SIZE ) - index -= RECEIVE_QUEUE_SIZE; - - m = receiveQueue[index]; - receiveQueue[index] = msg; - - ++receiveQueueSize; - post deliverTask(); - } - } - - return m; - } - - default event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) - { - return msg; - } -} diff --git a/tos/chips/rf230/Neighborhood.h b/tos/chips/rf230/Neighborhood.h deleted file mode 100644 index 40884e39..00000000 --- a/tos/chips/rf230/Neighborhood.h +++ /dev/null @@ -1,31 +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 __NEIGHBORHOOD_H__ -#define __NEIGHBORHOOD_H__ - -#ifndef NEIGHBORHOOD_SIZE -#define NEIGHBORHOOD_SIZE 5 -#endif - -#endif//__NEIGHBORHOOD_H__ diff --git a/tos/chips/rf230/Neighborhood.nc b/tos/chips/rf230/Neighborhood.nc deleted file mode 100644 index cc4b7db4..00000000 --- a/tos/chips/rf230/Neighborhood.nc +++ /dev/null @@ -1,70 +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 - -/** - * Every component maintains its own neighborhood data. The Neighboorhood - * component maintains only the nodeids and ages of the neighbors, and - * evicts old entries from the table when necessary. - */ -interface Neighborhood -{ - /** - * Returns the index of the neighbor in the table. If the node was not - * found in the table, then the value NEIGHBORHOOD is returned, - * otherwise an index in the range [0, NEIGHBORHOOD-1] is returned. - */ - tasklet_async command uint8_t getIndex(am_addr_t id); - - /** - * Returns the age of the given entry. The age is incremented by one - * every time a new node is inserted into the neighborhood table that - * is not already at the very end. If the age would get too large to - * fit into a byte, then it is periodically reset to a smaller value. - */ - tasklet_async command uint8_t getAge(uint8_t index); - - /** - * Returns the node address for the given entry. - */ - tasklet_async command am_addr_t getNode(uint8_t index); - - /** - * Adds a new node into the neighborhood table. If this node was already - * in the table, then it is just brought to the front (its age is reset - * to zero). If the node was not in the table, then the oldest is evicted - * and its entry is replaced with this node. The index of the entry - * is returned in the range [0, NEIGHBORHOOD-1]. - */ - tasklet_async command uint8_t insertNode(am_addr_t id); - - /** - * This event is fired when the oldest entry is replaced with a new - * node. The same interface is used by many users, so all of them - * will receive this event and can clear the corresponding entry. - * After this event is fired, all flags for this entry are cleared - * (see the NeighborhoodFlag interface) - */ - tasklet_async event void evicted(uint8_t index); -} diff --git a/tos/chips/rf230/NeighborhoodC.nc b/tos/chips/rf230/NeighborhoodC.nc deleted file mode 100644 index e2ba9b50..00000000 --- a/tos/chips/rf230/NeighborhoodC.nc +++ /dev/null @@ -1,35 +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 NeighborhoodC -{ - provides interface Neighborhood; -} - -implementation -{ - components NeighborhoodP, MainC; - - Neighborhood = NeighborhoodP; - MainC.SoftwareInit -> NeighborhoodP; -} diff --git a/tos/chips/rf230/NeighborhoodFlag.nc b/tos/chips/rf230/NeighborhoodFlag.nc deleted file mode 100644 index e1dda902..00000000 --- a/tos/chips/rf230/NeighborhoodFlag.nc +++ /dev/null @@ -1,52 +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 - -/** - * This interface provides one bit storage for each neighbor in a very - * fast and conveint way (without using shifts for example). - */ -interface NeighborhoodFlag -{ - /** - * Returns the value of the flag for the given index - */ - tasklet_async command bool get(uint8_t index); - - /** - * Sets the flag for the given index - */ - tasklet_async command void set(uint8_t index); - - /** - * Clears the flag for the given index. The flag is automatically - * cleared after the Neighborhood.evicted event is fired. - */ - tasklet_async command void clear(uint8_t index); - - /** - * Clears the flag for all indices - */ - tasklet_async command void clearAll(); -} diff --git a/tos/chips/rf230/NeighborhoodFlagC.nc b/tos/chips/rf230/NeighborhoodFlagC.nc deleted file mode 100644 index 2f064eb6..00000000 --- a/tos/chips/rf230/NeighborhoodFlagC.nc +++ /dev/null @@ -1,35 +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 - */ - -generic configuration NeighborhoodFlagC() -{ - provides interface NeighborhoodFlag; -} - -implementation -{ - components NeighborhoodP; - - // TODO: make sure that no more than 8 flags are used at a time - NeighborhoodFlag = NeighborhoodP.NeighborhoodFlag[unique("NeighborhoodFlag")]; -} diff --git a/tos/chips/rf230/NeighborhoodP.nc b/tos/chips/rf230/NeighborhoodP.nc deleted file mode 100644 index fb84dc8a..00000000 --- a/tos/chips/rf230/NeighborhoodP.nc +++ /dev/null @@ -1,171 +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 - -module NeighborhoodP -{ - provides - { - interface Init; - interface Neighborhood; - interface NeighborhoodFlag[uint8_t bit]; - } -} - -implementation -{ - tasklet_norace am_addr_t nodes[NEIGHBORHOOD_SIZE]; - tasklet_norace uint8_t ages[NEIGHBORHOOD_SIZE]; - tasklet_norace uint8_t flags[NEIGHBORHOOD_SIZE]; - tasklet_norace uint8_t time; - tasklet_norace uint8_t last; - - command error_t Init.init() - { - uint8_t i; - - for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) - nodes[i] = AM_BROADCAST_ADDR; - - return SUCCESS; - } - - inline tasklet_async command am_addr_t Neighborhood.getNode(uint8_t index) - { - return nodes[index]; - } - - inline tasklet_async command uint8_t Neighborhood.getAge(uint8_t index) - { - return time - ages[index]; - } - - tasklet_async uint8_t command Neighborhood.getIndex(am_addr_t node) - { - uint8_t i; - - if( nodes[last] == node ) - return last; - - for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) - { - if( nodes[i] == node ) - { - last = i; - break; - } - } - - return i; - } - - tasklet_async uint8_t command Neighborhood.insertNode(am_addr_t node) - { - uint8_t i; - uint8_t maxAge; - - if( nodes[last] == node ) - { - if( ages[last] == time ) - return last; - - ages[last] = ++time; - maxAge = 0x80; - } - else - { - uint8_t oldest = 0; - maxAge = 0; - - for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) - { - uint8_t age; - - if( nodes[i] == node ) - { - last = i; - if( ages[i] == time ) - return i; - - ages[i] = ++time; - maxAge = 0x80; - break; - } - - age = time - ages[i]; - if( age > maxAge ) - { - maxAge = age; - oldest = i; - } - } - - if( i == NEIGHBORHOOD_SIZE ) - { - signal Neighborhood.evicted(oldest); - - last = oldest; - nodes[oldest] = node; - ages[oldest] = ++time; - flags[oldest] = 0; - } - } - - if( (time & 0x7F) == 0x7F && maxAge >= 0x7F ) - { - for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) - { - if( (ages[i] | 0x7F) != time ) - ages[i] = time & 0x80; - } - } - - return last; - } - - inline tasklet_async command bool NeighborhoodFlag.get[uint8_t bit](uint8_t index) - { - return flags[index] & (1 << bit); - } - - inline tasklet_async command void NeighborhoodFlag.set[uint8_t bit](uint8_t index) - { - flags[index] |= (1 << bit); - } - - inline tasklet_async command void NeighborhoodFlag.clear[uint8_t bit](uint8_t index) - { - flags[index] &= ~(1 << bit); - } - - tasklet_async command void NeighborhoodFlag.clearAll[uint8_t bit]() - { - uint8_t i; - - bit = ~(1 << bit); - - for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) - flags[i] &= bit; - } -} diff --git a/tos/chips/rf230/PacketField.nc b/tos/chips/rf230/PacketField.nc deleted file mode 100644 index 3f902931..00000000 --- a/tos/chips/rf230/PacketField.nc +++ /dev/null @@ -1,47 +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 - */ - -interface PacketField -{ - /** - * Returns TRUE if the value is set for this message. - */ - async command bool isSet(message_t* msg); - - /** - * Returns the stored value of this field in the message. If the - * value is not set, then the returned value is undefined. - */ - async command value_type get(message_t* msg); - - /** - * Clears the isSet flag. - */ - async command void clear(message_t* msg); - - /** - * Sets the isSet false to TRUE and the time stamp value to the - * specified value. - */ - async command void set(message_t* msg, value_type value); -} diff --git a/tos/chips/rf230/RF2xx.h b/tos/chips/rf230/RF2xx.h deleted file mode 100644 index a694df88..00000000 --- a/tos/chips/rf230/RF2xx.h +++ /dev/null @@ -1,157 +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 __RF2XX_H__ -#define __RF2XX_H__ - -/* Set RF2XX_CHIPSET to one of these to enable specific features */ -#define RF230_CHIPSET 0 -#define 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 deleted file mode 100644 index 0e58c6e1..00000000 --- a/tos/chips/rf230/RF2xxActiveMessageC.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 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 deleted file mode 100644 index edc5b8f6..00000000 --- a/tos/chips/rf230/RF2xxActiveMessageP.nc +++ /dev/null @@ -1,299 +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 - -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 deleted file mode 100644 index 47f73378..00000000 --- a/tos/chips/rf230/RF2xxDriverConfig.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 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 deleted file mode 100644 index 5ce75ebf..00000000 --- a/tos/chips/rf230/RF2xxDriverLayerC.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 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 deleted file mode 100644 index c23a8222..00000000 --- a/tos/chips/rf230/RF2xxDriverLayerP.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 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 deleted file mode 100644 index d3b6898b..00000000 --- a/tos/chips/rf230/RF2xxPacket.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 __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 deleted file mode 100644 index 70b9add2..00000000 --- a/tos/chips/rf230/RF2xxPacketC.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 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 deleted file mode 100644 index 5a727575..00000000 --- a/tos/chips/rf230/RF2xxPacketP.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 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 deleted file mode 100644 index 88da07e5..00000000 --- a/tos/chips/rf230/RF2xxTimeSyncMessageC.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 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 deleted file mode 100644 index fd5dfc88..00000000 --- a/tos/chips/rf230/RF2xxTimeSyncMessageP.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 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/chips/rf230/RadioAlarm.nc b/tos/chips/rf230/RadioAlarm.nc deleted file mode 100644 index d09c4f0e..00000000 --- a/tos/chips/rf230/RadioAlarm.nc +++ /dev/null @@ -1,54 +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 - -interface RadioAlarm -{ - /** - * Returns TRUE if the alarm is free and ready to be used. Once the alarm - * is free, it cannot become nonfree in the same tasklet block. Note, - * if the alarm is currently set (even if for ourselves) then it is not free. - */ - tasklet_async command bool isFree(); - - /** - * Waits till the specified timeout period expires. The alarm must be free. - */ - tasklet_async command void wait(uint16_t timeout); - - /** - * Cancels the running alarm. The alarm must be pending. - */ - tasklet_async command void cancel(); - - /** - * This event is fired when the specified timeout period expires. - */ - tasklet_async event void fired(); - - /** - * Returns the current time as measured by the radio stack. - */ - async command uint16_t getNow(); -} diff --git a/tos/chips/rf230/RadioAlarmC.nc b/tos/chips/rf230/RadioAlarmC.nc deleted file mode 100644 index 68f53d54..00000000 --- a/tos/chips/rf230/RadioAlarmC.nc +++ /dev/null @@ -1,44 +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 RadioAlarmC -{ - provides - { - interface RadioAlarm[uint8_t id]; // use unique("RadioAlarm") - } - - uses - { - interface Alarm @exactlyonce(); - } -} - -implementation -{ - components RadioAlarmP, TaskletC; - - RadioAlarm = RadioAlarmP; - Alarm = RadioAlarmP; - RadioAlarmP.Tasklet -> TaskletC; -} diff --git a/tos/chips/rf230/RadioAlarmP.nc b/tos/chips/rf230/RadioAlarmP.nc deleted file mode 100644 index 537b76a7..00000000 --- a/tos/chips/rf230/RadioAlarmP.nc +++ /dev/null @@ -1,104 +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 RadioAlarmP -{ - provides - { - interface RadioAlarm[uint8_t id]; - } - - uses - { - interface Alarm; - interface Tasklet; - } -} - -implementation -{ - norace uint8_t state; - enum - { - STATE_READY = 0, - STATE_WAIT = 1, - STATE_FIRED = 2, - }; - - tasklet_norace uint8_t alarm; - - async event void Alarm.fired() - { - atomic - { - if( state == STATE_WAIT ) - state = STATE_FIRED; - } - - call Tasklet.schedule(); - } - - inline async command uint16_t RadioAlarm.getNow[uint8_t id]() - { - return call Alarm.getNow(); - } - - tasklet_async event void Tasklet.run() - { - if( state == STATE_FIRED ) - { - state = STATE_READY; - signal RadioAlarm.fired[alarm](); - } - } - - default tasklet_async event void RadioAlarm.fired[uint8_t id]() - { - } - - inline tasklet_async command bool RadioAlarm.isFree[uint8_t id]() - { - return state == STATE_READY; - } - - tasklet_async command void RadioAlarm.wait[uint8_t id](uint16_t timeout) - { - ASSERT( state == STATE_READY ); - - alarm = id; - state = STATE_WAIT; - call Alarm.start(timeout); - } - - tasklet_async command void RadioAlarm.cancel[uint8_t id]() - { - ASSERT( alarm == id ); - ASSERT( state != STATE_READY ); - - call Alarm.stop(); - state = STATE_READY; - } -} diff --git a/tos/chips/rf230/RadioAssert.h b/tos/chips/rf230/RadioAssert.h deleted file mode 100644 index 0194f21e..00000000 --- a/tos/chips/rf230/RadioAssert.h +++ /dev/null @@ -1,38 +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 __RADIOASSERT_H__ -#define __RADIOASSERT_H__ - -#ifdef RF2XX_DEBUG - - void assert(bool condition, const char* file, uint16_t line); - #define ASSERT(COND) assert(COND, __FILE__, __LINE__) - -#else - - #define ASSERT(COND) for(;0;) - -#endif - -#endif//__RADIOASSERT_H__ diff --git a/tos/chips/rf230/RadioCCA.nc b/tos/chips/rf230/RadioCCA.nc deleted file mode 100644 index 78e16949..00000000 --- a/tos/chips/rf230/RadioCCA.nc +++ /dev/null @@ -1,42 +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 - -interface RadioCCA -{ - /** - * Starts the clear channel assesment procedure. Returns EBUSY if the radio - * is currently servicing a clear channel assesment, and SUCCESS otherwise. - * The check will be performed only in the RX_READY state. - */ - tasklet_async command error_t request(); - - /** - * Signals the completion of the clear channel assesment send command. - * SUCCESS means the channel is clear, EBUSY means the channel is not - * clear, and FAIL means that the clear channel assesment could not - * be finished or the operation was cancelled. - */ - tasklet_async event void done(error_t error); -} diff --git a/tos/chips/rf230/RadioChannel.nc b/tos/chips/rf230/RadioChannel.nc deleted file mode 100644 index 5fa6c247..00000000 --- a/tos/chips/rf230/RadioChannel.nc +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2009, Vanderbilt University - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation for any purpose, without fee, and without written agreement is - * hereby granted, provided that the above copyright notice, the following - * two paragraphs and the author appear in all copies of this software. - * - * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT - * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT - * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Author: Miklos Maroti - */ - -interface RadioChannel -{ - /** - * Sets the current channel. Returns EBUSY if the stack is unable - * to change the channel this time (some other operation is in progress), - * EALREADY if the selected channel is already set, SUCCESS otherwise. - */ - command error_t setChannel(uint8_t channel); - - /** - * This event is signaled exactly once for each sucessfully posted state - * setChannel command when it is completed. - */ - event void setChannelDone(); - - /** - * Returns the currently selected channel. - */ - command uint8_t getChannel(); -} diff --git a/tos/chips/rf230/RadioReceive.nc b/tos/chips/rf230/RadioReceive.nc deleted file mode 100644 index 0e8330f9..00000000 --- a/tos/chips/rf230/RadioReceive.nc +++ /dev/null @@ -1,43 +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 - -interface RadioReceive -{ - /** - * This event is fired when the header is received/downloaded and the - * higher layers are consulted whether it needs to be downloaded and - * further processed. Return FALSE if the message should be discarded. - * In particular, the message buffer layer returns FALSE if there is - * no space for a new message, so this message will not get acknowledged. - */ - tasklet_async event bool header(message_t* msg); - - /** - * Signals the reception of a message, but only for those messages for - * which SUCCESS was returned in the header event. The usual owner rules - * apply to the message pointers. - */ - tasklet_async event message_t* receive(message_t* msg); -} diff --git a/tos/chips/rf230/RadioSend.nc b/tos/chips/rf230/RadioSend.nc deleted file mode 100644 index 59437946..00000000 --- a/tos/chips/rf230/RadioSend.nc +++ /dev/null @@ -1,53 +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 - -interface RadioSend -{ - /** - * Starts the transmission of the given message. This command must not - * be called while another send is in progress (so one must wait for the - * sendDone event). Returns EBUSY if a reception is in progress or for - * some other reason the request cannot be temporarily satisfied (e.g. - * the SPI bus access could not be acquired). In this case the send - * command could be retried from a tasklet. Returns SUCCESS if the - * transmission could be started. In this case sendDone will be fired. - */ - tasklet_async command error_t send(message_t* msg); - - /** - * Signals the completion of the send command, exactly once for each - * successfull send command. If the returned error code is SUCCESS, then - * the message was sent (may not have been acknowledged), otherwise - * the message was not transmitted over the air. - */ - tasklet_async event void sendDone(error_t error); - - /** - * This event is fired when the component is most likely able to accept - * a send request. If the send command has returned with a failure, then - * this event will be called at least once in the near future. - */ - tasklet_async event void ready(); -} diff --git a/tos/chips/rf230/RadioState.nc b/tos/chips/rf230/RadioState.nc deleted file mode 100644 index cae77813..00000000 --- a/tos/chips/rf230/RadioState.nc +++ /dev/null @@ -1,64 +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 - -interface RadioState -{ - /** - * Moves to radio into sleep state with the lowest power consumption but - * highest wakeup time. The radio cannot send or receive in this state - * and releases all access to shared resources (e.g. SPI bus). - */ - tasklet_async command error_t turnOff(); - - /** - * The same as the turnOff command, except it is not as deep sleep, and - * it is quicker to recover from this state. - */ - tasklet_async command error_t standby(); - - /** - * Goes into receive state. The radio continuously receive messages - * and able to transmit. - */ - tasklet_async command error_t turnOn(); - - /** - * Sets the current channel. Returns EBUSY if the stack is unable - * to change the channel this time (some other operation is in progress) - * SUCCESS otherwise. - */ - tasklet_async command error_t setChannel(uint8_t channel); - - /** - * This event is signaled exactly once for each sucessfully posted state - * transition and setChannel command when it is completed. - */ - tasklet_async event void done(); - - /** - * Returns the currently selected channel. - */ - tasklet_async command uint8_t getChannel(); -} diff --git a/tos/chips/rf230/RandomCollisionConfig.nc b/tos/chips/rf230/RandomCollisionConfig.nc deleted file mode 100644 index b12cc692..00000000 --- a/tos/chips/rf230/RandomCollisionConfig.nc +++ /dev/null @@ -1,47 +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 - */ - -interface RandomCollisionConfig -{ - /** - * Returns the initial amount of maximum backoff for this message. - */ - async command uint16_t getInitialBackoff(message_t* msg); - - /** - * Returns the amount of maximum backoff when there is congestion - * (the channel was busy for the first try) - */ - async command uint16_t getCongestionBackoff(message_t* msg); - - /** - * Returns the minimum ticks before the message could be sent. - */ - async command uint16_t getMinimumBackoff(); - - /** - * The provided message was just received, and this command should return - * the time till no transmission should be initiated. - */ - async command uint16_t getTransmitBarrier(message_t* msg); -} diff --git a/tos/chips/rf230/RandomCollisionLayerC.nc b/tos/chips/rf230/RandomCollisionLayerC.nc deleted file mode 100644 index ba7ad054..00000000 --- a/tos/chips/rf230/RandomCollisionLayerC.nc +++ /dev/null @@ -1,51 +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 RandomCollisionLayerC -{ - provides - { - interface RadioSend; - interface RadioReceive; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RandomCollisionConfig as Config; - } -} - -implementation -{ - components RandomCollisionLayerP, RadioAlarmC, RandomC; - - RadioSend = RandomCollisionLayerP; - SubSend = RandomCollisionLayerP; - Config = RandomCollisionLayerP; - RadioReceive = RandomCollisionLayerP; - SubReceive = RandomCollisionLayerP; - - RandomCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; - RandomCollisionLayerP.Random -> RandomC; -} diff --git a/tos/chips/rf230/RandomCollisionLayerP.nc b/tos/chips/rf230/RandomCollisionLayerP.nc deleted file mode 100644 index c53d1b91..00000000 --- a/tos/chips/rf230/RandomCollisionLayerP.nc +++ /dev/null @@ -1,177 +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 RandomCollisionLayerP -{ - provides - { - interface RadioSend; - interface RadioReceive; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RadioAlarm; - interface Random; - interface RandomCollisionConfig as Config; - } -} - -implementation -{ - tasklet_norace uint8_t state; - enum - { - STATE_READY = 0, - STATE_TX_PENDING_FIRST = 1, - STATE_TX_PENDING_SECOND = 2, - STATE_TX_SENDING = 3, - - STATE_BARRIER = 0x80, - }; - - tasklet_norace message_t *txMsg; - tasklet_norace uint16_t txBarrier; - - tasklet_async event void SubSend.ready() - { - if( state == STATE_READY && call RadioAlarm.isFree() ) - signal RadioSend.ready(); - } - - uint16_t nextRandom; - task void calcNextRandom() - { - uint16_t a = call Random.rand16(); - atomic nextRandom = a; - } - - uint16_t getBackoff(uint16_t maxBackoff) - { - uint16_t a; - - atomic - { - a = nextRandom; - nextRandom += 273; - } - post calcNextRandom(); - - return (a % maxBackoff) + call Config.getMinimumBackoff(); - } - - tasklet_async command error_t RadioSend.send(message_t* msg) - { - if( state != STATE_READY || ! call RadioAlarm.isFree() ) - return EBUSY; - - txMsg = msg; - state = STATE_TX_PENDING_FIRST; - call RadioAlarm.wait(getBackoff(call Config.getInitialBackoff(msg))); - - return SUCCESS; - } - - tasklet_async event void RadioAlarm.fired() - { - error_t error; - int16_t delay; - - ASSERT( state != STATE_READY ); - - delay = (int16_t)txBarrier - call RadioAlarm.getNow(); - - if( state == STATE_BARRIER ) - { - state = STATE_READY; - - signal RadioSend.ready(); - return; - } - else if( (state & STATE_BARRIER) && delay > 0 ) - error = EBUSY; - else - error = call SubSend.send(txMsg); - - if( error != SUCCESS ) - { - if( (state & ~STATE_BARRIER) == STATE_TX_PENDING_FIRST ) - { - state = (state & STATE_BARRIER) | STATE_TX_PENDING_SECOND; - call RadioAlarm.wait(getBackoff(call Config.getCongestionBackoff(txMsg))); - } - else - { - if( (state & STATE_BARRIER) && delay > 0 ) - { - state = STATE_BARRIER; - call RadioAlarm.wait(delay); - } - else - state = STATE_READY; - - signal RadioSend.sendDone(error); - } - } - else - state = STATE_TX_SENDING; - } - - tasklet_async event void SubSend.sendDone(error_t error) - { - ASSERT( state == STATE_TX_SENDING ); - - state = STATE_READY; - signal RadioSend.sendDone(error); - } - - tasklet_async event bool SubReceive.header(message_t* msg) - { - return signal RadioReceive.header(msg); - } - - tasklet_async event message_t* SubReceive.receive(message_t* msg) - { - int16_t delay; - - txBarrier = call Config.getTransmitBarrier(msg); - delay = txBarrier - call RadioAlarm.getNow(); - - if( delay > 0 ) - { - if( state == STATE_READY ) - { - call RadioAlarm.wait(delay); - state = STATE_BARRIER; - } - else - state |= STATE_BARRIER; - } - - return signal RadioReceive.receive(msg); - } -} diff --git a/tos/chips/rf230/SlottedCollisionConfig.nc b/tos/chips/rf230/SlottedCollisionConfig.nc deleted file mode 100644 index 4b6b9931..00000000 --- a/tos/chips/rf230/SlottedCollisionConfig.nc +++ /dev/null @@ -1,61 +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 - */ - -interface SlottedCollisionConfig -{ - /** - * This command should return the approximate transmit delay between - * setting an alarm, waiting for the fire event, calling send and - * obtaining the timestamp for the transmitted message. - */ - async command uint16_t getInitialDelay(); - - /** - * Must return a binary exponent so that the collision avoidance layer - * can assign slots in the range of [0, 1 << exponent) of size collision - * window. - */ - async command uint8_t getScheduleExponent(); - - /** - * This command must return the time when the message was transmitted. - */ - async command uint16_t getTransmitTime(message_t* msg); - - /** - * Returns the start of the collision window for this received message, - * so transmit times in this range would be considered possible collisions. - */ - async command uint16_t getCollisionWindowStart(message_t* msg); - - /** - * Returns the size of the collision window for this received message. - */ - async command uint16_t getCollisionWindowLength(message_t* msg); - - /** - * This event should be called periodically to indicate the passing of - * time (maybe we should use a timer) - */ - tasklet_async event void timerTick(); -} diff --git a/tos/chips/rf230/SlottedCollisionLayerC.nc b/tos/chips/rf230/SlottedCollisionLayerC.nc deleted file mode 100644 index fb3962b3..00000000 --- a/tos/chips/rf230/SlottedCollisionLayerC.nc +++ /dev/null @@ -1,57 +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 SlottedCollisionLayerC -{ - provides - { - interface RadioSend; - interface RadioReceive; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface SlottedCollisionConfig as Config; - } -} - -implementation -{ - components SlottedCollisionLayerP, MainC, RadioAlarmC, RandomC; - - RadioSend = SlottedCollisionLayerP; - RadioReceive = SlottedCollisionLayerP; - SubSend = SlottedCollisionLayerP; - SubReceive = SlottedCollisionLayerP; - Config = SlottedCollisionLayerP; - - SlottedCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; - SlottedCollisionLayerP.Random -> RandomC; - MainC.SoftwareInit -> SlottedCollisionLayerP; - -#ifdef RF2XX_DEBUG - components DiagMsgC; - SlottedCollisionLayerP.DiagMsg -> DiagMsgC; -#endif -} diff --git a/tos/chips/rf230/SlottedCollisionLayerP.nc b/tos/chips/rf230/SlottedCollisionLayerP.nc deleted file mode 100644 index 4a7eaff6..00000000 --- a/tos/chips/rf230/SlottedCollisionLayerP.nc +++ /dev/null @@ -1,275 +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 SlottedCollisionLayerP -{ - provides - { - interface RadioSend; - interface RadioReceive; - interface Init; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RadioAlarm; - interface Random; - interface SlottedCollisionConfig as Config; -#ifdef RF2XX_DEBUG - interface DiagMsg; -#endif - } -} - -implementation -{ -/* ----- random ----- */ - - uint16_t nextRandom; - - task void calcNextRandom() - { - uint16_t a = call Random.rand16(); - atomic nextRandom = a; - } - - uint16_t getNextRandom() - { - uint16_t a; - - atomic - { - a = nextRandom; - nextRandom += 273; - } - post calcNextRandom(); - - return a; - } - -/* ----- schedule selection ----- */ - - tasklet_async event bool SubReceive.header(message_t* msg) - { - return signal RadioReceive.header(msg); - } - - // WARNING!!! Do not change these values, the error values can overflow - enum - { - ERROR_DECAY = 3, - ERROR_SWITCH = 30, // should be a multiple of (1 << decay) - ERROR_COLLISION = 20, // must be less than (255 - switch) >> decay - ERROR_BUSY = 1, // must be less than collision - ERROR_INITIAL = 80, // must be less than giveup - ERROR_GIVEUP = 120, // must be less than collision * (1 << decay) - ERROR_REPRESS = 40, // must be more than switch - ERROR_MAX = 255, - }; - - /** - * Returns TRUE if time is between start and start + window - * modulo the schedule size of (1 << exponent) - */ - inline bool isBetween(uint8_t exponent, uint16_t time, uint16_t start, uint16_t length) - { - return (uint16_t)((time - start) & ((1 << exponent) - 1)) < length; - } - - tasklet_norace uint16_t schedule1; - tasklet_norace uint16_t schedule2; - - tasklet_norace uint8_t error1; - tasklet_norace uint8_t error2; - - tasklet_async event message_t* SubReceive.receive(message_t* msg) - { - uint8_t exponent = call Config.getScheduleExponent(); - uint16_t start = call Config.getCollisionWindowStart(msg); - uint16_t length = call Config.getCollisionWindowLength(msg); - - error1 -= error1 >> ERROR_DECAY; - if( isBetween(exponent, schedule1, start, length) ) - error1 += ERROR_COLLISION; - - error2 -= error2 >> ERROR_DECAY; - if( isBetween(exponent, schedule2, start, length) ) - error2 += ERROR_COLLISION; - - if( error2 + ERROR_SWITCH <= error1 ) - { - error1 = error2; - schedule1 = schedule2; - error2 = ERROR_GIVEUP; - } - - if( error2 >= ERROR_GIVEUP ) - { - error2 = ERROR_INITIAL; - schedule2 = getNextRandom(); - } - - return signal RadioReceive.receive(msg); - } - - void printStats(); - - tasklet_async event void Config.timerTick() - { - if( error1 >= (1 << ERROR_DECAY) ) - error1 -= error1 >> ERROR_DECAY; - else if( error1 > 0 ) - --error1; - - if( error2 >= (1 << ERROR_DECAY) ) - error2 -= error2 >> ERROR_DECAY; - else if( error2 > 0 ) - --error2; - - printStats(); - } - -/* ------ transmit ------ */ - - tasklet_norace uint8_t state; - enum - { - STATE_READY = 0, - STATE_PENDING = 1, - STATE_SENDING = 2, - }; - - enum { DELAY_DECAY = 2 }; - - tasklet_norace message_t *txMsg; - tasklet_norace uint16_t txDelay; // the averaged delay between schedule and timestamp - tasklet_norace uint16_t txTime; // the schedule time of transmission - - tasklet_async event void SubSend.ready() - { - if( state == STATE_READY && call RadioAlarm.isFree() ) - signal RadioSend.ready(); - } - - tasklet_async command error_t RadioSend.send(message_t* msg) - { - uint16_t backoff; - uint16_t time; - - // TODO: we could supress transmission while error is large - if( state != STATE_READY || ! call RadioAlarm.isFree() || error1 >= ERROR_REPRESS ) - return EBUSY; - - txMsg = msg; - state = STATE_PENDING; - - time = call RadioAlarm.getNow(); - backoff = 1 + ((schedule1 - time - (txDelay >> DELAY_DECAY)) - & ((1 << call Config.getScheduleExponent()) - 1)); - - backoff += getNextRandom() & (3 << call Config.getScheduleExponent()); - - call RadioAlarm.wait(backoff); - txTime = time + backoff; - - return SUCCESS; - } - - tasklet_async event void RadioAlarm.fired() - { - error_t error; - - ASSERT( state == STATE_PENDING ); - - error = call SubSend.send(txMsg); - if( error == SUCCESS ) - state = STATE_SENDING; - else - { - if( error2 + ERROR_SWITCH <= error1 ) - { - error1 = error2; - schedule1 = schedule2; - error2 = ERROR_INITIAL; - schedule2 = getNextRandom(); - } - else if( error1 < ERROR_MAX - ERROR_BUSY ) - error1 = error1 + ERROR_BUSY; - - state = STATE_READY; - signal RadioSend.sendDone(error); - } - } - - tasklet_async event void SubSend.sendDone(error_t error) - { - ASSERT( state == STATE_SENDING ); - - if( error == SUCCESS ) - { - txDelay += (call Config.getTransmitTime(txMsg) - txTime) - (txDelay >> DELAY_DECAY); - - ASSERT( (txDelay >> DELAY_DECAY) < (1 << call Config.getScheduleExponent()) ); - } - - state = STATE_READY; - signal RadioSend.sendDone(error); - } - -/* ------ init ------ */ - - command error_t Init.init() - { - // do not use Random here because it might not be initialized - schedule1 = (uint16_t)(TOS_NODE_ID * 1973); - schedule2 = schedule1 + 0117; - txDelay = call Config.getInitialDelay() << DELAY_DECAY; - - return SUCCESS; - } - -#ifdef RF2XX_DEBUG - tasklet_norace uint8_t count; - void printStats() - { - if( ++count > 10 && call DiagMsg.record() ) - { - count = 0; - - call DiagMsg.str("slotted"); - call DiagMsg.uint16(txDelay >> DELAY_DECAY); - call DiagMsg.uint16(schedule1); - call DiagMsg.uint8(error1); - call DiagMsg.uint16(schedule2); - call DiagMsg.uint8(error2); - call DiagMsg.send(); - } - } -#else - void printStats() { } -#endif -} diff --git a/tos/chips/rf230/SoftwareAckConfig.nc b/tos/chips/rf230/SoftwareAckConfig.nc deleted file mode 100644 index b3c87c73..00000000 --- a/tos/chips/rf230/SoftwareAckConfig.nc +++ /dev/null @@ -1,75 +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 - -interface SoftwareAckConfig -{ - /** - * Returns the acknowledgement timeout (in the radio clock units), - * in which a sent packet must be acknowledged. - */ - async command uint16_t getAckTimeout(); - - /** - * Returns TRUE if the layer should wait for a software acknowledgement - * to be received after this packet was transmitted. - */ - async command bool requiresAckWait(message_t* msg); - - /** - * Sets for the transmitted message whether it was acknowledged or not. - */ - async command void setAckReceived(message_t* msg, bool acked); - - /** - * Returns TRUE if the received packet is an acknowledgement packet. - * The AckedSend layer will filter out all received acknowledgement - * packets and uses only the matching one for the acknowledgement. - */ - async command bool isAckPacket(message_t* msg); - - /** - * Returns TRUE if the acknowledgement packet corresponds to the - * data packet. The acknowledgement packect was already verified - * to be a valid acknowledgement packet via the isAckPacket command. - */ - async command bool verifyAckPacket(message_t* data, message_t* ack); - - /** - * Returns TRUE if the received packet needs software acknowledgements - * to be sent back to the sender. - */ - async command bool requiresAckReply(message_t* msg); - - /** - * Creates an acknowledgement packet for the given data packet. - */ - async command void createAckPacket(message_t* data, message_t* ack); - - /** - * This command is called when a sent packet did not receive an - * acknowledgement. - */ - tasklet_async command void reportChannelError(); -} diff --git a/tos/chips/rf230/SoftwareAckLayerC.nc b/tos/chips/rf230/SoftwareAckLayerC.nc deleted file mode 100644 index 97703e1f..00000000 --- a/tos/chips/rf230/SoftwareAckLayerC.nc +++ /dev/null @@ -1,51 +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 SoftwareAckLayerC -{ - provides - { - interface RadioSend; - interface RadioReceive; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - - interface SoftwareAckConfig as Config; - } -} - -implementation -{ - components SoftwareAckLayerP, RadioAlarmC; - - RadioSend = SoftwareAckLayerP; - RadioReceive = SoftwareAckLayerP; - SubSend = SoftwareAckLayerP; - SubReceive = SoftwareAckLayerP; - Config = SoftwareAckLayerP; - - SoftwareAckLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; -} diff --git a/tos/chips/rf230/SoftwareAckLayerP.nc b/tos/chips/rf230/SoftwareAckLayerP.nc deleted file mode 100644 index 02ca70de..00000000 --- a/tos/chips/rf230/SoftwareAckLayerP.nc +++ /dev/null @@ -1,161 +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 SoftwareAckLayerP -{ - provides - { - interface RadioSend; - interface RadioReceive; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RadioAlarm; - - interface SoftwareAckConfig; - } -} - -implementation -{ - tasklet_norace uint8_t state; - enum - { - STATE_READY = 0, - STATE_DATA_SEND = 1, - STATE_ACK_WAIT = 2, - STATE_ACK_SEND = 3, - }; - - tasklet_norace message_t *txMsg; - tasklet_norace message_t ackMsg; - - tasklet_async event void SubSend.ready() - { - if( state == STATE_READY ) - signal RadioSend.ready(); - } - - tasklet_async command error_t RadioSend.send(message_t* msg) - { - error_t error; - - if( state == STATE_READY ) - { - if( (error = call SubSend.send(msg)) == SUCCESS ) - { - call SoftwareAckConfig.setAckReceived(msg, FALSE); - state = STATE_DATA_SEND; - txMsg = msg; - } - } - else - error = EBUSY; - - return error; - } - - tasklet_async event void SubSend.sendDone(error_t error) - { - if( state == STATE_ACK_SEND ) - { - // TODO: what if error != SUCCESS - ASSERT( error == SUCCESS ); - - state = STATE_READY; - } - else - { - ASSERT( state == STATE_DATA_SEND ); - ASSERT( call RadioAlarm.isFree() ); - - if( error == SUCCESS && call SoftwareAckConfig.requiresAckWait(txMsg) && call RadioAlarm.isFree() ) - { - call RadioAlarm.wait(call SoftwareAckConfig.getAckTimeout()); - state = STATE_ACK_WAIT; - } - else - { - state = STATE_READY; - signal RadioSend.sendDone(error); - } - } - } - - tasklet_async event void RadioAlarm.fired() - { - ASSERT( state == STATE_ACK_WAIT ); - - call SoftwareAckConfig.reportChannelError(); - - state = STATE_READY; - signal RadioSend.sendDone(SUCCESS); // we have sent it, but not acked - } - - tasklet_async event bool SubReceive.header(message_t* msg) - { - if( call SoftwareAckConfig.isAckPacket(msg) ) - return state == STATE_ACK_WAIT && call SoftwareAckConfig.verifyAckPacket(txMsg, msg); - else - return signal RadioReceive.header(msg); - } - - tasklet_async event message_t* SubReceive.receive(message_t* msg) - { - bool ack = call SoftwareAckConfig.isAckPacket(msg); - - ASSERT( state == STATE_ACK_WAIT || state == STATE_READY ); - - if( state == STATE_ACK_WAIT ) - { - ASSERT( !ack || call SoftwareAckConfig.verifyAckPacket(txMsg, msg) ); - - call RadioAlarm.cancel(); - call SoftwareAckConfig.setAckReceived(txMsg, ack); - - state = STATE_READY; - signal RadioSend.sendDone(SUCCESS); - } - - if( ack ) - return msg; - - if( call SoftwareAckConfig.requiresAckReply(msg) ) - { - call SoftwareAckConfig.createAckPacket(msg, &ackMsg); - - // TODO: what to do if we are busy and cannot send an ack - if( call SubSend.send(&ackMsg) == SUCCESS ) - state = STATE_ACK_SEND; - else - ASSERT(FALSE); - } - - return signal RadioReceive.receive(msg); - } -} diff --git a/tos/chips/rf230/Tasklet.h b/tos/chips/rf230/Tasklet.h deleted file mode 100644 index e4cd520c..00000000 --- a/tos/chips/rf230/Tasklet.h +++ /dev/null @@ -1,39 +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 __TASKLET_H__ -#define __TASKLET_H__ - -#ifdef TASKLET_IS_TASK - - #define tasklet_async - #define tasklet_norace - -#else - - #define tasklet_async async - #define tasklet_norace norace - -#endif - -#endif//__TASKLET_H__ diff --git a/tos/chips/rf230/Tasklet.nc b/tos/chips/rf230/Tasklet.nc deleted file mode 100644 index 527400aa..00000000 --- a/tos/chips/rf230/Tasklet.nc +++ /dev/null @@ -1,69 +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 - -/** - * This interface is useful in building state machines when the state - * transitions should be executed atomically but with interrupts enabled. - * All state transitions should take place in the run event handler or - * in blocks protected by the suspend and resume commands. - */ -interface Tasklet -{ - /** - * This method is executed atomically. - */ - tasklet_async event void run(); - - /** - * Makes sure that the run event is called at least once more. If the - * run event is currently not executing, then it is called immediately - * and this command returns only after the completion of the run event. - * If the run event is currently executed, then this method returns at - * once, and makes sure that the run event is called once more when - * it is finished. If this method is called from a task, then by the - * above rules, the run event will be called from a task as well. - */ - async command void schedule(); - - /** - * Enters a critical section of the code and meakes sure that the - * run event is not called while in this section. No long running - * computation should be called from the critical session, and - * in particular no user event should be fired. This call is only - * possible from task context, otherwise we cannot guarantee that - * the run event is not currently running. The suspend calls - * can be nested. It is very important that the same number of - * resume commands must be called in all control paths, e.g. be very - * careful with the return and break commands. - */ - command void suspend(); - - /** - * Leaves the critical section. This call is conly possible from - * task context. If there were scheduled executions of the run - * event, then those will be called before this command returns. - */ - command void resume(); -} diff --git a/tos/chips/rf230/TaskletC.nc b/tos/chips/rf230/TaskletC.nc deleted file mode 100644 index 360f54fb..00000000 --- a/tos/chips/rf230/TaskletC.nc +++ /dev/null @@ -1,118 +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 TaskletC -{ - provides interface Tasklet; -} - -implementation -{ -#ifdef TASKLET_IS_TASK - - task void tasklet() - { - signal Tasklet.run(); - } - - inline async command void Tasklet.schedule() - { - post tasklet(); - } - - inline command void Tasklet.suspend() - { - } - - inline command void Tasklet.resume() - { - } - -#else - - /** - * The lower 7 bits contain the number of suspends plus one if the run - * event is currently beeing executed. The highest bit is set if the run - * event needs to be called again when the suspend count goes down to zero. - */ - uint8_t state; - - void doit() - { - for(;;) - { - signal Tasklet.run(); - - atomic - { - if( state == 1 ) - { - state = 0; - return; - } - - ASSERT( state == 0x81 ); - state = 1; - } - } - } - - inline command void Tasklet.suspend() - { - atomic ++state; - } - - command void Tasklet.resume() - { - atomic - { - if( --state != 0x80 ) - return; - - state = 1; - } - - doit(); - } - - async command void Tasklet.schedule() - { - atomic - { - if( state != 0 ) - { - state |= 0x80; - return; - } - - state = 1; - } - - doit(); - } - -#endif -} diff --git a/tos/chips/rf230/TimeSyncMessage.h b/tos/chips/rf230/TimeSyncMessage.h deleted file mode 100644 index 38fba022..00000000 --- a/tos/chips/rf230/TimeSyncMessage.h +++ /dev/null @@ -1,33 +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 __TIMESYNCMESSAGE_H__ -#define __TIMESYNCMESSAGE_H__ - -// this value is sent in the air -typedef nx_int32_t timesync_relative_t; - -// this value is stored in memory -typedef uint32_t timesync_absolute_t; - -#endif//__TIMESYNCMESSAGE_H__ diff --git a/tos/chips/rf230/TrafficMonitorConfig.nc b/tos/chips/rf230/TrafficMonitorConfig.nc deleted file mode 100644 index 0b7bc649..00000000 --- a/tos/chips/rf230/TrafficMonitorConfig.nc +++ /dev/null @@ -1,80 +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 - -interface TrafficMonitorConfig -{ - /** - * Returns the frequency (in milliseconds) when the traffic averages - * should be updated. - */ - async command uint16_t getUpdatePeriod(); - - /** - * Returns the amount of time this message has occupied the channel. - */ - async command uint16_t getChannelTime(message_t* msg); - - /** - * Returns the sender address of the message so we can calculate the - * average number of neighbors that send messages per update period. - */ - async command am_addr_t getSender(message_t* msg); - - /** - * This event should be fired if we notice some anomalies in the operation - * of the channel, such as not receiving acknowledgements, missing - * sequence numbers or packets with corrupted CRC. - */ - tasklet_async event void channelError(); - - /** - * Returns the averaged (exponential decay) transmit channel time - * during one update period. - */ - tasklet_async event uint16_t getTransmitAverage(); - - /** - * Returns the averaged (exponential decay) receive channel time - * during one update period. - */ - tasklet_async event uint16_t getReceiveAverage(); - - /** - * Returns the averaged (exponential decay) number of neighbors - * whose messages this component receives during one update period. - */ - tasklet_async event uint8_t getNeighborAverage(); - - /** - * Returns the averaged error events during one update period. - */ - tasklet_async event uint8_t getErrorAverage(); - - /** - * This command is periodically called when the timer is fired and - * the averages are updated - */ - tasklet_async command void timerTick(); -} diff --git a/tos/chips/rf230/TrafficMonitorLayerC.nc b/tos/chips/rf230/TrafficMonitorLayerC.nc deleted file mode 100644 index bad50e12..00000000 --- a/tos/chips/rf230/TrafficMonitorLayerC.nc +++ /dev/null @@ -1,64 +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 TrafficMonitorLayerC -{ - provides - { - interface RadioSend; - interface RadioReceive; - interface RadioState; - } - uses - { - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RadioState as SubState; - - interface TrafficMonitorConfig as Config; - } -} - -implementation -{ - components TrafficMonitorLayerP, new TimerMilliC() as UpdateTimerC; - components NeighborhoodC, new NeighborhoodFlagC(), TaskletC; - - RadioSend = TrafficMonitorLayerP; - RadioReceive = TrafficMonitorLayerP; - RadioState = TrafficMonitorLayerP; - SubSend = TrafficMonitorLayerP; - SubReceive = TrafficMonitorLayerP; - SubState = TrafficMonitorLayerP; - Config = TrafficMonitorLayerP; - - TrafficMonitorLayerP.Timer -> UpdateTimerC; - TrafficMonitorLayerP.Neighborhood -> NeighborhoodC; - TrafficMonitorLayerP.NeighborhoodFlag -> NeighborhoodFlagC; - TrafficMonitorLayerP.Tasklet -> TaskletC; - -#ifdef RF2XX_DEBUG - components DiagMsgC; - TrafficMonitorLayerP.DiagMsg -> DiagMsgC; -#endif -} diff --git a/tos/chips/rf230/TrafficMonitorLayerP.nc b/tos/chips/rf230/TrafficMonitorLayerP.nc deleted file mode 100644 index ff9a42a3..00000000 --- a/tos/chips/rf230/TrafficMonitorLayerP.nc +++ /dev/null @@ -1,247 +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, reportS, ENHANCEMENTS, OR MODIFICATIONS. - * - * Author: Miklos Maroti - */ - -#include - -/* - * You have to make sure that the maximum channel time in one report - * period times (1 << TRAFFIC_MONITOR_DECAY) is less than 65535. - */ -#ifndef TRAFFIC_MONITOR_DECAY -#define TRAFFIC_MONITOR_DECAY 3 -#endif - -module TrafficMonitorLayerP -{ - provides - { - interface RadioSend; - interface RadioReceive; - interface RadioState; - } - - uses - { - interface TrafficMonitorConfig; - interface RadioSend as SubSend; - interface RadioReceive as SubReceive; - interface RadioState as SubState; - interface Timer as Timer; - interface Neighborhood; - interface NeighborhoodFlag; - interface Tasklet; -#ifdef RF2XX_DEBUG - interface DiagMsg; -#endif - } -} - -implementation -{ - tasklet_norace message_t *txMsg; - tasklet_norace uint8_t neighborCount; - - tasklet_norace uint16_t txAverage; - tasklet_norace uint16_t rxAverage; - tasklet_norace uint8_t neighborAverage; - tasklet_norace uint8_t errorAverage; - - enum - { - // the maximum average value - TRAFFIC_MONITOR_UINT8_MAX = 1 << (7-TRAFFIC_MONITOR_DECAY), - - // the unsignificant bits of the averaged values - TRAFFIC_MONITOR_MASK = (1 << TRAFFIC_MONITOR_DECAY) - 1, - - // to get the ceiling integer value - TRAFFIC_MONITOR_ROUND_UP = (1 << TRAFFIC_MONITOR_DECAY) - 1, - }; - - tasklet_async event void SubSend.ready() - { - signal RadioSend.ready(); - } - - tasklet_async command error_t RadioSend.send(message_t* msg) - { - txMsg = msg; - return call SubSend.send(msg); - } - - tasklet_async event void SubSend.sendDone(error_t error) - { - if( error == SUCCESS ) - txAverage += call TrafficMonitorConfig.getChannelTime(txMsg); - - signal RadioSend.sendDone(error); - } - - tasklet_async event bool SubReceive.header(message_t* msg) - { - return signal RadioReceive.header(msg); - } - - tasklet_async event message_t* SubReceive.receive(message_t* msg) - { - uint8_t index; - - rxAverage += call TrafficMonitorConfig.getChannelTime(msg); - - index = call Neighborhood.insertNode(call TrafficMonitorConfig.getSender(msg)); - if( ! call NeighborhoodFlag.get(index) ) - { - if( neighborCount < TRAFFIC_MONITOR_UINT8_MAX ) - { - ++neighborCount; - call NeighborhoodFlag.set(index); - } - } - - return signal RadioReceive.receive(msg); - } - - tasklet_async event void TrafficMonitorConfig.channelError() - { - if( errorAverage < 255 ) - ++errorAverage; - } - - uint8_t debugCounter; - - event void Timer.fired() - { - uint8_t fraction; - - call Tasklet.suspend(); - - txAverage -= (txAverage >> TRAFFIC_MONITOR_DECAY); - rxAverage -= (rxAverage >> TRAFFIC_MONITOR_DECAY); - errorAverage -= (errorAverage >> TRAFFIC_MONITOR_DECAY); - - // we could get stuck in the [1,7] range with no neighbors, so be more precise - fraction = neighborAverage >> TRAFFIC_MONITOR_DECAY; - if( fraction == neighborCount && (neighborAverage & TRAFFIC_MONITOR_MASK) != 0 ) - --neighborAverage; - else - neighborAverage += neighborCount - fraction; - - call NeighborhoodFlag.clearAll(); - neighborCount = 0; - - call TrafficMonitorConfig.timerTick(); - - call Tasklet.resume(); - -#ifdef RF2XX_DEBUG - if( ++debugCounter >= 10 && call DiagMsg.record() ) - { - debugCounter = 0; - - call DiagMsg.str("traffic"); - call DiagMsg.uint16(signal TrafficMonitorConfig.getTransmitAverage()); - call DiagMsg.uint16(signal TrafficMonitorConfig.getReceiveAverage()); - call DiagMsg.uint8(signal TrafficMonitorConfig.getNeighborAverage()); - call DiagMsg.uint8(signal TrafficMonitorConfig.getErrorAverage()); - call DiagMsg.send(); - } -#endif - } - - tasklet_async event void Tasklet.run() - { - } - - tasklet_async event uint16_t TrafficMonitorConfig.getTransmitAverage() - { - return txAverage >> TRAFFIC_MONITOR_DECAY; - } - - tasklet_async event uint16_t TrafficMonitorConfig.getReceiveAverage() - { - return rxAverage >> TRAFFIC_MONITOR_DECAY; - } - - tasklet_async event uint8_t TrafficMonitorConfig.getNeighborAverage() - { - return (neighborAverage + TRAFFIC_MONITOR_ROUND_UP) >> TRAFFIC_MONITOR_DECAY; - } - - tasklet_async event uint8_t TrafficMonitorConfig.getErrorAverage() - { - return errorAverage >> TRAFFIC_MONITOR_DECAY; - } - - tasklet_async event void Neighborhood.evicted(uint8_t index) { } - - enum - { - RADIO_CMD_NONE = 0, - RADIO_CMD_TURNON = 1, - RADIO_CMD_TURNOFF = 2, - }; - tasklet_norace uint8_t radioCmd; - - tasklet_async command error_t RadioState.turnOff() - { - radioCmd = RADIO_CMD_TURNOFF; - return call SubState.turnOff(); - } - - tasklet_async command error_t RadioState.standby() - { - radioCmd = RADIO_CMD_TURNOFF; - return call SubState.standby(); - } - - tasklet_async command error_t RadioState.turnOn() - { - radioCmd = RADIO_CMD_TURNON; - return call SubState.turnOn(); - } - - tasklet_async command error_t RadioState.setChannel(uint8_t channel) - { - radioCmd = RADIO_CMD_NONE; - return call SubState.setChannel(channel); - } - - tasklet_async command uint8_t RadioState.getChannel() - { - return call SubState.getChannel(); - } - - task void startStopTimer() - { - if( radioCmd == RADIO_CMD_TURNON ) - call Timer.startPeriodic(call TrafficMonitorConfig.getUpdatePeriod()); - else if( radioCmd == RADIO_CMD_TURNOFF ) - call Timer.stop(); - } - - tasklet_async event void SubState.done() - { - post startStopTimer(); - signal RadioState.done(); - } -} diff --git a/tos/chips/rf230/UniqueConfig.nc b/tos/chips/rf230/UniqueConfig.nc deleted file mode 100644 index 5f14c521..00000000 --- a/tos/chips/rf230/UniqueConfig.nc +++ /dev/null @@ -1,48 +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 - -interface UniqueConfig -{ - /** - * Returns the sequence number of the packet. - */ - async command uint8_t getSequenceNumber(message_t* msg); - - /** - * Returns the sender of the packet. - */ - async command am_addr_t getSender(message_t* msg); - - /** - * Sets the sequence number of the packet. - */ - async command void setSequenceNumber(message_t*msg, uint8_t number); - - /** - * This command is called when the unqiue layer detects a missing (jump - * in the data sequence number) or a duplicate packet. - */ - tasklet_async command void reportChannelError(); -} diff --git a/tos/chips/rf230/UniqueLayerC.nc b/tos/chips/rf230/UniqueLayerC.nc deleted file mode 100644 index 5d2e5f23..00000000 --- a/tos/chips/rf230/UniqueLayerC.nc +++ /dev/null @@ -1,55 +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 UniqueLayerC -{ - provides - { - // NOTE, this is a combined layer, should be hooked up at two places - interface Send; - interface RadioReceive; - } - uses - { - interface Send as SubSend; - interface RadioReceive as SubReceive; - - interface UniqueConfig as Config; - } -} - -implementation -{ - components UniqueLayerP, MainC, NeighborhoodC, new NeighborhoodFlagC(); - - MainC.SoftwareInit -> UniqueLayerP; - UniqueLayerP.Neighborhood -> NeighborhoodC; - UniqueLayerP.NeighborhoodFlag -> NeighborhoodFlagC; - - Send = UniqueLayerP; - SubSend = UniqueLayerP; - - RadioReceive = UniqueLayerP; - SubReceive = UniqueLayerP; - Config = UniqueLayerP; -} diff --git a/tos/chips/rf230/UniqueLayerP.nc b/tos/chips/rf230/UniqueLayerP.nc deleted file mode 100644 index d341942e..00000000 --- a/tos/chips/rf230/UniqueLayerP.nc +++ /dev/null @@ -1,116 +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 UniqueLayerP -{ - provides - { - interface Send; - interface RadioReceive; - - interface Init; - } - - uses - { - interface Send as SubSend; - interface RadioReceive as SubReceive; - - interface UniqueConfig; - interface Neighborhood; - interface NeighborhoodFlag; - } -} - -implementation -{ - uint8_t sequenceNumber; - - command error_t Init.init() - { - sequenceNumber = TOS_NODE_ID << 4; - return SUCCESS; - } - - command error_t Send.send(message_t* msg, uint8_t len) - { - call UniqueConfig.setSequenceNumber(msg, ++sequenceNumber); - return call SubSend.send(msg, len); - } - - command error_t Send.cancel(message_t* msg) - { - return call SubSend.cancel(msg); - } - - event void SubSend.sendDone(message_t* msg, error_t error) - { - signal Send.sendDone(msg, error); - } - - command uint8_t Send.maxPayloadLength() - { - return call SubSend.maxPayloadLength(); - } - - command void* Send.getPayload(message_t* msg, uint8_t len) - { - return call SubSend.getPayload(msg, len); - } - - tasklet_async event bool SubReceive.header(message_t* msg) - { - // we could scan here, but better be lazy - return signal RadioReceive.header(msg); - } - - tasklet_norace uint8_t receivedNumbers[NEIGHBORHOOD_SIZE]; - - tasklet_async event message_t* SubReceive.receive(message_t* msg) - { - uint8_t index = call Neighborhood.insertNode(call UniqueConfig.getSender(msg)); - uint8_t dsn = call UniqueConfig.getSequenceNumber(msg); - - if( call NeighborhoodFlag.get(index) ) - { - uint8_t diff = dsn - receivedNumbers[index]; - - if( diff == 0 ) - { - call UniqueConfig.reportChannelError(); - return msg; - } - } - else - call NeighborhoodFlag.set(index); - - receivedNumbers[index] = dsn; - - return signal RadioReceive.receive(msg); - } - - tasklet_async event void Neighborhood.evicted(uint8_t index) { } -} diff --git a/tos/chips/rf2xx/layers/ActiveMessageConfig.nc b/tos/chips/rf2xx/layers/ActiveMessageConfig.nc new file mode 100755 index 00000000..e47f0e8b --- /dev/null +++ b/tos/chips/rf2xx/layers/ActiveMessageConfig.nc @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface ActiveMessageConfig +{ + /** + * This command is called when the message first enters the radio stack + * via the Send.send command. This should clear the packet if the user + * forgot to do so (or return EINVAL to be strict). + */ + command error_t checkPacket(message_t* msg); +} diff --git a/tos/chips/rf2xx/layers/ActiveMessageLayerC.nc b/tos/chips/rf2xx/layers/ActiveMessageLayerC.nc new file mode 100755 index 00000000..f635a9c6 --- /dev/null +++ b/tos/chips/rf2xx/layers/ActiveMessageLayerC.nc @@ -0,0 +1,107 @@ +/* + * 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 + */ + +module ActiveMessageLayerC +{ + provides + { + interface AMSend[am_id_t id]; + interface Receive[am_id_t id]; + interface Receive as Snoop[am_id_t id]; + } + uses + { + interface Send as SubSend; + interface Receive as SubReceive; + interface AMPacket; + interface ActiveMessageConfig as Config; + } +} + +implementation +{ +/*----------------- Send -----------------*/ + + command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len) + { + error_t error; + + error = call Config.checkPacket(msg); + if( error != SUCCESS ) + return error; + + call AMPacket.setSource(msg, call AMPacket.address()); + call AMPacket.setGroup(msg, call AMPacket.localGroup()); + call AMPacket.setType(msg, id); + call AMPacket.setDestination(msg, addr); + + return call SubSend.send(msg, len); + } + + inline event void SubSend.sendDone(message_t* msg, error_t error) + { + signal AMSend.sendDone[call AMPacket.type(msg)](msg, error); + } + + inline command error_t AMSend.cancel[am_id_t id](message_t* msg) + { + return call SubSend.cancel(msg); + } + + default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error) + { + } + + inline command uint8_t AMSend.maxPayloadLength[am_id_t id]() + { + return call SubSend.maxPayloadLength(); + } + + inline command void* AMSend.getPayload[am_id_t id](message_t* msg, uint8_t len) + { + return call SubSend.getPayload(msg, len); + } + +/*----------------- Receive -----------------*/ + + event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) + { + am_id_t type = call AMPacket.type(msg); + + msg = call AMPacket.isForMe(msg) + ? signal Receive.receive[type](msg, payload, len) + : signal Snoop.receive[type](msg, payload, len); + + return msg; + } + + default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) + { + return msg; + } + + default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) + { + return msg; + } +} diff --git a/tos/chips/rf2xx/layers/CsmaConfig.nc b/tos/chips/rf2xx/layers/CsmaConfig.nc new file mode 100755 index 00000000..9d453767 --- /dev/null +++ b/tos/chips/rf2xx/layers/CsmaConfig.nc @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface CsmaConfig +{ + /** + * This command is called when the message is transmitted to + * check if it needs software clear channel assesment. + */ + async command bool requiresSoftwareCCA(message_t* msg); +} diff --git a/tos/chips/rf2xx/layers/CsmaLayerC.nc b/tos/chips/rf2xx/layers/CsmaLayerC.nc new file mode 100755 index 00000000..e0ddc262 --- /dev/null +++ b/tos/chips/rf2xx/layers/CsmaLayerC.nc @@ -0,0 +1,47 @@ +/* + * 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 CsmaLayerC +{ + provides + { + interface RadioSend; + } + uses + { + interface RadioSend as SubSend; + interface RadioCCA as SubCCA; + + interface CsmaConfig as Config; + } +} + +implementation +{ + components CsmaLayerP; + + RadioSend = CsmaLayerP; + SubSend = CsmaLayerP; + SubCCA = CsmaLayerP; + Config = CsmaLayerP; +} diff --git a/tos/chips/rf2xx/layers/CsmaLayerP.nc b/tos/chips/rf2xx/layers/CsmaLayerP.nc new file mode 100755 index 00000000..5bd1aa41 --- /dev/null +++ b/tos/chips/rf2xx/layers/CsmaLayerP.nc @@ -0,0 +1,103 @@ +/* + * 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 CsmaLayerP +{ + provides + { + interface RadioSend; + } + + uses + { + interface CsmaConfig as Config; + + interface RadioSend as SubSend; + interface RadioCCA as SubCCA; + } +} + +implementation +{ + tasklet_norace message_t *txMsg; + + tasklet_norace uint8_t state; + enum + { + STATE_READY = 0, + STATE_CCA_WAIT = 1, + STATE_SEND = 2, + }; + + tasklet_async event void SubSend.ready() + { + if( state == STATE_READY ) + signal RadioSend.ready(); + } + + tasklet_async command error_t RadioSend.send(message_t* msg) + { + error_t error; + + if( state == STATE_READY ) + { + if( call Config.requiresSoftwareCCA(msg) ) + { + txMsg = msg; + + if( (error = call SubCCA.request()) == SUCCESS ) + state = STATE_CCA_WAIT; + } + else if( (error = call SubSend.send(msg)) == SUCCESS ) + state = STATE_SEND; + } + else + error = EBUSY; + + return error; + } + + tasklet_async event void SubCCA.done(error_t error) + { + ASSERT( state == STATE_CCA_WAIT ); + + if( error == SUCCESS && (error = call SubSend.send(txMsg)) == SUCCESS ) + state = STATE_SEND; + else + { + state = STATE_READY; + signal RadioSend.sendDone(EBUSY); + } + } + + tasklet_async event void SubSend.sendDone(error_t error) + { + ASSERT( state == STATE_SEND ); + + state = STATE_READY; + signal RadioSend.sendDone(error); + } +} diff --git a/tos/chips/rf2xx/layers/DummyConfig.nc b/tos/chips/rf2xx/layers/DummyConfig.nc new file mode 100755 index 00000000..c76631e6 --- /dev/null +++ b/tos/chips/rf2xx/layers/DummyConfig.nc @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface DummyConfig +{ + /** + * We need to put something here, but this is not going to get called + */ + async command void nothing(); +} diff --git a/tos/chips/rf2xx/layers/DummyLayerC.nc b/tos/chips/rf2xx/layers/DummyLayerC.nc new file mode 100644 index 00000000..e3c55dea --- /dev/null +++ b/tos/chips/rf2xx/layers/DummyLayerC.nc @@ -0,0 +1,70 @@ +/* + * 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 + */ + +generic configuration DummyLayerC() +{ + provides + { + interface SplitControl; + interface Send; + interface Receive; + interface LowPowerListening; + + interface RadioState; + interface RadioSend; + interface RadioReceive; + interface RadioCCA; + + interface DummyConfig as UnconnectedConfig; + } + + uses + { + interface RadioState as SubState; + interface RadioSend as SubRadioSend; + interface RadioReceive as SubRadioReceive; + interface RadioCCA as SubRadioCCA; + interface SplitControl as SubControl; + interface Send as SubSend; + interface Receive as SubReceive; + + interface DummyConfig as Config; + } +} + +implementation +{ + RadioState = SubState; + RadioSend = SubRadioSend; + RadioReceive = SubRadioReceive; + RadioCCA = SubRadioCCA; + + SplitControl = SubControl; + Send = SubSend; + Receive = SubReceive; + + Config = UnconnectedConfig; + + components DummyLayerP; + LowPowerListening = DummyLayerP.LowPowerListening; +} diff --git a/tos/chips/rf2xx/layers/DummyLayerP.nc b/tos/chips/rf2xx/layers/DummyLayerP.nc new file mode 100644 index 00000000..8ce32610 --- /dev/null +++ b/tos/chips/rf2xx/layers/DummyLayerP.nc @@ -0,0 +1,50 @@ +/* + * 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 + */ + +module DummyLayerP +{ + provides interface LowPowerListening; +} + +implementation +{ + command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { } + + command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; } + + command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { } + + command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; } + + command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { } + + command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; } + + command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { } + + command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; } + + command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; } + + command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; } +} diff --git a/tos/chips/rf2xx/layers/GenericTimeSyncMessage.h b/tos/chips/rf2xx/layers/GenericTimeSyncMessage.h new file mode 100644 index 00000000..6f2247ff --- /dev/null +++ b/tos/chips/rf2xx/layers/GenericTimeSyncMessage.h @@ -0,0 +1,33 @@ +/* + * 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 __GENERICTIMESYNCMESSAGE_H__ +#define __GENERICTIMESYNCMESSAGE_H__ + +// this value is sent in the air +typedef nx_int32_t timesync_relative_t; + +// this value is stored in memory +typedef uint32_t timesync_absolute_t; + +#endif//__GENERICTIMESYNCMESSAGE_H__ diff --git a/tos/chips/rf2xx/layers/GenericTimeSyncMessageC.nc b/tos/chips/rf2xx/layers/GenericTimeSyncMessageC.nc new file mode 100644 index 00000000..d684a83e --- /dev/null +++ b/tos/chips/rf2xx/layers/GenericTimeSyncMessageC.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 + */ + +#include +#include +#include + +configuration GenericTimeSyncMessageC +{ + 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; + } + + uses + { + interface PacketField as PacketTimeSyncOffset; + interface LocalTime as LocalTimeRadio; + } +} + +implementation +{ + components GenericTimeSyncMessageP, ActiveMessageC, LocalTimeMilliC; + + TimeSyncAMSendRadio = GenericTimeSyncMessageP; + TimeSyncPacketRadio = GenericTimeSyncMessageP; + + TimeSyncAMSendMilli = GenericTimeSyncMessageP; + TimeSyncPacketMilli = GenericTimeSyncMessageP; + + Packet = GenericTimeSyncMessageP; + GenericTimeSyncMessageP.SubSend -> ActiveMessageC.AMSend; + GenericTimeSyncMessageP.SubPacket -> ActiveMessageC.Packet; + + GenericTimeSyncMessageP.PacketTimeStampRadio -> ActiveMessageC; + GenericTimeSyncMessageP.PacketTimeStampMilli -> ActiveMessageC; + GenericTimeSyncMessageP.LocalTimeRadio = LocalTimeRadio; + GenericTimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC; + + GenericTimeSyncMessageP.PacketTimeSyncOffset = PacketTimeSyncOffset; + + SplitControl = ActiveMessageC; + Receive = ActiveMessageC.Receive; + Snoop = ActiveMessageC.Snoop; + AMPacket = ActiveMessageC; +} diff --git a/tos/chips/rf2xx/layers/GenericTimeSyncMessageP.nc b/tos/chips/rf2xx/layers/GenericTimeSyncMessageP.nc new file mode 100644 index 00000000..ba508ad7 --- /dev/null +++ b/tos/chips/rf2xx/layers/GenericTimeSyncMessageP.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 GenericTimeSyncMessageP +{ + 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()) << RADIO_ALARM_MILLI_EXP) + 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) >> RADIO_ALARM_MILLI_EXP) + call PacketTimeStampMilli.timestamp(msg); + } +} diff --git a/tos/chips/rf2xx/layers/IEEE154NetworkLayerC.nc b/tos/chips/rf2xx/layers/IEEE154NetworkLayerC.nc new file mode 100644 index 00000000..2cfd690e --- /dev/null +++ b/tos/chips/rf2xx/layers/IEEE154NetworkLayerC.nc @@ -0,0 +1,53 @@ +/* + * 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 IEEE154NetworkLayerC +{ + provides + { + interface SplitControl; + interface Send; + interface Receive; + } + uses + { + interface SplitControl as SubControl; + interface Send as SubSend; + interface Receive as SubReceive; + } +} + +implementation +{ + components IEEE154NetworkLayerP, IEEE154PacketC; + + SplitControl = SubControl; + + Send = IEEE154NetworkLayerP; + Receive = IEEE154NetworkLayerP; + + SubSend = IEEE154NetworkLayerP; + SubReceive = IEEE154NetworkLayerP; + + IEEE154NetworkLayerP.IEEE154Packet -> IEEE154PacketC; +} diff --git a/tos/chips/rf2xx/layers/IEEE154NetworkLayerP.nc b/tos/chips/rf2xx/layers/IEEE154NetworkLayerP.nc new file mode 100644 index 00000000..f4abf636 --- /dev/null +++ b/tos/chips/rf2xx/layers/IEEE154NetworkLayerP.nc @@ -0,0 +1,87 @@ +/* + * 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 + */ + +module IEEE154NetworkLayerP +{ + provides + { + interface Send; + interface Receive; + interface Receive as NonTinyosReceive[uint8_t network]; + } + + uses + { + interface Send as SubSend; + interface Receive as SubReceive; + + interface IEEE154Packet; + } +} + +implementation +{ +#ifndef TINYOS_6LOWPAN_NETWORK_ID +#define TINYOS_6LOWPAN_NETWORK_ID 0x3f +#endif + + command error_t Send.send(message_t* msg, uint8_t len) + { + call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID); + return call SubSend.send(msg, len); + } + + command error_t Send.cancel(message_t* msg) + { + return call SubSend.cancel(msg); + } + + command uint8_t Send.maxPayloadLength() + { + return call SubSend.maxPayloadLength(); + } + + command void* Send.getPayload(message_t* msg, uint8_t len) + { + return call SubSend.getPayload(msg, len); + } + + event void SubSend.sendDone(message_t* msg, error_t error) + { + signal Send.sendDone(msg, error); + } + + event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len) + { + uint8_t network = call IEEE154Packet.get6LowPan(msg); + if( network == TINYOS_6LOWPAN_NETWORK_ID ) + return signal Receive.receive(msg, payload, len); + else + return signal NonTinyosReceive.receive[network](msg, payload, len); + } + + default event message_t *NonTinyosReceive.receive[uint8_t network](message_t *msg, void *payload, uint8_t len) + { + return msg; + } +} diff --git a/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc b/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc new file mode 100644 index 00000000..b1efca25 --- /dev/null +++ b/tos/chips/rf2xx/layers/LowPowerListeningLayerC.nc @@ -0,0 +1,65 @@ +/* + * 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 + */ + +#warning "*** USING LOW POWER LISTENING LAYER" + +configuration LowPowerListeningLayerC +{ + provides + { + interface SplitControl; + interface Send; + interface Receive; + + interface LowPowerListening; + } + uses + { + interface SplitControl as SubControl; + interface Send as SubSend; + interface Receive as SubReceive; + + interface PacketField as PacketSleepInterval; + interface IEEE154Packet; + interface PacketAcknowledgements; + } +} + +implementation +{ + components LowPowerListeningLayerP, new TimerMilliC(); + + SplitControl = LowPowerListeningLayerP; + Send = LowPowerListeningLayerP; + Receive = LowPowerListeningLayerP; + LowPowerListening = LowPowerListeningLayerP; + + SubControl = LowPowerListeningLayerP; + SubSend = LowPowerListeningLayerP; + SubReceive = LowPowerListeningLayerP; + PacketSleepInterval = LowPowerListeningLayerP; + IEEE154Packet = LowPowerListeningLayerP; + PacketAcknowledgements = LowPowerListeningLayerP; + + LowPowerListeningLayerP.Timer -> TimerMilliC; +} diff --git a/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc b/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc new file mode 100644 index 00000000..ef4bac56 --- /dev/null +++ b/tos/chips/rf2xx/layers/LowPowerListeningLayerP.nc @@ -0,0 +1,443 @@ +/* + * 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 + +module LowPowerListeningLayerP +{ + provides + { + interface SplitControl; + interface Send; + interface Receive; + + interface LowPowerListening; + } + + uses + { + interface SplitControl as SubControl; + interface Send as SubSend; + interface Receive as SubReceive; + + interface PacketField as PacketSleepInterval; + interface IEEE154Packet; + interface PacketAcknowledgements; + interface Timer; + } +} + +implementation +{ + enum + { + // minimum wakeup time to catch a transmission in milliseconds + LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535 + + // extra wakeup time after receiving a message in milliseconds + AFTER_RECEIVE = 10U, + + // extra wakeup time after transmitting a message in milliseconds + AFTER_TRANSMIT = 10U, + + MIN_SLEEP = 2, // the minimum sleep interval in milliseconds + MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds + MIN_DUTY = 2, // the minimum duty cycle + }; + + uint16_t sleepInterval; + + message_t* txMsg; + uint8_t txLen; + error_t txError; + +/*----------------- state machine -----------------*/ + + enum + { + OFF = 0, + OFF_SUBSTOP = 1, // must have consecutive indices + OFF_SUBSTOP_DONE = 2, // must have consecutive indices + OFF_STOP_END = 3, // must have consecutive indices + OFF_START_END = 4, + + LISTEN_SUBSTART = 5, // must have consecutive indices + LISTEN_SUBSTART_DONE = 6, // must have consecutive indices + LISTEN_TIMER = 7, // must have consecutive indices + LISTEN = 8, // must have consecutive indices + + SLEEP_SUBSTOP = 9, // must have consecutive indices + SLEEP_SUBSTOP_DONE = 10, // must have consecutive indices + SLEEP_TIMER = 11, // must have consecutive indices + SLEEP = 12, // must have consecutive indices + + SEND_SUBSTART = 13, // must have consecutive indices + SEND_SUBSTART_DONE = 14, // must have consecutive indices + SEND_TIMER = 15, // must have consecutive indices + SEND_SUBSEND= 16, + SEND_SUBSEND_DONE = 17, + SEND_SUBSEND_DONE_LAST = 18, + SEND_DONE = 19, + }; + + uint8_t state; + + task void transition() + { + error_t error; + uint16_t transmitInterval; + + if( state == LISTEN_SUBSTART || state == SEND_SUBSTART ) + { + error = call SubControl.start(); + ASSERT( error == SUCCESS || error == EBUSY ); + + if( error == SUCCESS ) + ++state; + else + post transition(); + } + else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP ) + { + error = call SubControl.stop(); + ASSERT( error == SUCCESS || error == EBUSY ); + + if( error == SUCCESS ) + ++state; + else + post transition(); + } + else if( state == OFF_START_END ) + { + state = LISTEN_SUBSTART; + post transition(); + + signal SplitControl.startDone(SUCCESS); + } + else if( state == OFF_STOP_END ) + { + state = OFF; + signal SplitControl.stopDone(SUCCESS); + } + else if( state == LISTEN_TIMER ) + { + state = LISTEN; + if( sleepInterval > 0 ) + call Timer.startOneShot(LISTEN_WAKEUP); + } + else if( state == SLEEP_TIMER ) + { + if( sleepInterval > 0 ) + { + state = SLEEP; + call Timer.startOneShot(sleepInterval); + } + else + { + state = LISTEN_SUBSTART; + post transition(); + } + } + else if( state == SEND_TIMER ) + { + transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg); + + if( transmitInterval > 0 ) + call Timer.startOneShot(transmitInterval); + + state = SEND_SUBSEND; + post transition(); + } + else if( state == SEND_SUBSEND) + { + txError = call SubSend.send(txMsg, txLen); + + if( txError == SUCCESS ) + state = SEND_SUBSEND_DONE; + else + { + state = SEND_DONE; + post transition(); + } + } + else if( state == SEND_DONE ) + { + state = LISTEN; + if( sleepInterval > 0 ) + call Timer.startOneShot(AFTER_TRANSMIT); + + signal Send.sendDone(txMsg, txError); + } + } + + command error_t SplitControl.start() + { + if( state == OFF_START_END ) + return EBUSY; + else if( state != OFF ) + return EALREADY; + + state = OFF_START_END; + post transition(); + + return SUCCESS; + } + + event void SubControl.startDone(error_t error) + { + ASSERT( error == SUCCESS || error == EBUSY ); + ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE ); + + if( error == SUCCESS ) + ++state; + else + --state; + + post transition(); + } + + command error_t SplitControl.stop() + { + if( state == SLEEP || state == LISTEN ) + { + call Timer.stop(); + post transition(); + } + + if( state == LISTEN_TIMER || state == LISTEN || state == SLEEP_SUBSTOP ) + state = OFF_SUBSTOP; + else if( state == SLEEP_SUBSTOP_DONE ) + state = OFF_SUBSTOP_DONE; + else if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP ) + state = OFF_STOP_END; + else if( state == OFF ) + return EALREADY; + else + return EBUSY; + + return SUCCESS; + } + + event void SubControl.stopDone(error_t error) + { + ASSERT( error == SUCCESS || error == EBUSY ); + ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE ); + + if( error == SUCCESS ) + ++state; + else + --state; + + post transition(); + } + + event void Timer.fired() + { + ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND || state == SEND_SUBSEND_DONE ); + + if( state == LISTEN ) + state = SLEEP_SUBSTOP; + else if( state == SLEEP ) + state = LISTEN_SUBSTART; + else if( state == SEND_SUBSEND_DONE ) + state = SEND_SUBSEND_DONE_LAST; + else if( state == SEND_SUBSEND) + state = SEND_DONE; + + post transition(); + } + + event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) + { + if( state == SLEEP_SUBSTOP ) + state = LISTEN; + + if( state == LISTEN && sleepInterval > 0 ) + call Timer.startOneShot(AFTER_RECEIVE); + + return signal Receive.receive(msg, payload, len); + } + + command error_t Send.send(message_t* msg, uint8_t len) + { + if( state == LISTEN || state == SLEEP ) + { + call Timer.stop(); + post transition(); + } + + if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP ) + state = SEND_SUBSTART; + else if( state == LISTEN_SUBSTART_DONE ) + state = SEND_SUBSTART_DONE; + else if( state == LISTEN_TIMER || state == SLEEP_SUBSTOP || state == LISTEN ) + state = SEND_TIMER; + else + return EBUSY; + + txMsg = msg; + txLen = len; + txError = FAIL; + + return SUCCESS; + } + + command error_t Send.cancel(message_t* msg) + { + if( state == SEND_SUBSEND ) + { + call Timer.stop(); + state = SEND_DONE; + txError = ECANCEL; + post transition(); + + return SUCCESS; + } + else if( state == SEND_SUBSEND_DONE ) + { + // we stop sending the message even if SubSend.cancel was not succesfull + state = SEND_SUBSEND_DONE_LAST; + + return call SubSend.cancel(txMsg); + } + else + return FAIL; + } + + event void SubSend.sendDone(message_t* msg, error_t error) + { + ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST ); + ASSERT( msg == txMsg ); + + txError = error; + + // TODO: extend the PacketAcknowledgements interface with getAckRequired + if( error != SUCCESS + || call LowPowerListening.getRxSleepInterval(msg) == 0 + || state == SEND_SUBSEND_DONE_LAST + || (call IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) ) + { + call Timer.stop(); + state = SEND_DONE; + } + else + state = SEND_SUBSEND; + + post transition(); + } + + command uint8_t Send.maxPayloadLength() + { + return call SubSend.maxPayloadLength(); + } + + command void* Send.getPayload(message_t* msg, uint8_t len) + { + return call SubSend.getPayload(msg, len); + } + +/*----------------- LowPowerListening -----------------*/ + + command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) + { + if( dutyCycle >= 10000 ) + return 0; + else if( dutyCycle <= MIN_DUTY ) + return MAX_SLEEP; + + return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP; + } + + command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval) + { + if( interval < MIN_SLEEP ) + return 10000; + else if( interval >= MAX_SLEEP ) + return MIN_DUTY; + + return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval); + } + + command void LowPowerListening.setLocalSleepInterval(uint16_t interval) + { + if( interval < MIN_SLEEP ) + interval = 0; + else if( interval > MAX_SLEEP ) + interval = MAX_SLEEP; + + sleepInterval = interval; + + if( (state == LISTEN && sleepInterval == 0) || state == SLEEP ) + { + call Timer.stop(); + --state; + post transition(); + } + } + + command uint16_t LowPowerListening.getLocalSleepInterval() + { + return sleepInterval; + } + + command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) + { + call LowPowerListening.setLocalSleepInterval( + call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); + } + + command uint16_t LowPowerListening.getLocalDutyCycle() + { + return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval); + } + + command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval) + { + if( interval < MIN_SLEEP ) + interval = 0; + else if( interval > MAX_SLEEP ) + interval = MAX_SLEEP; + + call PacketSleepInterval.set(msg, interval); + } + + command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) + { + if( ! call PacketSleepInterval.isSet(msg) ) + return sleepInterval; + + return call PacketSleepInterval.get(msg); + } + + command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) + { + call LowPowerListening.setRxSleepInterval(msg, + call LowPowerListening.dutyCycleToSleepInterval(dutyCycle)); + } + + command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) + { + return call LowPowerListening.sleepIntervalToDutyCycle( + call LowPowerListening.getRxSleepInterval(msg)); + } +} diff --git a/tos/chips/rf2xx/layers/MessageBufferLayerC.nc b/tos/chips/rf2xx/layers/MessageBufferLayerC.nc new file mode 100644 index 00000000..90402c35 --- /dev/null +++ b/tos/chips/rf2xx/layers/MessageBufferLayerC.nc @@ -0,0 +1,60 @@ +/* + * 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 MessageBufferLayerC +{ + provides + { + interface SplitControl; + interface Send; + interface Receive; + interface RadioChannel; + } + uses + { + interface RadioState; + interface RadioSend; + interface RadioReceive; + + interface Packet; + } +} + +implementation +{ + components MessageBufferLayerP, MainC, TaskletC; + + MainC.SoftwareInit -> MessageBufferLayerP; + + SplitControl = MessageBufferLayerP; + Send = MessageBufferLayerP; + Receive = MessageBufferLayerP; + RadioChannel = MessageBufferLayerP; + + RadioState = MessageBufferLayerP; + MessageBufferLayerP.Tasklet -> TaskletC; + RadioSend = MessageBufferLayerP; + RadioReceive = MessageBufferLayerP; + + Packet = MessageBufferLayerP; +} diff --git a/tos/chips/rf2xx/layers/MessageBufferLayerP.nc b/tos/chips/rf2xx/layers/MessageBufferLayerP.nc new file mode 100644 index 00000000..374edaad --- /dev/null +++ b/tos/chips/rf2xx/layers/MessageBufferLayerP.nc @@ -0,0 +1,360 @@ +/* + * 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 MessageBufferLayerP +{ + provides + { + interface SplitControl; + interface Init as SoftwareInit; + + interface Send; + interface Receive; + interface RadioChannel; + } + uses + { + interface RadioState; + interface Tasklet; + interface RadioSend; + interface RadioReceive; + + interface Packet; + } +} + +implementation +{ +/*----------------- State -----------------*/ + + norace uint8_t state; // written only from tasks + enum + { + STATE_READY = 0, + STATE_TX_PENDING = 1, + STATE_TX_SEND = 2, + STATE_TX_DONE = 3, + STATE_TURN_ON = 4, + STATE_TURN_OFF = 5, + STATE_CHANNEL = 6, + }; + + command error_t SplitControl.start() + { + error_t error; + + call Tasklet.suspend(); + + if( state != STATE_READY ) + error = EBUSY; + else + error = call RadioState.turnOn(); + + if( error == SUCCESS ) + state = STATE_TURN_ON; + + call Tasklet.resume(); + + return error; + } + + command error_t SplitControl.stop() + { + error_t error; + + call Tasklet.suspend(); + + if( state != STATE_READY ) + error = EBUSY; + else + error = call RadioState.turnOff(); + + if( error == SUCCESS ) + state = STATE_TURN_OFF; + + call Tasklet.resume(); + + return error; + } + + command error_t RadioChannel.setChannel(uint8_t channel) + { + error_t error; + + call Tasklet.suspend(); + + if( state != STATE_READY ) + error = EBUSY; + else + error = call RadioState.setChannel(channel); + + if( error == SUCCESS ) + state = STATE_CHANNEL; + + call Tasklet.resume(); + + return error; + } + + command uint8_t RadioChannel.getChannel() + { + return call RadioState.getChannel(); + } + + task void stateDoneTask() + { + uint8_t s; + + s = state; + + // change the state before so we can be reentered from the event + state = STATE_READY; + + if( s == STATE_TURN_ON ) + signal SplitControl.startDone(SUCCESS); + else if( s == STATE_TURN_OFF ) + signal SplitControl.stopDone(SUCCESS); + else if( s == STATE_CHANNEL ) + signal RadioChannel.setChannelDone(); + else // not our event, ignore it + state = s; + } + + tasklet_async event void RadioState.done() + { + post stateDoneTask(); + } + + default event void SplitControl.startDone(error_t error) + { + } + + default event void SplitControl.stopDone(error_t error) + { + } + + default event void RadioChannel.setChannelDone() + { + } + +/*----------------- Send -----------------*/ + + message_t* txMsg; + error_t txError; + uint8_t retries; + + // Many EBUSY replies from RadioSend are normal if the channel is cognested + enum { MAX_RETRIES = 5 }; + + task void sendTask() + { + error_t error; + + ASSERT( state == STATE_TX_PENDING || state == STATE_TX_SEND ); + + atomic error = txError; + if( (state == STATE_TX_SEND && error == SUCCESS) || ++retries > MAX_RETRIES ) + state = STATE_TX_DONE; + else + { + call Tasklet.suspend(); + + error = call RadioSend.send(txMsg); + if( error == SUCCESS ) + state = STATE_TX_SEND; + else if( retries == MAX_RETRIES ) + state = STATE_TX_DONE; + else + state = STATE_TX_PENDING; + + call Tasklet.resume(); + } + + if( state == STATE_TX_DONE ) + { + state = STATE_READY; + signal Send.sendDone(txMsg, error); + } + } + + tasklet_async event void RadioSend.sendDone(error_t error) + { + ASSERT( state == STATE_TX_SEND ); + + atomic txError = error; + post sendTask(); + } + + command error_t Send.send(message_t* msg, uint8_t len) + { + if( len > call Packet.maxPayloadLength() ) + return EINVAL; + else if( state != STATE_READY ) + return EBUSY; + + call Packet.setPayloadLength(msg, len); + + txMsg = msg; + state = STATE_TX_PENDING; + retries = 0; + post sendTask(); + + return SUCCESS; + } + + tasklet_async event void RadioSend.ready() + { + if( state == STATE_TX_PENDING ) + post sendTask(); + } + + tasklet_async event void Tasklet.run() + { + } + + command error_t Send.cancel(message_t* msg) + { + if( state == STATE_TX_PENDING ) + { + state = STATE_READY; + + // TODO: check if sendDone can be called before cancel returns + signal Send.sendDone(msg, ECANCEL); + + return SUCCESS; + } + else + return FAIL; + } + + default event void Send.sendDone(message_t* msg, error_t error) + { + } + + inline command uint8_t Send.maxPayloadLength() + { + return call Packet.maxPayloadLength(); + } + + inline command void* Send.getPayload(message_t* msg, uint8_t len) + { + return call Packet.getPayload(msg, len); + } + +/*----------------- Receive -----------------*/ + + enum + { + RECEIVE_QUEUE_SIZE = 3, + }; + + message_t receiveQueueData[RECEIVE_QUEUE_SIZE]; + message_t* receiveQueue[RECEIVE_QUEUE_SIZE]; + + uint8_t receiveQueueHead; + uint8_t receiveQueueSize; + + command error_t SoftwareInit.init() + { + uint8_t i; + + for(i = 0; i < RECEIVE_QUEUE_SIZE; ++i) + receiveQueue[i] = receiveQueueData + i; + + return SUCCESS; + } + + tasklet_async event bool RadioReceive.header(message_t* msg) + { + bool notFull; + + // this prevents undeliverable messages to be acknowledged + atomic notFull = receiveQueueSize < RECEIVE_QUEUE_SIZE; + + return notFull; + } + + task void deliverTask() + { + // get rid of as many messages as possible without interveining tasks + for(;;) + { + message_t* msg; + + atomic + { + if( receiveQueueSize == 0 ) + return; + + msg = receiveQueue[receiveQueueHead]; + } + + msg = signal Receive.receive(msg, + call Packet.getPayload(msg, call Packet.maxPayloadLength()), + call Packet.payloadLength(msg)); + + atomic + { + receiveQueue[receiveQueueHead] = msg; + + if( ++receiveQueueHead >= RECEIVE_QUEUE_SIZE ) + receiveQueueHead = 0; + + --receiveQueueSize; + } + } + } + + tasklet_async event message_t* RadioReceive.receive(message_t* msg) + { + message_t *m; + + atomic + { + if( receiveQueueSize >= RECEIVE_QUEUE_SIZE ) + m = msg; + else + { + uint8_t index = receiveQueueHead + receiveQueueSize; + if( index >= RECEIVE_QUEUE_SIZE ) + index -= RECEIVE_QUEUE_SIZE; + + m = receiveQueue[index]; + receiveQueue[index] = msg; + + ++receiveQueueSize; + post deliverTask(); + } + } + + return m; + } + + default event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len) + { + return msg; + } +} diff --git a/tos/chips/rf2xx/layers/RandomCollisionConfig.nc b/tos/chips/rf2xx/layers/RandomCollisionConfig.nc new file mode 100755 index 00000000..b12cc692 --- /dev/null +++ b/tos/chips/rf2xx/layers/RandomCollisionConfig.nc @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface RandomCollisionConfig +{ + /** + * Returns the initial amount of maximum backoff for this message. + */ + async command uint16_t getInitialBackoff(message_t* msg); + + /** + * Returns the amount of maximum backoff when there is congestion + * (the channel was busy for the first try) + */ + async command uint16_t getCongestionBackoff(message_t* msg); + + /** + * Returns the minimum ticks before the message could be sent. + */ + async command uint16_t getMinimumBackoff(); + + /** + * The provided message was just received, and this command should return + * the time till no transmission should be initiated. + */ + async command uint16_t getTransmitBarrier(message_t* msg); +} diff --git a/tos/chips/rf2xx/layers/RandomCollisionLayerC.nc b/tos/chips/rf2xx/layers/RandomCollisionLayerC.nc new file mode 100755 index 00000000..ba7ad054 --- /dev/null +++ b/tos/chips/rf2xx/layers/RandomCollisionLayerC.nc @@ -0,0 +1,51 @@ +/* + * 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 RandomCollisionLayerC +{ + provides + { + interface RadioSend; + interface RadioReceive; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface RandomCollisionConfig as Config; + } +} + +implementation +{ + components RandomCollisionLayerP, RadioAlarmC, RandomC; + + RadioSend = RandomCollisionLayerP; + SubSend = RandomCollisionLayerP; + Config = RandomCollisionLayerP; + RadioReceive = RandomCollisionLayerP; + SubReceive = RandomCollisionLayerP; + + RandomCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; + RandomCollisionLayerP.Random -> RandomC; +} diff --git a/tos/chips/rf2xx/layers/RandomCollisionLayerP.nc b/tos/chips/rf2xx/layers/RandomCollisionLayerP.nc new file mode 100755 index 00000000..c53d1b91 --- /dev/null +++ b/tos/chips/rf2xx/layers/RandomCollisionLayerP.nc @@ -0,0 +1,177 @@ +/* + * 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 RandomCollisionLayerP +{ + provides + { + interface RadioSend; + interface RadioReceive; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface RadioAlarm; + interface Random; + interface RandomCollisionConfig as Config; + } +} + +implementation +{ + tasklet_norace uint8_t state; + enum + { + STATE_READY = 0, + STATE_TX_PENDING_FIRST = 1, + STATE_TX_PENDING_SECOND = 2, + STATE_TX_SENDING = 3, + + STATE_BARRIER = 0x80, + }; + + tasklet_norace message_t *txMsg; + tasklet_norace uint16_t txBarrier; + + tasklet_async event void SubSend.ready() + { + if( state == STATE_READY && call RadioAlarm.isFree() ) + signal RadioSend.ready(); + } + + uint16_t nextRandom; + task void calcNextRandom() + { + uint16_t a = call Random.rand16(); + atomic nextRandom = a; + } + + uint16_t getBackoff(uint16_t maxBackoff) + { + uint16_t a; + + atomic + { + a = nextRandom; + nextRandom += 273; + } + post calcNextRandom(); + + return (a % maxBackoff) + call Config.getMinimumBackoff(); + } + + tasklet_async command error_t RadioSend.send(message_t* msg) + { + if( state != STATE_READY || ! call RadioAlarm.isFree() ) + return EBUSY; + + txMsg = msg; + state = STATE_TX_PENDING_FIRST; + call RadioAlarm.wait(getBackoff(call Config.getInitialBackoff(msg))); + + return SUCCESS; + } + + tasklet_async event void RadioAlarm.fired() + { + error_t error; + int16_t delay; + + ASSERT( state != STATE_READY ); + + delay = (int16_t)txBarrier - call RadioAlarm.getNow(); + + if( state == STATE_BARRIER ) + { + state = STATE_READY; + + signal RadioSend.ready(); + return; + } + else if( (state & STATE_BARRIER) && delay > 0 ) + error = EBUSY; + else + error = call SubSend.send(txMsg); + + if( error != SUCCESS ) + { + if( (state & ~STATE_BARRIER) == STATE_TX_PENDING_FIRST ) + { + state = (state & STATE_BARRIER) | STATE_TX_PENDING_SECOND; + call RadioAlarm.wait(getBackoff(call Config.getCongestionBackoff(txMsg))); + } + else + { + if( (state & STATE_BARRIER) && delay > 0 ) + { + state = STATE_BARRIER; + call RadioAlarm.wait(delay); + } + else + state = STATE_READY; + + signal RadioSend.sendDone(error); + } + } + else + state = STATE_TX_SENDING; + } + + tasklet_async event void SubSend.sendDone(error_t error) + { + ASSERT( state == STATE_TX_SENDING ); + + state = STATE_READY; + signal RadioSend.sendDone(error); + } + + tasklet_async event bool SubReceive.header(message_t* msg) + { + return signal RadioReceive.header(msg); + } + + tasklet_async event message_t* SubReceive.receive(message_t* msg) + { + int16_t delay; + + txBarrier = call Config.getTransmitBarrier(msg); + delay = txBarrier - call RadioAlarm.getNow(); + + if( delay > 0 ) + { + if( state == STATE_READY ) + { + call RadioAlarm.wait(delay); + state = STATE_BARRIER; + } + else + state |= STATE_BARRIER; + } + + return signal RadioReceive.receive(msg); + } +} diff --git a/tos/chips/rf2xx/layers/SlottedCollisionConfig.nc b/tos/chips/rf2xx/layers/SlottedCollisionConfig.nc new file mode 100755 index 00000000..4b6b9931 --- /dev/null +++ b/tos/chips/rf2xx/layers/SlottedCollisionConfig.nc @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface SlottedCollisionConfig +{ + /** + * This command should return the approximate transmit delay between + * setting an alarm, waiting for the fire event, calling send and + * obtaining the timestamp for the transmitted message. + */ + async command uint16_t getInitialDelay(); + + /** + * Must return a binary exponent so that the collision avoidance layer + * can assign slots in the range of [0, 1 << exponent) of size collision + * window. + */ + async command uint8_t getScheduleExponent(); + + /** + * This command must return the time when the message was transmitted. + */ + async command uint16_t getTransmitTime(message_t* msg); + + /** + * Returns the start of the collision window for this received message, + * so transmit times in this range would be considered possible collisions. + */ + async command uint16_t getCollisionWindowStart(message_t* msg); + + /** + * Returns the size of the collision window for this received message. + */ + async command uint16_t getCollisionWindowLength(message_t* msg); + + /** + * This event should be called periodically to indicate the passing of + * time (maybe we should use a timer) + */ + tasklet_async event void timerTick(); +} diff --git a/tos/chips/rf2xx/layers/SlottedCollisionLayerC.nc b/tos/chips/rf2xx/layers/SlottedCollisionLayerC.nc new file mode 100644 index 00000000..5a6502b3 --- /dev/null +++ b/tos/chips/rf2xx/layers/SlottedCollisionLayerC.nc @@ -0,0 +1,57 @@ +/* + * 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 SlottedCollisionLayerC +{ + provides + { + interface RadioSend; + interface RadioReceive; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface SlottedCollisionConfig as Config; + } +} + +implementation +{ + components SlottedCollisionLayerP, MainC, RadioAlarmC, RandomC; + + RadioSend = SlottedCollisionLayerP; + RadioReceive = SlottedCollisionLayerP; + SubSend = SlottedCollisionLayerP; + SubReceive = SlottedCollisionLayerP; + Config = SlottedCollisionLayerP; + + SlottedCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; + SlottedCollisionLayerP.Random -> RandomC; + MainC.SoftwareInit -> SlottedCollisionLayerP; + +#ifdef RADIO_DEBUG + components DiagMsgC; + SlottedCollisionLayerP.DiagMsg -> DiagMsgC; +#endif +} diff --git a/tos/chips/rf2xx/layers/SlottedCollisionLayerP.nc b/tos/chips/rf2xx/layers/SlottedCollisionLayerP.nc new file mode 100644 index 00000000..500fef86 --- /dev/null +++ b/tos/chips/rf2xx/layers/SlottedCollisionLayerP.nc @@ -0,0 +1,275 @@ +/* + * 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 SlottedCollisionLayerP +{ + provides + { + interface RadioSend; + interface RadioReceive; + interface Init; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface RadioAlarm; + interface Random; + interface SlottedCollisionConfig as Config; +#ifdef RADIO_DEBUG + interface DiagMsg; +#endif + } +} + +implementation +{ +/* ----- random ----- */ + + uint16_t nextRandom; + + task void calcNextRandom() + { + uint16_t a = call Random.rand16(); + atomic nextRandom = a; + } + + uint16_t getNextRandom() + { + uint16_t a; + + atomic + { + a = nextRandom; + nextRandom += 273; + } + post calcNextRandom(); + + return a; + } + +/* ----- schedule selection ----- */ + + tasklet_async event bool SubReceive.header(message_t* msg) + { + return signal RadioReceive.header(msg); + } + + // WARNING!!! Do not change these values, the error values can overflow + enum + { + ERROR_DECAY = 3, + ERROR_SWITCH = 30, // should be a multiple of (1 << decay) + ERROR_COLLISION = 20, // must be less than (255 - switch) >> decay + ERROR_BUSY = 1, // must be less than collision + ERROR_INITIAL = 80, // must be less than giveup + ERROR_GIVEUP = 120, // must be less than collision * (1 << decay) + ERROR_REPRESS = 40, // must be more than switch + ERROR_MAX = 255, + }; + + /** + * Returns TRUE if time is between start and start + window + * modulo the schedule size of (1 << exponent) + */ + inline bool isBetween(uint8_t exponent, uint16_t time, uint16_t start, uint16_t length) + { + return (uint16_t)((time - start) & ((1 << exponent) - 1)) < length; + } + + tasklet_norace uint16_t schedule1; + tasklet_norace uint16_t schedule2; + + tasklet_norace uint8_t error1; + tasklet_norace uint8_t error2; + + tasklet_async event message_t* SubReceive.receive(message_t* msg) + { + uint8_t exponent = call Config.getScheduleExponent(); + uint16_t start = call Config.getCollisionWindowStart(msg); + uint16_t length = call Config.getCollisionWindowLength(msg); + + error1 -= error1 >> ERROR_DECAY; + if( isBetween(exponent, schedule1, start, length) ) + error1 += ERROR_COLLISION; + + error2 -= error2 >> ERROR_DECAY; + if( isBetween(exponent, schedule2, start, length) ) + error2 += ERROR_COLLISION; + + if( error2 + ERROR_SWITCH <= error1 ) + { + error1 = error2; + schedule1 = schedule2; + error2 = ERROR_GIVEUP; + } + + if( error2 >= ERROR_GIVEUP ) + { + error2 = ERROR_INITIAL; + schedule2 = getNextRandom(); + } + + return signal RadioReceive.receive(msg); + } + + void printStats(); + + tasklet_async event void Config.timerTick() + { + if( error1 >= (1 << ERROR_DECAY) ) + error1 -= error1 >> ERROR_DECAY; + else if( error1 > 0 ) + --error1; + + if( error2 >= (1 << ERROR_DECAY) ) + error2 -= error2 >> ERROR_DECAY; + else if( error2 > 0 ) + --error2; + + printStats(); + } + +/* ------ transmit ------ */ + + tasklet_norace uint8_t state; + enum + { + STATE_READY = 0, + STATE_PENDING = 1, + STATE_SENDING = 2, + }; + + enum { DELAY_DECAY = 2 }; + + tasklet_norace message_t *txMsg; + tasklet_norace uint16_t txDelay; // the averaged delay between schedule and timestamp + tasklet_norace uint16_t txTime; // the schedule time of transmission + + tasklet_async event void SubSend.ready() + { + if( state == STATE_READY && call RadioAlarm.isFree() ) + signal RadioSend.ready(); + } + + tasklet_async command error_t RadioSend.send(message_t* msg) + { + uint16_t backoff; + uint16_t time; + + // TODO: we could supress transmission while error is large + if( state != STATE_READY || ! call RadioAlarm.isFree() || error1 >= ERROR_REPRESS ) + return EBUSY; + + txMsg = msg; + state = STATE_PENDING; + + time = call RadioAlarm.getNow(); + backoff = 1 + ((schedule1 - time - (txDelay >> DELAY_DECAY)) + & ((1 << call Config.getScheduleExponent()) - 1)); + + backoff += getNextRandom() & (3 << call Config.getScheduleExponent()); + + call RadioAlarm.wait(backoff); + txTime = time + backoff; + + return SUCCESS; + } + + tasklet_async event void RadioAlarm.fired() + { + error_t error; + + ASSERT( state == STATE_PENDING ); + + error = call SubSend.send(txMsg); + if( error == SUCCESS ) + state = STATE_SENDING; + else + { + if( error2 + ERROR_SWITCH <= error1 ) + { + error1 = error2; + schedule1 = schedule2; + error2 = ERROR_INITIAL; + schedule2 = getNextRandom(); + } + else if( error1 < ERROR_MAX - ERROR_BUSY ) + error1 = error1 + ERROR_BUSY; + + state = STATE_READY; + signal RadioSend.sendDone(error); + } + } + + tasklet_async event void SubSend.sendDone(error_t error) + { + ASSERT( state == STATE_SENDING ); + + if( error == SUCCESS ) + { + txDelay += (call Config.getTransmitTime(txMsg) - txTime) - (txDelay >> DELAY_DECAY); + + ASSERT( (txDelay >> DELAY_DECAY) < (1 << call Config.getScheduleExponent()) ); + } + + state = STATE_READY; + signal RadioSend.sendDone(error); + } + +/* ------ init ------ */ + + command error_t Init.init() + { + // do not use Random here because it might not be initialized + schedule1 = (uint16_t)(TOS_NODE_ID * 1973); + schedule2 = schedule1 + 0117; + txDelay = call Config.getInitialDelay() << DELAY_DECAY; + + return SUCCESS; + } + +#ifdef RADIO_DEBUG + tasklet_norace uint8_t count; + void printStats() + { + if( ++count > 10 && call DiagMsg.record() ) + { + count = 0; + + call DiagMsg.str("slotted"); + call DiagMsg.uint16(txDelay >> DELAY_DECAY); + call DiagMsg.uint16(schedule1); + call DiagMsg.uint8(error1); + call DiagMsg.uint16(schedule2); + call DiagMsg.uint8(error2); + call DiagMsg.send(); + } + } +#else + void printStats() { } +#endif +} diff --git a/tos/chips/rf2xx/layers/SoftwareAckConfig.nc b/tos/chips/rf2xx/layers/SoftwareAckConfig.nc new file mode 100755 index 00000000..b3c87c73 --- /dev/null +++ b/tos/chips/rf2xx/layers/SoftwareAckConfig.nc @@ -0,0 +1,75 @@ +/* + * 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 + +interface SoftwareAckConfig +{ + /** + * Returns the acknowledgement timeout (in the radio clock units), + * in which a sent packet must be acknowledged. + */ + async command uint16_t getAckTimeout(); + + /** + * Returns TRUE if the layer should wait for a software acknowledgement + * to be received after this packet was transmitted. + */ + async command bool requiresAckWait(message_t* msg); + + /** + * Sets for the transmitted message whether it was acknowledged or not. + */ + async command void setAckReceived(message_t* msg, bool acked); + + /** + * Returns TRUE if the received packet is an acknowledgement packet. + * The AckedSend layer will filter out all received acknowledgement + * packets and uses only the matching one for the acknowledgement. + */ + async command bool isAckPacket(message_t* msg); + + /** + * Returns TRUE if the acknowledgement packet corresponds to the + * data packet. The acknowledgement packect was already verified + * to be a valid acknowledgement packet via the isAckPacket command. + */ + async command bool verifyAckPacket(message_t* data, message_t* ack); + + /** + * Returns TRUE if the received packet needs software acknowledgements + * to be sent back to the sender. + */ + async command bool requiresAckReply(message_t* msg); + + /** + * Creates an acknowledgement packet for the given data packet. + */ + async command void createAckPacket(message_t* data, message_t* ack); + + /** + * This command is called when a sent packet did not receive an + * acknowledgement. + */ + tasklet_async command void reportChannelError(); +} diff --git a/tos/chips/rf2xx/layers/SoftwareAckLayerC.nc b/tos/chips/rf2xx/layers/SoftwareAckLayerC.nc new file mode 100755 index 00000000..97703e1f --- /dev/null +++ b/tos/chips/rf2xx/layers/SoftwareAckLayerC.nc @@ -0,0 +1,51 @@ +/* + * 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 SoftwareAckLayerC +{ + provides + { + interface RadioSend; + interface RadioReceive; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + + interface SoftwareAckConfig as Config; + } +} + +implementation +{ + components SoftwareAckLayerP, RadioAlarmC; + + RadioSend = SoftwareAckLayerP; + RadioReceive = SoftwareAckLayerP; + SubSend = SoftwareAckLayerP; + SubReceive = SoftwareAckLayerP; + Config = SoftwareAckLayerP; + + SoftwareAckLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; +} diff --git a/tos/chips/rf2xx/layers/SoftwareAckLayerP.nc b/tos/chips/rf2xx/layers/SoftwareAckLayerP.nc new file mode 100644 index 00000000..02ca70de --- /dev/null +++ b/tos/chips/rf2xx/layers/SoftwareAckLayerP.nc @@ -0,0 +1,161 @@ +/* + * 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 SoftwareAckLayerP +{ + provides + { + interface RadioSend; + interface RadioReceive; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface RadioAlarm; + + interface SoftwareAckConfig; + } +} + +implementation +{ + tasklet_norace uint8_t state; + enum + { + STATE_READY = 0, + STATE_DATA_SEND = 1, + STATE_ACK_WAIT = 2, + STATE_ACK_SEND = 3, + }; + + tasklet_norace message_t *txMsg; + tasklet_norace message_t ackMsg; + + tasklet_async event void SubSend.ready() + { + if( state == STATE_READY ) + signal RadioSend.ready(); + } + + tasklet_async command error_t RadioSend.send(message_t* msg) + { + error_t error; + + if( state == STATE_READY ) + { + if( (error = call SubSend.send(msg)) == SUCCESS ) + { + call SoftwareAckConfig.setAckReceived(msg, FALSE); + state = STATE_DATA_SEND; + txMsg = msg; + } + } + else + error = EBUSY; + + return error; + } + + tasklet_async event void SubSend.sendDone(error_t error) + { + if( state == STATE_ACK_SEND ) + { + // TODO: what if error != SUCCESS + ASSERT( error == SUCCESS ); + + state = STATE_READY; + } + else + { + ASSERT( state == STATE_DATA_SEND ); + ASSERT( call RadioAlarm.isFree() ); + + if( error == SUCCESS && call SoftwareAckConfig.requiresAckWait(txMsg) && call RadioAlarm.isFree() ) + { + call RadioAlarm.wait(call SoftwareAckConfig.getAckTimeout()); + state = STATE_ACK_WAIT; + } + else + { + state = STATE_READY; + signal RadioSend.sendDone(error); + } + } + } + + tasklet_async event void RadioAlarm.fired() + { + ASSERT( state == STATE_ACK_WAIT ); + + call SoftwareAckConfig.reportChannelError(); + + state = STATE_READY; + signal RadioSend.sendDone(SUCCESS); // we have sent it, but not acked + } + + tasklet_async event bool SubReceive.header(message_t* msg) + { + if( call SoftwareAckConfig.isAckPacket(msg) ) + return state == STATE_ACK_WAIT && call SoftwareAckConfig.verifyAckPacket(txMsg, msg); + else + return signal RadioReceive.header(msg); + } + + tasklet_async event message_t* SubReceive.receive(message_t* msg) + { + bool ack = call SoftwareAckConfig.isAckPacket(msg); + + ASSERT( state == STATE_ACK_WAIT || state == STATE_READY ); + + if( state == STATE_ACK_WAIT ) + { + ASSERT( !ack || call SoftwareAckConfig.verifyAckPacket(txMsg, msg) ); + + call RadioAlarm.cancel(); + call SoftwareAckConfig.setAckReceived(txMsg, ack); + + state = STATE_READY; + signal RadioSend.sendDone(SUCCESS); + } + + if( ack ) + return msg; + + if( call SoftwareAckConfig.requiresAckReply(msg) ) + { + call SoftwareAckConfig.createAckPacket(msg, &ackMsg); + + // TODO: what to do if we are busy and cannot send an ack + if( call SubSend.send(&ackMsg) == SUCCESS ) + state = STATE_ACK_SEND; + else + ASSERT(FALSE); + } + + return signal RadioReceive.receive(msg); + } +} diff --git a/tos/chips/rf2xx/layers/TrafficMonitorConfig.nc b/tos/chips/rf2xx/layers/TrafficMonitorConfig.nc new file mode 100755 index 00000000..0b7bc649 --- /dev/null +++ b/tos/chips/rf2xx/layers/TrafficMonitorConfig.nc @@ -0,0 +1,80 @@ +/* + * 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 + +interface TrafficMonitorConfig +{ + /** + * Returns the frequency (in milliseconds) when the traffic averages + * should be updated. + */ + async command uint16_t getUpdatePeriod(); + + /** + * Returns the amount of time this message has occupied the channel. + */ + async command uint16_t getChannelTime(message_t* msg); + + /** + * Returns the sender address of the message so we can calculate the + * average number of neighbors that send messages per update period. + */ + async command am_addr_t getSender(message_t* msg); + + /** + * This event should be fired if we notice some anomalies in the operation + * of the channel, such as not receiving acknowledgements, missing + * sequence numbers or packets with corrupted CRC. + */ + tasklet_async event void channelError(); + + /** + * Returns the averaged (exponential decay) transmit channel time + * during one update period. + */ + tasklet_async event uint16_t getTransmitAverage(); + + /** + * Returns the averaged (exponential decay) receive channel time + * during one update period. + */ + tasklet_async event uint16_t getReceiveAverage(); + + /** + * Returns the averaged (exponential decay) number of neighbors + * whose messages this component receives during one update period. + */ + tasklet_async event uint8_t getNeighborAverage(); + + /** + * Returns the averaged error events during one update period. + */ + tasklet_async event uint8_t getErrorAverage(); + + /** + * This command is periodically called when the timer is fired and + * the averages are updated + */ + tasklet_async command void timerTick(); +} diff --git a/tos/chips/rf2xx/layers/TrafficMonitorLayerC.nc b/tos/chips/rf2xx/layers/TrafficMonitorLayerC.nc new file mode 100644 index 00000000..6bab73f6 --- /dev/null +++ b/tos/chips/rf2xx/layers/TrafficMonitorLayerC.nc @@ -0,0 +1,64 @@ +/* + * 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 TrafficMonitorLayerC +{ + provides + { + interface RadioSend; + interface RadioReceive; + interface RadioState; + } + uses + { + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface RadioState as SubState; + + interface TrafficMonitorConfig as Config; + } +} + +implementation +{ + components TrafficMonitorLayerP, new TimerMilliC() as UpdateTimerC; + components NeighborhoodC, new NeighborhoodFlagC(), TaskletC; + + RadioSend = TrafficMonitorLayerP; + RadioReceive = TrafficMonitorLayerP; + RadioState = TrafficMonitorLayerP; + SubSend = TrafficMonitorLayerP; + SubReceive = TrafficMonitorLayerP; + SubState = TrafficMonitorLayerP; + Config = TrafficMonitorLayerP; + + TrafficMonitorLayerP.Timer -> UpdateTimerC; + TrafficMonitorLayerP.Neighborhood -> NeighborhoodC; + TrafficMonitorLayerP.NeighborhoodFlag -> NeighborhoodFlagC; + TrafficMonitorLayerP.Tasklet -> TaskletC; + +#ifdef RADIO_DEBUG + components DiagMsgC; + TrafficMonitorLayerP.DiagMsg -> DiagMsgC; +#endif +} diff --git a/tos/chips/rf2xx/layers/TrafficMonitorLayerP.nc b/tos/chips/rf2xx/layers/TrafficMonitorLayerP.nc new file mode 100644 index 00000000..b5f152ad --- /dev/null +++ b/tos/chips/rf2xx/layers/TrafficMonitorLayerP.nc @@ -0,0 +1,247 @@ +/* + * 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, reportS, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +#include + +/* + * You have to make sure that the maximum channel time in one report + * period times (1 << TRAFFIC_MONITOR_DECAY) is less than 65535. + */ +#ifndef TRAFFIC_MONITOR_DECAY +#define TRAFFIC_MONITOR_DECAY 3 +#endif + +module TrafficMonitorLayerP +{ + provides + { + interface RadioSend; + interface RadioReceive; + interface RadioState; + } + + uses + { + interface TrafficMonitorConfig; + interface RadioSend as SubSend; + interface RadioReceive as SubReceive; + interface RadioState as SubState; + interface Timer as Timer; + interface Neighborhood; + interface NeighborhoodFlag; + interface Tasklet; +#ifdef RADIO_DEBUG + interface DiagMsg; +#endif + } +} + +implementation +{ + tasklet_norace message_t *txMsg; + tasklet_norace uint8_t neighborCount; + + tasklet_norace uint16_t txAverage; + tasklet_norace uint16_t rxAverage; + tasklet_norace uint8_t neighborAverage; + tasklet_norace uint8_t errorAverage; + + enum + { + // the maximum average value + TRAFFIC_MONITOR_UINT8_MAX = 1 << (7-TRAFFIC_MONITOR_DECAY), + + // the unsignificant bits of the averaged values + TRAFFIC_MONITOR_MASK = (1 << TRAFFIC_MONITOR_DECAY) - 1, + + // to get the ceiling integer value + TRAFFIC_MONITOR_ROUND_UP = (1 << TRAFFIC_MONITOR_DECAY) - 1, + }; + + tasklet_async event void SubSend.ready() + { + signal RadioSend.ready(); + } + + tasklet_async command error_t RadioSend.send(message_t* msg) + { + txMsg = msg; + return call SubSend.send(msg); + } + + tasklet_async event void SubSend.sendDone(error_t error) + { + if( error == SUCCESS ) + txAverage += call TrafficMonitorConfig.getChannelTime(txMsg); + + signal RadioSend.sendDone(error); + } + + tasklet_async event bool SubReceive.header(message_t* msg) + { + return signal RadioReceive.header(msg); + } + + tasklet_async event message_t* SubReceive.receive(message_t* msg) + { + uint8_t index; + + rxAverage += call TrafficMonitorConfig.getChannelTime(msg); + + index = call Neighborhood.insertNode(call TrafficMonitorConfig.getSender(msg)); + if( ! call NeighborhoodFlag.get(index) ) + { + if( neighborCount < TRAFFIC_MONITOR_UINT8_MAX ) + { + ++neighborCount; + call NeighborhoodFlag.set(index); + } + } + + return signal RadioReceive.receive(msg); + } + + tasklet_async event void TrafficMonitorConfig.channelError() + { + if( errorAverage < 255 ) + ++errorAverage; + } + + uint8_t debugCounter; + + event void Timer.fired() + { + uint8_t fraction; + + call Tasklet.suspend(); + + txAverage -= (txAverage >> TRAFFIC_MONITOR_DECAY); + rxAverage -= (rxAverage >> TRAFFIC_MONITOR_DECAY); + errorAverage -= (errorAverage >> TRAFFIC_MONITOR_DECAY); + + // we could get stuck in the [1,7] range with no neighbors, so be more precise + fraction = neighborAverage >> TRAFFIC_MONITOR_DECAY; + if( fraction == neighborCount && (neighborAverage & TRAFFIC_MONITOR_MASK) != 0 ) + --neighborAverage; + else + neighborAverage += neighborCount - fraction; + + call NeighborhoodFlag.clearAll(); + neighborCount = 0; + + call TrafficMonitorConfig.timerTick(); + + call Tasklet.resume(); + +#ifdef RADIO_DEBUG + if( ++debugCounter >= 10 && call DiagMsg.record() ) + { + debugCounter = 0; + + call DiagMsg.str("traffic"); + call DiagMsg.uint16(signal TrafficMonitorConfig.getTransmitAverage()); + call DiagMsg.uint16(signal TrafficMonitorConfig.getReceiveAverage()); + call DiagMsg.uint8(signal TrafficMonitorConfig.getNeighborAverage()); + call DiagMsg.uint8(signal TrafficMonitorConfig.getErrorAverage()); + call DiagMsg.send(); + } +#endif + } + + tasklet_async event void Tasklet.run() + { + } + + tasklet_async event uint16_t TrafficMonitorConfig.getTransmitAverage() + { + return txAverage >> TRAFFIC_MONITOR_DECAY; + } + + tasklet_async event uint16_t TrafficMonitorConfig.getReceiveAverage() + { + return rxAverage >> TRAFFIC_MONITOR_DECAY; + } + + tasklet_async event uint8_t TrafficMonitorConfig.getNeighborAverage() + { + return (neighborAverage + TRAFFIC_MONITOR_ROUND_UP) >> TRAFFIC_MONITOR_DECAY; + } + + tasklet_async event uint8_t TrafficMonitorConfig.getErrorAverage() + { + return errorAverage >> TRAFFIC_MONITOR_DECAY; + } + + tasklet_async event void Neighborhood.evicted(uint8_t index) { } + + enum + { + RADIO_CMD_NONE = 0, + RADIO_CMD_TURNON = 1, + RADIO_CMD_TURNOFF = 2, + }; + tasklet_norace uint8_t radioCmd; + + tasklet_async command error_t RadioState.turnOff() + { + radioCmd = RADIO_CMD_TURNOFF; + return call SubState.turnOff(); + } + + tasklet_async command error_t RadioState.standby() + { + radioCmd = RADIO_CMD_TURNOFF; + return call SubState.standby(); + } + + tasklet_async command error_t RadioState.turnOn() + { + radioCmd = RADIO_CMD_TURNON; + return call SubState.turnOn(); + } + + tasklet_async command error_t RadioState.setChannel(uint8_t channel) + { + radioCmd = RADIO_CMD_NONE; + return call SubState.setChannel(channel); + } + + tasklet_async command uint8_t RadioState.getChannel() + { + return call SubState.getChannel(); + } + + task void startStopTimer() + { + if( radioCmd == RADIO_CMD_TURNON ) + call Timer.startPeriodic(call TrafficMonitorConfig.getUpdatePeriod()); + else if( radioCmd == RADIO_CMD_TURNOFF ) + call Timer.stop(); + } + + tasklet_async event void SubState.done() + { + post startStopTimer(); + signal RadioState.done(); + } +} diff --git a/tos/chips/rf2xx/layers/UniqueConfig.nc b/tos/chips/rf2xx/layers/UniqueConfig.nc new file mode 100755 index 00000000..5f14c521 --- /dev/null +++ b/tos/chips/rf2xx/layers/UniqueConfig.nc @@ -0,0 +1,48 @@ +/* + * 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 + +interface UniqueConfig +{ + /** + * Returns the sequence number of the packet. + */ + async command uint8_t getSequenceNumber(message_t* msg); + + /** + * Returns the sender of the packet. + */ + async command am_addr_t getSender(message_t* msg); + + /** + * Sets the sequence number of the packet. + */ + async command void setSequenceNumber(message_t*msg, uint8_t number); + + /** + * This command is called when the unqiue layer detects a missing (jump + * in the data sequence number) or a duplicate packet. + */ + tasklet_async command void reportChannelError(); +} diff --git a/tos/chips/rf2xx/layers/UniqueLayerC.nc b/tos/chips/rf2xx/layers/UniqueLayerC.nc new file mode 100755 index 00000000..5d2e5f23 --- /dev/null +++ b/tos/chips/rf2xx/layers/UniqueLayerC.nc @@ -0,0 +1,55 @@ +/* + * 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 UniqueLayerC +{ + provides + { + // NOTE, this is a combined layer, should be hooked up at two places + interface Send; + interface RadioReceive; + } + uses + { + interface Send as SubSend; + interface RadioReceive as SubReceive; + + interface UniqueConfig as Config; + } +} + +implementation +{ + components UniqueLayerP, MainC, NeighborhoodC, new NeighborhoodFlagC(); + + MainC.SoftwareInit -> UniqueLayerP; + UniqueLayerP.Neighborhood -> NeighborhoodC; + UniqueLayerP.NeighborhoodFlag -> NeighborhoodFlagC; + + Send = UniqueLayerP; + SubSend = UniqueLayerP; + + RadioReceive = UniqueLayerP; + SubReceive = UniqueLayerP; + Config = UniqueLayerP; +} diff --git a/tos/chips/rf2xx/layers/UniqueLayerP.nc b/tos/chips/rf2xx/layers/UniqueLayerP.nc new file mode 100755 index 00000000..d341942e --- /dev/null +++ b/tos/chips/rf2xx/layers/UniqueLayerP.nc @@ -0,0 +1,116 @@ +/* + * 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 UniqueLayerP +{ + provides + { + interface Send; + interface RadioReceive; + + interface Init; + } + + uses + { + interface Send as SubSend; + interface RadioReceive as SubReceive; + + interface UniqueConfig; + interface Neighborhood; + interface NeighborhoodFlag; + } +} + +implementation +{ + uint8_t sequenceNumber; + + command error_t Init.init() + { + sequenceNumber = TOS_NODE_ID << 4; + return SUCCESS; + } + + command error_t Send.send(message_t* msg, uint8_t len) + { + call UniqueConfig.setSequenceNumber(msg, ++sequenceNumber); + return call SubSend.send(msg, len); + } + + command error_t Send.cancel(message_t* msg) + { + return call SubSend.cancel(msg); + } + + event void SubSend.sendDone(message_t* msg, error_t error) + { + signal Send.sendDone(msg, error); + } + + command uint8_t Send.maxPayloadLength() + { + return call SubSend.maxPayloadLength(); + } + + command void* Send.getPayload(message_t* msg, uint8_t len) + { + return call SubSend.getPayload(msg, len); + } + + tasklet_async event bool SubReceive.header(message_t* msg) + { + // we could scan here, but better be lazy + return signal RadioReceive.header(msg); + } + + tasklet_norace uint8_t receivedNumbers[NEIGHBORHOOD_SIZE]; + + tasklet_async event message_t* SubReceive.receive(message_t* msg) + { + uint8_t index = call Neighborhood.insertNode(call UniqueConfig.getSender(msg)); + uint8_t dsn = call UniqueConfig.getSequenceNumber(msg); + + if( call NeighborhoodFlag.get(index) ) + { + uint8_t diff = dsn - receivedNumbers[index]; + + if( diff == 0 ) + { + call UniqueConfig.reportChannelError(); + return msg; + } + } + else + call NeighborhoodFlag.set(index); + + receivedNumbers[index] = dsn; + + return signal RadioReceive.receive(msg); + } + + tasklet_async event void Neighborhood.evicted(uint8_t index) { } +} diff --git a/tos/chips/rf2xx/rf230/RF230.h b/tos/chips/rf2xx/rf230/RF230.h new file mode 100644 index 00000000..781a1330 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230.h @@ -0,0 +1,153 @@ +/* + * 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/rf2xx/rf230/RF230ActiveMessageC.nc b/tos/chips/rf2xx/rf230/RF230ActiveMessageC.nc new file mode 100644 index 00000000..46c2f575 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230ActiveMessageC.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 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 RADIO_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 SLOTTED_MAC + components SlottedCollisionLayerC as CollisionAvoidanceLayerC; +#else + components RandomCollisionLayerC as CollisionAvoidanceLayerC; +#endif + components SoftwareAckLayerC; + components new DummyLayerC() as CsmaLayerC; + components RF230DriverLayerC; + + 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 -> RF230DriverLayerC; + + CollisionAvoidanceLayerC.Config -> RF230ActiveMessageP; + CollisionAvoidanceLayerC.SubSend -> SoftwareAckLayerC; + CollisionAvoidanceLayerC.SubReceive -> SoftwareAckLayerC; + + SoftwareAckLayerC.Config -> RF230ActiveMessageP; + SoftwareAckLayerC.SubSend -> CsmaLayerC; + SoftwareAckLayerC.SubReceive -> RF230DriverLayerC; + + CsmaLayerC.Config -> RF230ActiveMessageP; + CsmaLayerC -> RF230DriverLayerC.RadioSend; + CsmaLayerC -> RF230DriverLayerC.RadioCCA; + + RF230DriverLayerC.RF230DriverConfig -> RF230ActiveMessageP; +} diff --git a/tos/chips/rf2xx/rf230/RF230ActiveMessageP.nc b/tos/chips/rf2xx/rf230/RF230ActiveMessageP.nc index 71b13307..58f65840 100644 --- a/tos/chips/rf2xx/rf230/RF230ActiveMessageP.nc +++ b/tos/chips/rf2xx/rf230/RF230ActiveMessageP.nc @@ -268,7 +268,7 @@ implementation async command uint8_t SlottedCollisionConfig.getScheduleExponent() { - return 11; + return 1 + RADIO_ALARM_MILLI_EXP; } async command uint16_t SlottedCollisionConfig.getTransmitTime(message_t* msg) diff --git a/tos/chips/rf2xx/rf230/RF230DriverConfig.nc b/tos/chips/rf2xx/rf230/RF230DriverConfig.nc new file mode 100644 index 00000000..1b6b04f4 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230DriverConfig.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 RF230DriverLayerC component. + */ +interface RF230DriverConfig +{ + /** + * 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/rf2xx/rf230/RF230DriverLayerC.nc b/tos/chips/rf2xx/rf230/RF230DriverLayerC.nc new file mode 100644 index 00000000..021e0982 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230DriverLayerC.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 RF230DriverLayerC +{ + provides + { + interface RadioState; + interface RadioSend; + interface RadioReceive; + interface RadioCCA; + } + + uses interface RF230DriverConfig; +} + +implementation +{ + components RF230DriverLayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC, RF230PacketC, LocalTimeMicroC as LocalTimeRadioC; + + RadioState = RF230DriverLayerP; + RadioSend = RF230DriverLayerP; + RadioReceive = RF230DriverLayerP; + RadioCCA = RF230DriverLayerP; + + RF230DriverConfig = RF230DriverLayerP; + + RF230DriverLayerP.PacketLinkQuality -> RF230PacketC.PacketLinkQuality; + RF230DriverLayerP.PacketTransmitPower -> RF230PacketC.PacketTransmitPower; + RF230DriverLayerP.PacketRSSI -> RF230PacketC.PacketRSSI; + RF230DriverLayerP.PacketTimeSyncOffset -> RF230PacketC.PacketTimeSyncOffset; + RF230DriverLayerP.PacketTimeStamp -> RF230PacketC; + RF230DriverLayerP.LocalTime -> LocalTimeRadioC; + + RF230DriverLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")]; + RadioAlarmC.Alarm -> HplRF230C.Alarm; + + RF230DriverLayerP.SELN -> HplRF230C.SELN; + RF230DriverLayerP.SpiResource -> HplRF230C.SpiResource; + RF230DriverLayerP.FastSpiByte -> HplRF230C; + + RF230DriverLayerP.SLP_TR -> HplRF230C.SLP_TR; + RF230DriverLayerP.RSTN -> HplRF230C.RSTN; + + RF230DriverLayerP.IRQ -> HplRF230C.IRQ; + RF230DriverLayerP.Tasklet -> TaskletC; + RF230DriverLayerP.BusyWait -> BusyWaitMicroC; + +#ifdef RADIO_DEBUG + components DiagMsgC; + RF230DriverLayerP.DiagMsg -> DiagMsgC; +#endif + + MainC.SoftwareInit -> RF230DriverLayerP.SoftwareInit; + + components RealMainP; + RealMainP.PlatformInit -> RF230DriverLayerP.PlatformInit; +} diff --git a/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc b/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc new file mode 100644 index 00000000..c7e59fb2 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230DriverLayerP.nc @@ -0,0 +1,821 @@ +/* + * 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 + +module RF230DriverLayerP +{ + 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 RF230DriverConfig; + interface Tasklet; + interface RadioAlarm; + +#ifdef RADIO_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 RF230DriverConfig.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 RF230DriverConfig.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 RF230DriverConfig.getLength(msg); + data = call RF230DriverConfig.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 RF230DriverConfig.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 RADIO_DEBUG_MESSAGES + if( call DiagMsg.record() ) + { + length = call RF230DriverConfig.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 RF230DriverConfig.getMaxLength() ) + { + uint8_t read; + uint8_t* data; + + // initiate the reading + call FastSpiByte.splitWrite(0); + + call RF230DriverConfig.setLength(rxMsg, length); + data = call RF230DriverConfig.getPayload(rxMsg); + crc = 0; + + // we do not store the CRC field + length -= 2; + + read = call RF230DriverConfig.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 RADIO_DEBUG_MESSAGES + if( call DiagMsg.record() ) + { + length = call RF230DriverConfig.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 RF230DriverConfig.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 RADIO_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/rf2xx/rf230/RF230Packet.h b/tos/chips/rf2xx/rf230/RF230Packet.h new file mode 100644 index 00000000..f12e3e5b --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230Packet.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 __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/rf2xx/rf230/RF230PacketC.nc b/tos/chips/rf2xx/rf230/RF230PacketC.nc new file mode 100644 index 00000000..9d09b314 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230PacketC.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 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/rf2xx/rf230/RF230PacketP.nc b/tos/chips/rf2xx/rf230/RF230PacketP.nc new file mode 100644 index 00000000..383cad78 --- /dev/null +++ b/tos/chips/rf2xx/rf230/RF230PacketP.nc @@ -0,0 +1,290 @@ +/* + * 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 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(); + + return (offset >> RADIO_ALARM_MILLI_EXP) + 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) + { + int32_t offset = (value - call LocalTimeMilli.get()) << RADIO_ALARM_MILLI_EXP; + + 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/rf2xx/util/IEEE154Packet.h b/tos/chips/rf2xx/util/IEEE154Packet.h new file mode 100644 index 00000000..62fe16b0 --- /dev/null +++ b/tos/chips/rf2xx/util/IEEE154Packet.h @@ -0,0 +1,75 @@ +/* + * 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 __IEEE154PACKET_H__ +#define __IEEE154PACKET_H__ + +typedef nx_struct ieee154_header_t +{ + nxle_uint8_t length; + nxle_uint16_t fcf; + nxle_uint8_t dsn; + nxle_uint16_t destpan; + nxle_uint16_t dest; + nxle_uint16_t src; + +// I-Frame 6LowPAN interoperability byte +#ifndef TFRAMES_ENABLED + nxle_uint8_t network; +#endif + + nxle_uint8_t type; +} ieee154_header_t; + +// the actual radio driver might not use this +typedef nx_struct ieee154_footer_t +{ + nxle_uint16_t crc; +} ieee154_footer_t; + +enum ieee154_fcf_enums { + IEEE154_FCF_FRAME_TYPE = 0, + IEEE154_FCF_SECURITY_ENABLED = 3, + IEEE154_FCF_FRAME_PENDING = 4, + IEEE154_FCF_ACK_REQ = 5, + IEEE154_FCF_INTRAPAN = 6, + IEEE154_FCF_DEST_ADDR_MODE = 10, + IEEE154_FCF_SRC_ADDR_MODE = 14, +}; + +enum ieee154_fcf_type_enums { + IEEE154_TYPE_BEACON = 0, + IEEE154_TYPE_DATA = 1, + IEEE154_TYPE_ACK = 2, + IEEE154_TYPE_MAC_CMD = 3, + IEEE154_TYPE_MASK = 7, +}; + +enum iee154_fcf_addr_mode_enums { + IEEE154_ADDR_NONE = 0, + IEEE154_ADDR_SHORT = 2, + IEEE154_ADDR_EXT = 3, + IEEE154_ADDR_MASK = 3, +}; + +#endif//__IEEE154PACKET_H__ diff --git a/tos/chips/rf2xx/util/IEEE154Packet.nc b/tos/chips/rf2xx/util/IEEE154Packet.nc new file mode 100644 index 00000000..fd171743 --- /dev/null +++ b/tos/chips/rf2xx/util/IEEE154Packet.nc @@ -0,0 +1,197 @@ +/* + * 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 + +/** + * This interface encapsulates IEEE 802.15.4 intrapan data frames with + * 16-bit destination pan, source and destination addresses. It also + * supports 6LowPan interoperability mode, and acknowledgement frames. + * Note, that this interface does not support the CRC-16 value, which + * should be verified before the data can be trusted. + */ +interface IEEE154Packet +{ + /** + * Returns the IEEE 802.15.4 header including the length field. + */ + async command ieee154_header_t* getHeader(message_t* msg); + + /** + * Returns the raw value (unadjusted) of the length field + */ + async command uint8_t getLength(message_t* msg); + + /** + * Sets the length field + */ + async command void setLength(message_t* msg, uint8_t length); + + /** + * Returns the frame control field. This method should not be used, + * isDataFrame and isAckFrame should be used instead. + */ + async command uint16_t getFCF(message_t* msg); + + /** + * Sets the frame control field. This method should not be used, + * createDataFrame and createAckFrame should be used instead. + */ + async command void setFCF(message_t* msg, uint16_t fcf); + + /** + * Returns TRUE if the message is a data frame supported by + * this interface (based on the value of the FCF). + */ + async command bool isDataFrame(message_t* msg); + + /** + * Sets the FCF to create a data frame supported by this interface. + * You may call setAckRequired and setFramePending commands after this. + */ + async command void createDataFrame(message_t* msg); + + /** + * Returns TRUE if the message is an acknowledgement frame supported + * by this interface (based on the value of the FCF). + */ + async command bool isAckFrame(message_t* msg); + + /** + * Sets the FCF to create an acknowledgement frame supported by + * this interface. You may call setFramePending after this. + */ + async command void createAckFrame(message_t* msg); + + /** + * Creates an acknowledgement packet for the given data packet. + * This also sets the DSN value. The data message must be a + * data frame, the ack message will be overwritten. + */ + async command void createAckReply(message_t* data, message_t* ack); + + /** + * Returns TRUE if the acknowledgement packet corresponds to the + * data packet. The data message must be a data packet. + */ + async command bool verifyAckReply(message_t* data, message_t* ack); + + /** + * Returns TRUE if the ACK required field is set in the FCF. + */ + async command bool getAckRequired(message_t* msg); + + /** + * Sets the ACK required field in the FCF, should never be set + * for acknowledgement frames. + */ + async command void setAckRequired(message_t* msg, bool ack); + + /** + * Returns TRUE if the frame pending field is set in the FCF. + */ + async command bool getFramePending(message_t* msg); + + /** + * Sets the frame pending field in the FCF. + */ + async command void setFramePending(message_t* msg, bool pending); + + /** + * Returns the data sequence number + */ + async command uint8_t getDSN(message_t* msg); + + /** + * Sets the data sequence number + */ + async command void setDSN(message_t* msg, uint8_t dsn); + + /** + * returns the destination PAN id, values <= 255 are tinyos groups, + * valid only for data frames + */ + async command uint16_t getDestPan(message_t* msg); + + /** + * Sets the destination PAN id, valid only for data frames + */ + async command void setDestPan(message_t* msg, uint16_t pan); + + /** + * Returns the destination address, valid only for data frames + */ + async command uint16_t getDestAddr(message_t* msg); + + /** + * Sets the destination address, valid only for data frames + */ + async command void setDestAddr(message_t* msg, uint16_t addr); + + /** + * Returns the source address, valid only for data frames + */ + async command uint16_t getSrcAddr(message_t* msg); + + /** + * Sets the source address, valid only for data frames + */ + async command void setSrcAddr(message_t* msg, uint16_t addr); + +#ifndef TFRAMES_ENABLED + + /** + * Returns the value of the 6LowPan network field. + */ + async command uint8_t get6LowPan(message_t* msg); + + /** + * Sets the value of the 6LowPan network field. + */ + async command void set6LowPan(message_t* msg, uint8_t network); + +#endif + + /** + * Returns the active message type of the message + */ + async command am_id_t getType(message_t* msg); + + /** + * Sets the active message type + */ + async command void setType(message_t* msg, am_id_t type); + + /** + * Returns TRUE if the packet is a data packet, the ACK_REQ field + * is set and the destination address is not the broadcast address. + */ + async command bool requiresAckWait(message_t* msg); + + /** + * Returns TRUE if the packet is a data packet, the ACK_REQ field + * is set and the destionation address is this node. + */ + async command bool requiresAckReply(message_t* msg); +} diff --git a/tos/chips/rf2xx/util/IEEE154PacketC.nc b/tos/chips/rf2xx/util/IEEE154PacketC.nc new file mode 100755 index 00000000..2ea8ffeb --- /dev/null +++ b/tos/chips/rf2xx/util/IEEE154PacketC.nc @@ -0,0 +1,40 @@ +/* + * 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 IEEE154PacketC +{ + provides + { + interface IEEE154Packet; + interface AMPacket; + } +} + +implementation +{ + components IEEE154PacketP, ActiveMessageAddressC; + IEEE154PacketP.ActiveMessageAddress -> ActiveMessageAddressC; + + IEEE154Packet = IEEE154PacketP; + AMPacket = IEEE154PacketP; +} diff --git a/tos/chips/rf2xx/util/IEEE154PacketP.nc b/tos/chips/rf2xx/util/IEEE154PacketP.nc new file mode 100644 index 00000000..cb898244 --- /dev/null +++ b/tos/chips/rf2xx/util/IEEE154PacketP.nc @@ -0,0 +1,294 @@ +/* + * 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 + +module IEEE154PacketP +{ + provides + { + interface IEEE154Packet; + interface AMPacket; + } + + uses interface ActiveMessageAddress; +} + +implementation +{ +/*----------------- IEEE154Packet -----------------*/ + + enum + { + IEEE154_DATA_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE) + | (1 << IEEE154_FCF_INTRAPAN) + | (IEEE154_ADDR_MASK << IEEE154_FCF_DEST_ADDR_MODE) + | (IEEE154_ADDR_MASK << IEEE154_FCF_SRC_ADDR_MODE), + + IEEE154_DATA_FRAME_VALUE = (IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE) + | (1 << IEEE154_FCF_INTRAPAN) + | (IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE) + | (IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE), + + IEEE154_ACK_FRAME_LENGTH = 5, // includes the FCF, DSN and FCS + IEEE154_ACK_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE), + IEEE154_ACK_FRAME_VALUE = (IEEE154_TYPE_ACK << IEEE154_FCF_FRAME_TYPE), + }; + + inline ieee154_header_t* getHeader(message_t* msg) + { + return (ieee154_header_t*)(msg->data - sizeof(ieee154_header_t)); + } + + inline async command ieee154_header_t* IEEE154Packet.getHeader(message_t* msg) + { + return getHeader(msg); + } + + inline async command uint8_t IEEE154Packet.getLength(message_t* msg) + { + return getHeader(msg)->length; + } + + inline async command void IEEE154Packet.setLength(message_t* msg, uint8_t length) + { + getHeader(msg)->length = length; + } + + inline async command uint16_t IEEE154Packet.getFCF(message_t* msg) + { + return getHeader(msg)->fcf; + } + + inline async command void IEEE154Packet.setFCF(message_t* msg, uint16_t fcf) + { + getHeader(msg)->fcf = fcf; + } + + inline async command bool IEEE154Packet.isDataFrame(message_t* msg) + { + return (getHeader(msg)->fcf & IEEE154_DATA_FRAME_MASK) == IEEE154_DATA_FRAME_VALUE; + } + + inline async command void IEEE154Packet.createDataFrame(message_t* msg) + { + getHeader(msg)->fcf = IEEE154_DATA_FRAME_VALUE; + } + + inline async command bool IEEE154Packet.isAckFrame(message_t* msg) + { + return (getHeader(msg)->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE; + } + + inline async command void IEEE154Packet.createAckFrame(message_t* msg) + { + ieee154_header_t* header = getHeader(msg); + + header->length = IEEE154_ACK_FRAME_LENGTH; + header->fcf = IEEE154_ACK_FRAME_VALUE; + } + + inline async command void IEEE154Packet.createAckReply(message_t* data, message_t* ack) + { + ieee154_header_t* header = getHeader(ack); + + header->length = IEEE154_ACK_FRAME_LENGTH; + header->fcf = IEEE154_ACK_FRAME_VALUE; + header->dsn = getHeader(data)->dsn; + } + + inline async command bool IEEE154Packet.verifyAckReply(message_t* data, message_t* ack) + { + ieee154_header_t* header = getHeader(ack); + + return header->dsn == getHeader(data)->dsn + && (header->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE; + } + + inline async command bool IEEE154Packet.getAckRequired(message_t* msg) + { + return getHeader(msg)->fcf & (1 << IEEE154_FCF_ACK_REQ); + } + + inline async command void IEEE154Packet.setAckRequired(message_t* msg, bool ack) + { + if( ack ) + getHeader(msg)->fcf |= (1 << IEEE154_FCF_ACK_REQ); + else + getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_ACK_REQ); + } + + inline async command bool IEEE154Packet.getFramePending(message_t* msg) + { + return getHeader(msg)->fcf & (1 << IEEE154_FCF_FRAME_PENDING); + } + + inline async command void IEEE154Packet.setFramePending(message_t* msg, bool pending) + { + if( pending ) + getHeader(msg)->fcf |= (1 << IEEE154_FCF_FRAME_PENDING); + else + getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_FRAME_PENDING); + } + + inline async command uint8_t IEEE154Packet.getDSN(message_t* msg) + { + return getHeader(msg)->dsn; + } + + inline async command void IEEE154Packet.setDSN(message_t* msg, uint8_t dsn) + { + getHeader(msg)->dsn = dsn; + } + + inline async command uint16_t IEEE154Packet.getDestPan(message_t* msg) + { + return getHeader(msg)->destpan; + } + + inline async command void IEEE154Packet.setDestPan(message_t* msg, uint16_t pan) + { + getHeader(msg)->destpan = pan; + } + + inline async command uint16_t IEEE154Packet.getDestAddr(message_t* msg) + { + return getHeader(msg)->dest; + } + + inline async command void IEEE154Packet.setDestAddr(message_t* msg, uint16_t addr) + { + getHeader(msg)->dest = addr; + } + + inline async command uint16_t IEEE154Packet.getSrcAddr(message_t* msg) + { + return getHeader(msg)->src; + } + + inline async command void IEEE154Packet.setSrcAddr(message_t* msg, uint16_t addr) + { + getHeader(msg)->src = addr; + } + +#ifndef TFRAMES_ENABLED + + inline async command uint8_t IEEE154Packet.get6LowPan(message_t* msg) + { + return getHeader(msg)->network; + } + + inline async command void IEEE154Packet.set6LowPan(message_t* msg, uint8_t network) + { + getHeader(msg)->network = network; + } + +#endif + + inline async command am_id_t IEEE154Packet.getType(message_t* msg) + { + return getHeader(msg)->type; + } + + inline async command void IEEE154Packet.setType(message_t* msg, am_id_t type) + { + getHeader(msg)->type = type; + } + + async command bool IEEE154Packet.requiresAckWait(message_t* msg) + { + return call IEEE154Packet.getAckRequired(msg) + && call IEEE154Packet.isDataFrame(msg) + && call IEEE154Packet.getDestAddr(msg) != 0xFFFF; + } + + async command bool IEEE154Packet.requiresAckReply(message_t* msg) + { + return call IEEE154Packet.getAckRequired(msg) + && call IEEE154Packet.isDataFrame(msg) + && call IEEE154Packet.getDestAddr(msg) == call ActiveMessageAddress.amAddress(); + } + + inline async event void ActiveMessageAddress.changed() + { + } + +/*----------------- AMPacket -----------------*/ + + inline command am_addr_t AMPacket.address() + { + return call ActiveMessageAddress.amAddress(); + } + + inline command am_group_t AMPacket.localGroup() + { + // TODO: check if this is correct + return call ActiveMessageAddress.amGroup(); + } + + inline command am_addr_t AMPacket.destination(message_t* msg) + { + return call IEEE154Packet.getDestAddr(msg); + } + + inline command am_addr_t AMPacket.source(message_t* msg) + { + return call IEEE154Packet.getSrcAddr(msg); + } + + inline command void AMPacket.setDestination(message_t* msg, am_addr_t addr) + { + call IEEE154Packet.setDestAddr(msg, addr); + } + + inline command void AMPacket.setSource(message_t* msg, am_addr_t addr) + { + call IEEE154Packet.setSrcAddr(msg, addr); + } + + inline command bool AMPacket.isForMe(message_t* msg) + { + am_addr_t addr = call AMPacket.destination(msg); + return addr == call AMPacket.address() || addr == AM_BROADCAST_ADDR; + } + + inline command am_id_t AMPacket.type(message_t* msg) + { + return call IEEE154Packet.getType(msg); + } + + inline command void AMPacket.setType(message_t* msg, am_id_t type) + { + call IEEE154Packet.setType(msg, type); + } + + inline command am_group_t AMPacket.group(message_t* msg) + { + return call IEEE154Packet.getDestPan(msg); + } + + inline command void AMPacket.setGroup(message_t* msg, am_group_t grp) + { + call IEEE154Packet.setDestPan(msg, grp); + } +} diff --git a/tos/chips/rf2xx/util/Neighborhood.h b/tos/chips/rf2xx/util/Neighborhood.h new file mode 100755 index 00000000..40884e39 --- /dev/null +++ b/tos/chips/rf2xx/util/Neighborhood.h @@ -0,0 +1,31 @@ +/* + * 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 __NEIGHBORHOOD_H__ +#define __NEIGHBORHOOD_H__ + +#ifndef NEIGHBORHOOD_SIZE +#define NEIGHBORHOOD_SIZE 5 +#endif + +#endif//__NEIGHBORHOOD_H__ diff --git a/tos/chips/rf2xx/util/Neighborhood.nc b/tos/chips/rf2xx/util/Neighborhood.nc new file mode 100644 index 00000000..cc4b7db4 --- /dev/null +++ b/tos/chips/rf2xx/util/Neighborhood.nc @@ -0,0 +1,70 @@ +/* + * 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 + +/** + * Every component maintains its own neighborhood data. The Neighboorhood + * component maintains only the nodeids and ages of the neighbors, and + * evicts old entries from the table when necessary. + */ +interface Neighborhood +{ + /** + * Returns the index of the neighbor in the table. If the node was not + * found in the table, then the value NEIGHBORHOOD is returned, + * otherwise an index in the range [0, NEIGHBORHOOD-1] is returned. + */ + tasklet_async command uint8_t getIndex(am_addr_t id); + + /** + * Returns the age of the given entry. The age is incremented by one + * every time a new node is inserted into the neighborhood table that + * is not already at the very end. If the age would get too large to + * fit into a byte, then it is periodically reset to a smaller value. + */ + tasklet_async command uint8_t getAge(uint8_t index); + + /** + * Returns the node address for the given entry. + */ + tasklet_async command am_addr_t getNode(uint8_t index); + + /** + * Adds a new node into the neighborhood table. If this node was already + * in the table, then it is just brought to the front (its age is reset + * to zero). If the node was not in the table, then the oldest is evicted + * and its entry is replaced with this node. The index of the entry + * is returned in the range [0, NEIGHBORHOOD-1]. + */ + tasklet_async command uint8_t insertNode(am_addr_t id); + + /** + * This event is fired when the oldest entry is replaced with a new + * node. The same interface is used by many users, so all of them + * will receive this event and can clear the corresponding entry. + * After this event is fired, all flags for this entry are cleared + * (see the NeighborhoodFlag interface) + */ + tasklet_async event void evicted(uint8_t index); +} diff --git a/tos/chips/rf2xx/util/NeighborhoodC.nc b/tos/chips/rf2xx/util/NeighborhoodC.nc new file mode 100755 index 00000000..e2ba9b50 --- /dev/null +++ b/tos/chips/rf2xx/util/NeighborhoodC.nc @@ -0,0 +1,35 @@ +/* + * 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 NeighborhoodC +{ + provides interface Neighborhood; +} + +implementation +{ + components NeighborhoodP, MainC; + + Neighborhood = NeighborhoodP; + MainC.SoftwareInit -> NeighborhoodP; +} diff --git a/tos/chips/rf2xx/util/NeighborhoodFlag.nc b/tos/chips/rf2xx/util/NeighborhoodFlag.nc new file mode 100755 index 00000000..e1dda902 --- /dev/null +++ b/tos/chips/rf2xx/util/NeighborhoodFlag.nc @@ -0,0 +1,52 @@ +/* + * 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 + +/** + * This interface provides one bit storage for each neighbor in a very + * fast and conveint way (without using shifts for example). + */ +interface NeighborhoodFlag +{ + /** + * Returns the value of the flag for the given index + */ + tasklet_async command bool get(uint8_t index); + + /** + * Sets the flag for the given index + */ + tasklet_async command void set(uint8_t index); + + /** + * Clears the flag for the given index. The flag is automatically + * cleared after the Neighborhood.evicted event is fired. + */ + tasklet_async command void clear(uint8_t index); + + /** + * Clears the flag for all indices + */ + tasklet_async command void clearAll(); +} diff --git a/tos/chips/rf2xx/util/NeighborhoodFlagC.nc b/tos/chips/rf2xx/util/NeighborhoodFlagC.nc new file mode 100755 index 00000000..2f064eb6 --- /dev/null +++ b/tos/chips/rf2xx/util/NeighborhoodFlagC.nc @@ -0,0 +1,35 @@ +/* + * 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 + */ + +generic configuration NeighborhoodFlagC() +{ + provides interface NeighborhoodFlag; +} + +implementation +{ + components NeighborhoodP; + + // TODO: make sure that no more than 8 flags are used at a time + NeighborhoodFlag = NeighborhoodP.NeighborhoodFlag[unique("NeighborhoodFlag")]; +} diff --git a/tos/chips/rf2xx/util/NeighborhoodP.nc b/tos/chips/rf2xx/util/NeighborhoodP.nc new file mode 100755 index 00000000..fb84dc8a --- /dev/null +++ b/tos/chips/rf2xx/util/NeighborhoodP.nc @@ -0,0 +1,171 @@ +/* + * 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 + +module NeighborhoodP +{ + provides + { + interface Init; + interface Neighborhood; + interface NeighborhoodFlag[uint8_t bit]; + } +} + +implementation +{ + tasklet_norace am_addr_t nodes[NEIGHBORHOOD_SIZE]; + tasklet_norace uint8_t ages[NEIGHBORHOOD_SIZE]; + tasklet_norace uint8_t flags[NEIGHBORHOOD_SIZE]; + tasklet_norace uint8_t time; + tasklet_norace uint8_t last; + + command error_t Init.init() + { + uint8_t i; + + for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) + nodes[i] = AM_BROADCAST_ADDR; + + return SUCCESS; + } + + inline tasklet_async command am_addr_t Neighborhood.getNode(uint8_t index) + { + return nodes[index]; + } + + inline tasklet_async command uint8_t Neighborhood.getAge(uint8_t index) + { + return time - ages[index]; + } + + tasklet_async uint8_t command Neighborhood.getIndex(am_addr_t node) + { + uint8_t i; + + if( nodes[last] == node ) + return last; + + for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) + { + if( nodes[i] == node ) + { + last = i; + break; + } + } + + return i; + } + + tasklet_async uint8_t command Neighborhood.insertNode(am_addr_t node) + { + uint8_t i; + uint8_t maxAge; + + if( nodes[last] == node ) + { + if( ages[last] == time ) + return last; + + ages[last] = ++time; + maxAge = 0x80; + } + else + { + uint8_t oldest = 0; + maxAge = 0; + + for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) + { + uint8_t age; + + if( nodes[i] == node ) + { + last = i; + if( ages[i] == time ) + return i; + + ages[i] = ++time; + maxAge = 0x80; + break; + } + + age = time - ages[i]; + if( age > maxAge ) + { + maxAge = age; + oldest = i; + } + } + + if( i == NEIGHBORHOOD_SIZE ) + { + signal Neighborhood.evicted(oldest); + + last = oldest; + nodes[oldest] = node; + ages[oldest] = ++time; + flags[oldest] = 0; + } + } + + if( (time & 0x7F) == 0x7F && maxAge >= 0x7F ) + { + for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) + { + if( (ages[i] | 0x7F) != time ) + ages[i] = time & 0x80; + } + } + + return last; + } + + inline tasklet_async command bool NeighborhoodFlag.get[uint8_t bit](uint8_t index) + { + return flags[index] & (1 << bit); + } + + inline tasklet_async command void NeighborhoodFlag.set[uint8_t bit](uint8_t index) + { + flags[index] |= (1 << bit); + } + + inline tasklet_async command void NeighborhoodFlag.clear[uint8_t bit](uint8_t index) + { + flags[index] &= ~(1 << bit); + } + + tasklet_async command void NeighborhoodFlag.clearAll[uint8_t bit]() + { + uint8_t i; + + bit = ~(1 << bit); + + for(i = 0; i < NEIGHBORHOOD_SIZE; ++i) + flags[i] &= bit; + } +} diff --git a/tos/chips/rf2xx/util/PacketField.nc b/tos/chips/rf2xx/util/PacketField.nc new file mode 100644 index 00000000..3f902931 --- /dev/null +++ b/tos/chips/rf2xx/util/PacketField.nc @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2007, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface PacketField +{ + /** + * Returns TRUE if the value is set for this message. + */ + async command bool isSet(message_t* msg); + + /** + * Returns the stored value of this field in the message. If the + * value is not set, then the returned value is undefined. + */ + async command value_type get(message_t* msg); + + /** + * Clears the isSet flag. + */ + async command void clear(message_t* msg); + + /** + * Sets the isSet false to TRUE and the time stamp value to the + * specified value. + */ + async command void set(message_t* msg, value_type value); +} diff --git a/tos/chips/rf2xx/util/RadioAlarm.nc b/tos/chips/rf2xx/util/RadioAlarm.nc new file mode 100755 index 00000000..d09c4f0e --- /dev/null +++ b/tos/chips/rf2xx/util/RadioAlarm.nc @@ -0,0 +1,54 @@ +/* + * 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 + +interface RadioAlarm +{ + /** + * Returns TRUE if the alarm is free and ready to be used. Once the alarm + * is free, it cannot become nonfree in the same tasklet block. Note, + * if the alarm is currently set (even if for ourselves) then it is not free. + */ + tasklet_async command bool isFree(); + + /** + * Waits till the specified timeout period expires. The alarm must be free. + */ + tasklet_async command void wait(uint16_t timeout); + + /** + * Cancels the running alarm. The alarm must be pending. + */ + tasklet_async command void cancel(); + + /** + * This event is fired when the specified timeout period expires. + */ + tasklet_async event void fired(); + + /** + * Returns the current time as measured by the radio stack. + */ + async command uint16_t getNow(); +} diff --git a/tos/chips/rf2xx/util/RadioAlarmC.nc b/tos/chips/rf2xx/util/RadioAlarmC.nc new file mode 100644 index 00000000..68f53d54 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioAlarmC.nc @@ -0,0 +1,44 @@ +/* + * 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 RadioAlarmC +{ + provides + { + interface RadioAlarm[uint8_t id]; // use unique("RadioAlarm") + } + + uses + { + interface Alarm @exactlyonce(); + } +} + +implementation +{ + components RadioAlarmP, TaskletC; + + RadioAlarm = RadioAlarmP; + Alarm = RadioAlarmP; + RadioAlarmP.Tasklet -> TaskletC; +} diff --git a/tos/chips/rf2xx/util/RadioAlarmP.nc b/tos/chips/rf2xx/util/RadioAlarmP.nc new file mode 100644 index 00000000..537b76a7 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioAlarmP.nc @@ -0,0 +1,104 @@ +/* + * 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 RadioAlarmP +{ + provides + { + interface RadioAlarm[uint8_t id]; + } + + uses + { + interface Alarm; + interface Tasklet; + } +} + +implementation +{ + norace uint8_t state; + enum + { + STATE_READY = 0, + STATE_WAIT = 1, + STATE_FIRED = 2, + }; + + tasklet_norace uint8_t alarm; + + async event void Alarm.fired() + { + atomic + { + if( state == STATE_WAIT ) + state = STATE_FIRED; + } + + call Tasklet.schedule(); + } + + inline async command uint16_t RadioAlarm.getNow[uint8_t id]() + { + return call Alarm.getNow(); + } + + tasklet_async event void Tasklet.run() + { + if( state == STATE_FIRED ) + { + state = STATE_READY; + signal RadioAlarm.fired[alarm](); + } + } + + default tasklet_async event void RadioAlarm.fired[uint8_t id]() + { + } + + inline tasklet_async command bool RadioAlarm.isFree[uint8_t id]() + { + return state == STATE_READY; + } + + tasklet_async command void RadioAlarm.wait[uint8_t id](uint16_t timeout) + { + ASSERT( state == STATE_READY ); + + alarm = id; + state = STATE_WAIT; + call Alarm.start(timeout); + } + + tasklet_async command void RadioAlarm.cancel[uint8_t id]() + { + ASSERT( alarm == id ); + ASSERT( state != STATE_READY ); + + call Alarm.stop(); + state = STATE_READY; + } +} diff --git a/tos/chips/rf2xx/util/RadioAssert.h b/tos/chips/rf2xx/util/RadioAssert.h new file mode 100644 index 00000000..79ff1802 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioAssert.h @@ -0,0 +1,38 @@ +/* + * 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 __RADIOASSERT_H__ +#define __RADIOASSERT_H__ + +#ifdef RADIO_DEBUG + + void assert(bool condition, const char* file, uint16_t line); + #define ASSERT(COND) assert(COND, __FILE__, __LINE__) + +#else + + #define ASSERT(COND) for(;0;) + +#endif + +#endif//__RADIOASSERT_H__ diff --git a/tos/chips/rf2xx/util/RadioCCA.nc b/tos/chips/rf2xx/util/RadioCCA.nc new file mode 100755 index 00000000..78e16949 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioCCA.nc @@ -0,0 +1,42 @@ +/* + * 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 + +interface RadioCCA +{ + /** + * Starts the clear channel assesment procedure. Returns EBUSY if the radio + * is currently servicing a clear channel assesment, and SUCCESS otherwise. + * The check will be performed only in the RX_READY state. + */ + tasklet_async command error_t request(); + + /** + * Signals the completion of the clear channel assesment send command. + * SUCCESS means the channel is clear, EBUSY means the channel is not + * clear, and FAIL means that the clear channel assesment could not + * be finished or the operation was cancelled. + */ + tasklet_async event void done(error_t error); +} diff --git a/tos/chips/rf2xx/util/RadioChannel.nc b/tos/chips/rf2xx/util/RadioChannel.nc new file mode 100644 index 00000000..5fa6c247 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioChannel.nc @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2009, Vanderbilt University + * All rights reserved. + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT + * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Author: Miklos Maroti + */ + +interface RadioChannel +{ + /** + * Sets the current channel. Returns EBUSY if the stack is unable + * to change the channel this time (some other operation is in progress), + * EALREADY if the selected channel is already set, SUCCESS otherwise. + */ + command error_t setChannel(uint8_t channel); + + /** + * This event is signaled exactly once for each sucessfully posted state + * setChannel command when it is completed. + */ + event void setChannelDone(); + + /** + * Returns the currently selected channel. + */ + command uint8_t getChannel(); +} diff --git a/tos/chips/rf2xx/util/RadioReceive.nc b/tos/chips/rf2xx/util/RadioReceive.nc new file mode 100755 index 00000000..0e8330f9 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioReceive.nc @@ -0,0 +1,43 @@ +/* + * 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 + +interface RadioReceive +{ + /** + * This event is fired when the header is received/downloaded and the + * higher layers are consulted whether it needs to be downloaded and + * further processed. Return FALSE if the message should be discarded. + * In particular, the message buffer layer returns FALSE if there is + * no space for a new message, so this message will not get acknowledged. + */ + tasklet_async event bool header(message_t* msg); + + /** + * Signals the reception of a message, but only for those messages for + * which SUCCESS was returned in the header event. The usual owner rules + * apply to the message pointers. + */ + tasklet_async event message_t* receive(message_t* msg); +} diff --git a/tos/chips/rf2xx/util/RadioSend.nc b/tos/chips/rf2xx/util/RadioSend.nc new file mode 100755 index 00000000..59437946 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioSend.nc @@ -0,0 +1,53 @@ +/* + * 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 + +interface RadioSend +{ + /** + * Starts the transmission of the given message. This command must not + * be called while another send is in progress (so one must wait for the + * sendDone event). Returns EBUSY if a reception is in progress or for + * some other reason the request cannot be temporarily satisfied (e.g. + * the SPI bus access could not be acquired). In this case the send + * command could be retried from a tasklet. Returns SUCCESS if the + * transmission could be started. In this case sendDone will be fired. + */ + tasklet_async command error_t send(message_t* msg); + + /** + * Signals the completion of the send command, exactly once for each + * successfull send command. If the returned error code is SUCCESS, then + * the message was sent (may not have been acknowledged), otherwise + * the message was not transmitted over the air. + */ + tasklet_async event void sendDone(error_t error); + + /** + * This event is fired when the component is most likely able to accept + * a send request. If the send command has returned with a failure, then + * this event will be called at least once in the near future. + */ + tasklet_async event void ready(); +} diff --git a/tos/chips/rf2xx/util/RadioState.nc b/tos/chips/rf2xx/util/RadioState.nc new file mode 100644 index 00000000..cae77813 --- /dev/null +++ b/tos/chips/rf2xx/util/RadioState.nc @@ -0,0 +1,64 @@ +/* + * 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 + +interface RadioState +{ + /** + * Moves to radio into sleep state with the lowest power consumption but + * highest wakeup time. The radio cannot send or receive in this state + * and releases all access to shared resources (e.g. SPI bus). + */ + tasklet_async command error_t turnOff(); + + /** + * The same as the turnOff command, except it is not as deep sleep, and + * it is quicker to recover from this state. + */ + tasklet_async command error_t standby(); + + /** + * Goes into receive state. The radio continuously receive messages + * and able to transmit. + */ + tasklet_async command error_t turnOn(); + + /** + * Sets the current channel. Returns EBUSY if the stack is unable + * to change the channel this time (some other operation is in progress) + * SUCCESS otherwise. + */ + tasklet_async command error_t setChannel(uint8_t channel); + + /** + * This event is signaled exactly once for each sucessfully posted state + * transition and setChannel command when it is completed. + */ + tasklet_async event void done(); + + /** + * Returns the currently selected channel. + */ + tasklet_async command uint8_t getChannel(); +} diff --git a/tos/chips/rf2xx/util/Tasklet.h b/tos/chips/rf2xx/util/Tasklet.h new file mode 100644 index 00000000..e4cd520c --- /dev/null +++ b/tos/chips/rf2xx/util/Tasklet.h @@ -0,0 +1,39 @@ +/* + * 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 __TASKLET_H__ +#define __TASKLET_H__ + +#ifdef TASKLET_IS_TASK + + #define tasklet_async + #define tasklet_norace + +#else + + #define tasklet_async async + #define tasklet_norace norace + +#endif + +#endif//__TASKLET_H__ diff --git a/tos/chips/rf2xx/util/Tasklet.nc b/tos/chips/rf2xx/util/Tasklet.nc new file mode 100755 index 00000000..527400aa --- /dev/null +++ b/tos/chips/rf2xx/util/Tasklet.nc @@ -0,0 +1,69 @@ +/* + * 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 + +/** + * This interface is useful in building state machines when the state + * transitions should be executed atomically but with interrupts enabled. + * All state transitions should take place in the run event handler or + * in blocks protected by the suspend and resume commands. + */ +interface Tasklet +{ + /** + * This method is executed atomically. + */ + tasklet_async event void run(); + + /** + * Makes sure that the run event is called at least once more. If the + * run event is currently not executing, then it is called immediately + * and this command returns only after the completion of the run event. + * If the run event is currently executed, then this method returns at + * once, and makes sure that the run event is called once more when + * it is finished. If this method is called from a task, then by the + * above rules, the run event will be called from a task as well. + */ + async command void schedule(); + + /** + * Enters a critical section of the code and meakes sure that the + * run event is not called while in this section. No long running + * computation should be called from the critical session, and + * in particular no user event should be fired. This call is only + * possible from task context, otherwise we cannot guarantee that + * the run event is not currently running. The suspend calls + * can be nested. It is very important that the same number of + * resume commands must be called in all control paths, e.g. be very + * careful with the return and break commands. + */ + command void suspend(); + + /** + * Leaves the critical section. This call is conly possible from + * task context. If there were scheduled executions of the run + * event, then those will be called before this command returns. + */ + command void resume(); +} diff --git a/tos/chips/rf2xx/util/TaskletC.nc b/tos/chips/rf2xx/util/TaskletC.nc new file mode 100755 index 00000000..360f54fb --- /dev/null +++ b/tos/chips/rf2xx/util/TaskletC.nc @@ -0,0 +1,118 @@ +/* + * 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 TaskletC +{ + provides interface Tasklet; +} + +implementation +{ +#ifdef TASKLET_IS_TASK + + task void tasklet() + { + signal Tasklet.run(); + } + + inline async command void Tasklet.schedule() + { + post tasklet(); + } + + inline command void Tasklet.suspend() + { + } + + inline command void Tasklet.resume() + { + } + +#else + + /** + * The lower 7 bits contain the number of suspends plus one if the run + * event is currently beeing executed. The highest bit is set if the run + * event needs to be called again when the suspend count goes down to zero. + */ + uint8_t state; + + void doit() + { + for(;;) + { + signal Tasklet.run(); + + atomic + { + if( state == 1 ) + { + state = 0; + return; + } + + ASSERT( state == 0x81 ); + state = 1; + } + } + } + + inline command void Tasklet.suspend() + { + atomic ++state; + } + + command void Tasklet.resume() + { + atomic + { + if( --state != 0x80 ) + return; + + state = 1; + } + + doit(); + } + + async command void Tasklet.schedule() + { + atomic + { + if( state != 0 ) + { + state |= 0x80; + return; + } + + state = 1; + } + + doit(); + } + +#endif +} diff --git a/tos/platforms/iris/.platform b/tos/platforms/iris/.platform index 26d4d13f..1f97d154 100644 --- a/tos/platforms/iris/.platform +++ b/tos/platforms/iris/.platform @@ -13,8 +13,9 @@ push( @includes, qw( %T/platforms/micaz %T/platforms/mica %T/platforms/iris/chips/rf230 - %T/chips/rf230 - %T/chips/cc2420 + %T/chips/rf2xx/rf230 + %T/chips/rf2xx/layers + %T/chips/rf2xx/util %T/platforms/iris/chips/at45db %T/platforms/mica2/chips/at45db %T/platforms/mica/chips/at45db diff --git a/tos/platforms/iris/ActiveMessageC.nc b/tos/platforms/iris/ActiveMessageC.nc index f16da57a..649ae6f3 100644 --- a/tos/platforms/iris/ActiveMessageC.nc +++ b/tos/platforms/iris/ActiveMessageC.nc @@ -43,7 +43,7 @@ configuration ActiveMessageC implementation { - components RF2xxActiveMessageC as MAC; + components RF230ActiveMessageC as MAC; SplitControl = MAC; AMSend = MAC; @@ -53,7 +53,7 @@ implementation AMPacket = MAC; PacketAcknowledgements = MAC; - LowPowerListening = MAC; + LowPowerListening = MAC; PacketTimeStampMilli = MAC; PacketTimeStampMicro = MAC; } diff --git a/tos/platforms/iris/TimeSyncMessageC.nc b/tos/platforms/iris/TimeSyncMessageC.nc index 4bca9f68..2acab4c0 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,19 @@ configuration TimeSyncMessageC implementation { - components RF2xxTimeSyncMessageC; + components GenericTimeSyncMessageC as MAC, LocalTimeMicroC, RF230PacketC; - SplitControl = RF2xxTimeSyncMessageC; - - Receive = RF2xxTimeSyncMessageC.Receive; - Snoop = RF2xxTimeSyncMessageC.Snoop; - Packet = RF2xxTimeSyncMessageC; - AMPacket = RF2xxTimeSyncMessageC; - - TimeSyncAMSendRadio = RF2xxTimeSyncMessageC; - TimeSyncPacketRadio = RF2xxTimeSyncMessageC; - TimeSyncAMSendMilli = RF2xxTimeSyncMessageC; - TimeSyncPacketMilli = RF2xxTimeSyncMessageC; + SplitControl = MAC; + Receive = MAC.Receive; + Snoop = MAC.Snoop; + Packet = MAC; + AMPacket = MAC; + + TimeSyncAMSendRadio = MAC; + TimeSyncPacketRadio = MAC; + TimeSyncAMSendMilli = MAC; + TimeSyncPacketMilli = MAC; + + MAC.PacketTimeSyncOffset -> RF230PacketC.PacketTimeSyncOffset; + MAC.LocalTimeRadio -> LocalTimeMicroC; } diff --git a/tos/platforms/iris/chips/rf230/HplRF230C.nc b/tos/platforms/iris/chips/rf230/HplRF230C.nc new file mode 100644 index 00000000..3753b483 --- /dev/null +++ b/tos/platforms/iris/chips/rf230/HplRF230C.nc @@ -0,0 +1,67 @@ +/* + * 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 = SpiC; + + 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 new file mode 100644 index 00000000..761a2a96 --- /dev/null +++ b/tos/platforms/iris/chips/rf230/HplRF230P.nc @@ -0,0 +1,82 @@ +/* + * 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 + */ + +module HplRF230P +{ + provides + { + interface GpioCapture as IRQ; + interface Init as PlatformInit; + } + + 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(); + } +} diff --git a/tos/platforms/iris/chips/rf230/HplRF2xx.h b/tos/platforms/iris/chips/rf230/HplRF2xx.h deleted file mode 100644 index e312080f..00000000 --- a/tos/platforms/iris/chips/rf230/HplRF2xx.h +++ /dev/null @@ -1,76 +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 __HPLRF2XX_H__ -#define __HPLRF2XX_H__ - -#include -#include - -enum -{ - /** - * 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 - -#define RF2XX_CHIPSET RF230_CHIPSET - -/* - * 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 deleted file mode 100644 index 8d9a27fc..00000000 --- a/tos/platforms/iris/chips/rf230/HplRF2xxC.nc +++ /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 - */ - -#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 = SpiC; - - 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 deleted file mode 100644 index 3a06d1c2..00000000 --- a/tos/platforms/iris/chips/rf230/HplRF2xxP.nc +++ /dev/null @@ -1,84 +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 "Atm128Spi.h" - -module HplRF2xxP -{ - provides - { - interface GpioCapture as IRQ; - interface Init as PlatformInit; - } - - 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(); - } -} diff --git a/tos/platforms/iris/chips/rf230/RadioAlarm.h b/tos/platforms/iris/chips/rf230/RadioAlarm.h deleted file mode 100644 index 42b3d53c..00000000 --- a/tos/platforms/iris/chips/rf230/RadioAlarm.h +++ /dev/null @@ -1,40 +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 __RADIOALARM_H__ -#define __RADIOALARM_H__ - -#include - -/** - * This is the timer type of the radio alarm interface - */ -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. - */ -#define RADIO_ALARM_MICROSEC (7372800UL / MHZ / 32) * (1 << MICA_DIVIDE_ONE_FOR_32KHZ_LOG2) / 1000000UL - -#endif//__RADIOALARM_H__ diff --git a/tos/platforms/iris/chips/rf230/RadioConfig.h b/tos/platforms/iris/chips/rf230/RadioConfig.h new file mode 100644 index 00000000..703f2ea7 --- /dev/null +++ b/tos/platforms/iris/chips/rf230/RadioConfig.h @@ -0,0 +1,87 @@ +/* + * 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 __RADIOCONFIG_H__ +#define __RADIOCONFIG_H__ + +#include +#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 + +/* + * 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 RF230_CRCBYTE_COMMAND(uint16_t crc, uint8_t data) +{ + return _crc_ccitt_update(crc, data); +} + +/** + * This is the timer type of the radio alarm interface + */ +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. + */ +#define RADIO_ALARM_MICROSEC (7372800UL / MHZ / 32) * (1 << MICA_DIVIDE_ONE_FOR_32KHZ_LOG2) / 1000000UL + +/** + * The base two logarithm of the number of radio alarm ticks per one millisecond + */ +#define RADIO_ALARM_MILLI_EXP 10 + +#endif//__RADIOCONFIG_H__ diff --git a/tos/platforms/iris/platform_message.h b/tos/platforms/iris/platform_message.h index cdf078ae..e3245c96 100644 --- a/tos/platforms/iris/platform_message.h +++ b/tos/platforms/iris/platform_message.h @@ -23,20 +23,20 @@ #ifndef PLATFORM_MESSAGE_H #define PLATFORM_MESSAGE_H -#include +#include #include typedef union message_header { - rf2xxpacket_header_t rf2xx; + rf230packet_header_t rf230; serial_header_t serial; } message_header_t; typedef union message_footer { - rf2xxpacket_footer_t rf2xx; + rf230packet_footer_t rf230; } message_footer_t; typedef union message_metadata { - rf2xxpacket_metadata_t rf2xx; + rf230packet_metadata_t rf230; } message_metadata_t; #endif