--- /dev/null
+/**
+ *
+ * @author André Cunha
+ * @version 1.0
+ */
+
+interface AddressFilter {
+
+
+ command error_t set_address(uint16_t mac_short_address, uint32_t mac_extended0, uint32_t mac_extended1);
+
+
+ command error_t set_coord_address(uint16_t mac_coord_address, uint16_t mac_panid);
+
+
+ command error_t enable_address_decode(uint8_t enable);
+
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation for configuring a ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "CC2420.h"
+#include "IEEE802154.h"
+
+configuration CC2420ControlC {
+
+ provides interface Resource;
+ provides interface CC2420Config;
+ provides interface CC2420Power;
+ provides interface Read<uint16_t> as ReadRssi;
+
+ // provides interface Read_rssi;
+
+}
+
+implementation {
+
+ components CC2420ControlP;
+ Resource = CC2420ControlP;
+ CC2420Config = CC2420ControlP;
+ CC2420Power = CC2420ControlP;
+ ReadRssi = CC2420ControlP;
+
+ //Read_rssi = CC2420ControlP;
+
+ components MainC;
+ MainC.SoftwareInit -> CC2420ControlP;
+
+ //components CC2420ActiveMessageC;
+ //CC2420ControlP.AMPacket -> CC2420ActiveMessageC;
+
+ components AlarmMultiplexC as Alarm;
+ CC2420ControlP.StartupTimer -> Alarm;
+
+ components HplCC2420PinsC as Pins;
+ CC2420ControlP.CSN -> Pins.CSN;
+ CC2420ControlP.RSTN -> Pins.RSTN;
+ CC2420ControlP.VREN -> Pins.VREN;
+
+ components HplCC2420InterruptsC as Interrupts;
+ CC2420ControlP.InterruptCCA -> Interrupts.InterruptCCA;
+
+ components new CC2420SpiC() as Spi;
+ CC2420ControlP.SpiResource -> Spi;
+ CC2420ControlP.SRXON -> Spi.SRXON;
+ CC2420ControlP.SRFOFF -> Spi.SRFOFF;
+ CC2420ControlP.SXOSCON -> Spi.SXOSCON;
+ CC2420ControlP.SXOSCOFF -> Spi.SXOSCOFF;
+ CC2420ControlP.FSCTRL -> Spi.FSCTRL;
+ CC2420ControlP.IOCFG0 -> Spi.IOCFG0;
+ CC2420ControlP.IOCFG1 -> Spi.IOCFG1;
+ CC2420ControlP.MDMCTRL0 -> Spi.MDMCTRL0;
+ CC2420ControlP.MDMCTRL1 -> Spi.MDMCTRL1;
+ CC2420ControlP.PANID -> Spi.PANID;
+ CC2420ControlP.RXCTRL1 -> Spi.RXCTRL1;
+ CC2420ControlP.RSSI -> Spi.RSSI;
+
+
+
+ components new CC2420SpiC() as SyncSpiC;
+ CC2420ControlP.SyncResource -> SyncSpiC;
+
+ components new CC2420SpiC() as RssiResource;
+ CC2420ControlP.RssiResource -> RssiResource;
+
+ //components ActiveMessageAddressC;
+ //CC2420ControlP.ActiveMessageAddress -> ActiveMessageAddressC;
+
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Urs Hunkeler (ReadRssi implementation)
+ * @version $Revision$ $Date$
+ */
+
+#include "Timer.h"
+
+module CC2420ControlP {
+
+ provides interface Init;
+ provides interface Resource;
+ provides interface CC2420Config;
+ provides interface CC2420Power;
+ provides interface Read<uint16_t> as ReadRssi;
+
+ // provides interface Read_rssi;
+
+ uses interface Alarm<T32khz,uint32_t> as StartupTimer;
+ uses interface GeneralIO as CSN;
+ uses interface GeneralIO as RSTN;
+ uses interface GeneralIO as VREN;
+ uses interface GpioInterrupt as InterruptCCA;
+ //uses interface ActiveMessageAddress;
+
+ uses interface CC2420Ram as PANID;
+ uses interface CC2420Register as FSCTRL;
+ uses interface CC2420Register as IOCFG0;
+ uses interface CC2420Register as IOCFG1;
+ uses interface CC2420Register as MDMCTRL0;
+ uses interface CC2420Register as MDMCTRL1;
+ uses interface CC2420Register as RXCTRL1;
+ uses interface CC2420Register as RSSI;
+ uses interface CC2420Strobe as SRXON;
+ uses interface CC2420Strobe as SRFOFF;
+ uses interface CC2420Strobe as SXOSCOFF;
+ uses interface CC2420Strobe as SXOSCON;
+ // uses interface AMPacket;
+
+ uses interface Resource as SpiResource;
+ uses interface Resource as RssiResource;
+ uses interface Resource as SyncResource;
+
+ uses interface Leds;
+
+}
+
+implementation {
+
+ typedef enum {
+ S_VREG_STOPPED,
+ S_VREG_STARTING,
+ S_VREG_STARTED,
+ S_XOSC_STARTING,
+ S_XOSC_STARTED,
+ } cc2420_control_state_t;
+
+ uint8_t m_channel;
+
+ uint8_t m_tx_power;
+
+ uint16_t m_pan;
+
+ uint16_t m_short_addr;
+
+ bool m_sync_busy;
+
+ bool autoAckEnabled;
+
+ bool hwAutoAckDefault;
+
+ bool addressRecognition;
+
+ norace cc2420_control_state_t m_state = S_VREG_STOPPED;
+
+ /***************** Prototypes ****************/
+
+ void writeFsctrl();
+ void writeMdmctrl0();
+ void writeId();
+
+ task void sync();
+ task void syncDone();
+
+ /***************** Init Commands ****************/
+ command error_t Init.init() {
+ call CSN.makeOutput();
+ call RSTN.makeOutput();
+ call VREN.makeOutput();
+
+ //m_short_addr = call ActiveMessageAddress.amAddress();
+ // m_pan = call ActiveMessageAddress.amGroup();
+ m_tx_power = CC2420_DEF_RFPOWER;
+
+ //m_channel = CC2420_DEF_CHANNEL;
+ m_channel = LOGICAL_CHANNEL;
+
+
+//#if defined(CC2420_NO_ACKNOWLEDGEMENTS)
+ autoAckEnabled = FALSE;
+//#else
+// autoAckEnabled = TRUE;
+//#endif
+
+//#if defined(CC2420_HW_ACKNOWLEDGEMENTS)
+// hwAutoAckDefault = TRUE;
+//#else
+ hwAutoAckDefault = FALSE;
+//#endif
+
+//#if defined(CC2420_NO_ADDRESS_RECOGNITION)
+ addressRecognition = FALSE;
+//#else
+// addressRecognition = TRUE;
+//#endif
+
+ return SUCCESS;
+ }
+
+ /***************** Resource Commands ****************/
+ async command error_t Resource.immediateRequest() {
+ error_t error = call SpiResource.immediateRequest();
+ if ( error == SUCCESS ) {
+ call CSN.clr();
+ }
+ return error;
+ }
+
+ async command error_t Resource.request() {
+ return call SpiResource.request();
+ }
+
+ async command uint8_t Resource.isOwner() {
+ return call SpiResource.isOwner();
+ }
+
+ async command error_t Resource.release() {
+ atomic {
+ call CSN.set();
+ return call SpiResource.release();
+ }
+ }
+
+ /***************** CC2420Power Commands ****************/
+ async command error_t CC2420Power.startVReg() {
+ atomic {
+ if ( m_state != S_VREG_STOPPED ) {
+ return FAIL;
+ }
+ m_state = S_VREG_STARTING;
+ }
+ call VREN.set();
+ call StartupTimer.start( CC2420_TIME_VREN );
+ return SUCCESS;
+ }
+
+ async command error_t CC2420Power.stopVReg() {
+ m_state = S_VREG_STOPPED;
+ call RSTN.clr();
+ call VREN.clr();
+ call RSTN.set();
+ return SUCCESS;
+ }
+
+ async command error_t CC2420Power.startOscillator() {
+ atomic {
+ //if ( m_state != S_VREG_STARTED ) {
+ // return FAIL;
+ //}
+
+ //m_state = S_XOSC_STARTING;
+
+ /*
+ call IOCFG1.write( CC2420_SFDMUX_XOSC16M_STABLE <<
+ CC2420_IOCFG1_CCAMUX );
+ */
+ call IOCFG1.write(0x0018);
+
+ call InterruptCCA.enableRisingEdge();
+ call SXOSCON.strobe();
+ /*
+ call IOCFG0.write( ( 1 << CC2420_IOCFG0_FIFOP_POLARITY ) |
+ ( 127 << CC2420_IOCFG0_FIFOP_THR ) );
+ */
+ call IOCFG0.write(0x027F);
+
+
+ writeFsctrl();
+
+
+ //call FSCTRL.write(0x4192);
+ //initial set of frequency channel
+ //call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) | ( ( (LOGICAL_CHANNEL - 11)*5+357) << CC2420_FSCTRL_FREQ ) );
+
+ //call MDMCTRL0.write(0x0AE2);
+ call MDMCTRL0.write(0x02E2);
+
+ //CHANGE
+ writeMdmctrl0();
+ //call RXCTRL1.write(0x0A56);
+
+ /*
+ call RXCTRL1.write( ( 1 << CC2420_RXCTRL1_RXBPF_LOCUR ) |
+ ( 1 << CC2420_RXCTRL1_LOW_LOWGAIN ) |
+ ( 1 << CC2420_RXCTRL1_HIGH_HGM ) |
+ ( 1 << CC2420_RXCTRL1_LNA_CAP_ARRAY ) |
+ ( 1 << CC2420_RXCTRL1_RXMIX_TAIL ) |
+ ( 1 << CC2420_RXCTRL1_RXMIX_VCM ) |
+ ( 2 << CC2420_RXCTRL1_RXMIX_CURRENT ) );
+ */
+ }
+ return SUCCESS;
+ }
+
+
+ async command error_t CC2420Power.stopOscillator() {
+ atomic {
+ if ( m_state != S_XOSC_STARTED ) {
+ return FAIL;
+ }
+ m_state = S_VREG_STARTED;
+ call SXOSCOFF.strobe();
+ }
+ return SUCCESS;
+ }
+
+ async command error_t CC2420Power.rxOn() {
+ atomic {
+ if ( m_state != S_XOSC_STARTED ) {
+ return FAIL;
+ }
+ call SRXON.strobe();
+ }
+ return SUCCESS;
+ }
+
+ async command error_t CC2420Power.rfOff() {
+ atomic {
+ if ( m_state != S_XOSC_STARTED ) {
+ return FAIL;
+ }
+ call SRFOFF.strobe();
+ }
+ return SUCCESS;
+ }
+
+
+ /***************** CC2420Config Commands ****************/
+ command uint8_t CC2420Config.getChannel() {
+ atomic return m_channel;
+ }
+
+ command void CC2420Config.setChannel( uint8_t channel ) {
+ atomic m_channel = channel;
+
+ }
+
+ async command uint16_t CC2420Config.getShortAddr() {
+ atomic return m_short_addr;
+ }
+
+ command void CC2420Config.setShortAddr( uint16_t addr ) {
+ atomic m_short_addr = addr;
+ }
+
+ async command uint16_t CC2420Config.getPanAddr() {
+ atomic return m_pan;
+ }
+
+ command void CC2420Config.setPanAddr( uint16_t pan ) {
+ atomic m_pan = pan;
+ }
+
+ /**
+ * Sync must be called to commit software parameters configured on
+ * the microcontroller (through the CC2420Config interface) to the
+ * CC2420 radio chip.
+ */
+ command error_t CC2420Config.sync() {
+ atomic {
+ if ( m_sync_busy ) {
+ return FAIL;
+ }
+
+ m_sync_busy = TRUE;
+ if ( m_state == S_XOSC_STARTED ) {
+ call SyncResource.request();
+ } else {
+ post syncDone();
+ }
+ }
+ return SUCCESS;
+ }
+
+ /**
+ * @param on TRUE to turn address recognition on, FALSE to turn it off
+ */
+ command void CC2420Config.setAddressRecognition(bool on) {
+ atomic addressRecognition = on;
+ }
+
+ /**
+ * @return TRUE if address recognition is enabled
+ */
+ async command bool CC2420Config.isAddressRecognitionEnabled() {
+ atomic return addressRecognition;
+ }
+
+
+ /**
+ * Sync must be called for acknowledgement changes to take effect
+ * @param enableAutoAck TRUE to enable auto acknowledgements
+ * @param hwAutoAck TRUE to default to hardware auto acks, FALSE to
+ * default to software auto acknowledgements
+ */
+ command void CC2420Config.setAutoAck(bool enableAutoAck, bool hwAutoAck) {
+ autoAckEnabled = enableAutoAck;
+ hwAutoAckDefault = hwAutoAck;
+ }
+
+ /**
+ * @return TRUE if hardware auto acks are the default, FALSE if software
+ * acks are the default
+ */
+ async command bool CC2420Config.isHwAutoAckDefault() {
+ atomic return hwAutoAckDefault;
+ }
+
+ /**
+ * @return TRUE if auto acks are enabled
+ */
+ async command bool CC2420Config.isAutoAckEnabled() {
+ atomic return autoAckEnabled;
+ }
+
+ /***************** ReadRssi Commands ****************/
+ command error_t ReadRssi.read() {
+ return call RssiResource.request();
+ }
+
+ /***************** Spi Resources Events ****************/
+ event void SyncResource.granted() {
+ //possibly this is on the sync of the new configuration of the transceiver //CHECK
+
+ call CSN.clr();
+ call SRFOFF.strobe();
+
+ writeFsctrl();
+ //CHANGE
+ writeMdmctrl0();
+ writeId();
+ call CSN.set();
+ call CSN.clr();
+ call SRXON.strobe();
+ call CSN.set();
+ call SyncResource.release();
+ post syncDone();
+ }
+
+ event void SpiResource.granted() {
+ call CSN.clr();
+ signal Resource.granted();
+ }
+
+ event void RssiResource.granted() {
+ uint16_t data;
+ call CSN.clr();
+ call RSSI.read(&data);
+ call CSN.set();
+
+ call RssiResource.release();
+ data += 0x7f;
+ data &= 0x00ff;
+ //signal ReadRssi.readDone(SUCCESS, data);
+
+ //signal Read_rssi.readDone(SUCCESS, data);
+ }
+
+ /***************** StartupTimer Events ****************/
+ async event void StartupTimer.fired() {
+ if ( m_state == S_VREG_STARTING ) {
+ m_state = S_VREG_STARTED;
+ call RSTN.clr();
+ call RSTN.set();
+ signal CC2420Power.startVRegDone();
+ }
+ }
+
+ /***************** InterruptCCA Events ****************/
+ async event void InterruptCCA.fired() {
+ m_state = S_XOSC_STARTED;
+ call InterruptCCA.disable();
+ call IOCFG1.write( 0 );
+ writeId();
+ call CSN.set();
+ call CSN.clr();
+ signal CC2420Power.startOscillatorDone();
+ }
+
+ /***************** ActiveMessageAddress Events ****************/
+ /*
+ async event void ActiveMessageAddress.changed() {
+ atomic {
+ m_short_addr = call ActiveMessageAddress.amAddress();
+ m_pan = call ActiveMessageAddress.amGroup();
+ }
+
+ post sync();
+ }
+ */
+ /***************** Tasks ****************/
+ /**
+ * Attempt to synchronize our current settings with the CC2420
+ */
+ task void sync() {
+ call CC2420Config.sync();
+ }
+
+ task void syncDone() {
+ atomic m_sync_busy = FALSE;
+ signal CC2420Config.syncDone( SUCCESS );
+ }
+
+
+ /***************** Functions ****************/
+ /**
+ * Write teh FSCTRL register
+ */
+ void writeFsctrl() {
+ uint8_t channel;
+
+ atomic {
+ channel = m_channel;
+ }
+
+ call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
+ ( ( (channel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) );
+ /*
+ call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
+ ( channel << CC2420_FSCTRL_FREQ ) );
+ */
+ }
+
+ /**
+ * Write the MDMCTRL0 register
+ */
+ void writeMdmctrl0() {
+ atomic {
+ call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) |
+ ( addressRecognition << CC2420_MDMCTRL0_ADR_DECODE ) |
+ ( 2 << CC2420_MDMCTRL0_CCA_HYST ) |
+ ( 3 << CC2420_MDMCTRL0_CCA_MOD ) |
+ ( 1 << CC2420_MDMCTRL0_AUTOCRC ) |
+ ( (autoAckEnabled && hwAutoAckDefault) << CC2420_MDMCTRL0_AUTOACK ) |
+ ( 0 << CC2420_MDMCTRL0_AUTOACK ) |
+ ( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) );
+ }
+ // Jon Green:
+ // MDMCTRL1.CORR_THR is defaulted to 20 instead of 0 like the datasheet says
+ // If we add in changes to MDMCTRL1, be sure to include this fix.
+ }
+
+ /**
+ * Write the PANID register
+ */
+ void writeId() {
+ nxle_uint16_t id[ 2 ];
+
+ atomic {
+ id[ 0 ] = m_pan;
+ id[ 1 ] = m_short_addr;
+ }
+
+ call PANID.write(0, (uint8_t*)&id, sizeof(id));
+ }
+
+
+
+ /***************** Defaults ****************/
+ default event void CC2420Config.syncDone( error_t error ) {
+ }
+
+ default event void ReadRssi.readDone(error_t error, uint16_t data) {
+ }
+
+ /*
+
+ command error_t Read_rssi.read() {
+ return call RssiResource.request();
+ }
+ */
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation of the receive path for the ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+
+
+configuration CC2420ReceiveC {
+
+ provides interface StdControl;
+
+ provides interface Receiveframe;
+
+ provides interface AddressFilter;
+
+}
+
+implementation {
+ components MainC;
+ components CC2420ReceiveP;
+
+ components new CC2420SpiC() as Spi;
+ components CC2420ControlC;
+
+ components HplCC2420PinsC as Pins;
+ components HplCC2420InterruptsC as InterruptsC;
+
+ components LedsC as Leds;
+ CC2420ReceiveP.Leds -> Leds;
+
+ StdControl = CC2420ReceiveP;
+
+ Receiveframe = CC2420ReceiveP;
+
+ AddressFilter = CC2420ReceiveP;
+
+
+ MainC.SoftwareInit -> CC2420ReceiveP;
+
+ CC2420ReceiveP.CSN -> Pins.CSN;
+ CC2420ReceiveP.FIFO -> Pins.FIFO;
+ CC2420ReceiveP.FIFOP -> Pins.FIFOP;
+ CC2420ReceiveP.InterruptFIFOP -> InterruptsC.InterruptFIFOP;
+ CC2420ReceiveP.SpiResource -> Spi;
+ CC2420ReceiveP.RXFIFO -> Spi.RXFIFO;
+ CC2420ReceiveP.SFLUSHRX -> Spi.SFLUSHRX;
+ CC2420ReceiveP.SACK -> Spi.SACK;
+
+ CC2420ReceiveP.CC2420Config -> CC2420ControlC;
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Jung Il Choi
+ * @version $Revision$ $Date$
+ */
+
+#include "printfUART.h"
+#include "frame_format.h"
+#include "mac_func.h"
+
+module CC2420ReceiveP {
+
+ provides interface Init;
+ provides interface StdControl;
+ //provides interface CC2420Receive;
+ //provides interface Receive;
+ //provides interface ReceiveIndicator as PacketIndicator;
+
+ provides interface Receiveframe;
+
+ provides interface AddressFilter;
+
+
+
+ uses interface GeneralIO as CSN;
+ uses interface GeneralIO as FIFO;
+ uses interface GeneralIO as FIFOP;
+ uses interface GpioInterrupt as InterruptFIFOP;
+
+ uses interface Resource as SpiResource;
+ uses interface CC2420Fifo as RXFIFO;
+ uses interface CC2420Strobe as SACK;
+ uses interface CC2420Strobe as SFLUSHRX;
+ //uses interface CC2420Packet;
+ //uses interface CC2420PacketBody;
+ uses interface CC2420Config;
+
+ uses interface Leds;
+
+
+
+
+
+}
+
+implementation {
+
+typedef enum{
+ S_STOPPED =0,
+ S_STARTED=1,
+ S_RX_LENGTH=2,
+ S_RX_FC=3, //FC - FRAME CONTROL
+ S_RX_ADDR=4,
+ S_RX_PAYLOAD=5,
+ S_RX_DISCARD=6,
+}cc2420_receive_state_t;
+
+
+/*
+ typedef enum {
+ S_STOPPED,
+ S_STARTED,
+ S_RX_LENGTH,
+ S_RX_FCF,
+ S_RX_PAYLOAD,
+ } cc2420_receive_state_t;
+ */
+ enum {
+ RXFIFO_SIZE = 128,
+ TIMESTAMP_QUEUE_SIZE = 8,
+ SACK_HEADER_LENGTH = 7,
+ };
+
+ //uint16_t m_timestamp_queue[ TIMESTAMP_QUEUE_SIZE ];
+
+ //uint8_t m_timestamp_head;
+
+ //uint8_t m_timestamp_size;
+
+ /** Number of packets we missed because we were doing something else */
+ uint8_t m_missed_packets;
+
+ /** TRUE if we are receiving a valid packet into the stack */
+ bool receivingPacket;
+
+ /** The length of the frame we're currently receiving */
+ norace uint8_t rxFrameLength;
+
+ //number of bytes left in the FIFO Buffer
+ norace uint8_t m_bytes_left;
+
+ //norace message_t* m_p_rx_buf;
+
+ //message_t m_rx_buf;
+
+ //already used
+ //cc2420_receive_state_t m_state;
+
+
+ norace MPDU rxmpdu;
+ MPDU *rxmpdu_ptr;
+
+
+ cc2420_receive_state_t m_state;
+
+
+ uint8_t rssi;
+
+
+ uint8_t receive_count=0;
+
+
+
+/*******************************************/
+/**** ADDRESS DECODE VARIABLES ****/
+/*******************************************/
+ //address verification frame control variables
+ //frame control variables
+ uint8_t source_address=0;
+ uint8_t destination_address=0;
+
+ //address verification structure pointers
+ dest_short *dest_short_ptr;
+ dest_long *dest_long_ptr;
+
+ source_short *source_short_ptr;
+ source_long *source_long_ptr;
+
+ beacon_addr_short *beacon_addr_short_ptr;
+
+ uint8_t address_decode = 1;
+
+ //address verification variables
+ uint16_t ver_macCoordShortAddress = 0x0000;
+ uint16_t ver_macShortAddress = 0xffff;
+
+ uint32_t ver_aExtendedAddress0=0x00000000;
+ uint32_t ver_aExtendedAddress1=0x00000000;
+
+ uint16_t ver_macPANId=0xffff;
+
+
+
+ /***************** Prototypes ****************/
+ void reset_state();
+ void beginReceive();
+ void receive();
+ void waitForNextPacket();
+ void flush();
+
+ // task void receiveDone_task();
+
+ /***************** Init Commands ****************/
+ command error_t Init.init() {
+ //m_p_rx_buf = &m_rx_buf;
+
+ rxmpdu_ptr = &rxmpdu;
+
+ printfUART_init();
+
+ return SUCCESS;
+ }
+
+ /***************** StdControl ****************/
+ command error_t StdControl.start() {
+
+ atomic {
+ reset_state();
+ m_state = S_STARTED;
+ atomic receivingPacket = FALSE;
+ call InterruptFIFOP.enableFallingEdge();
+ }
+
+
+
+ return SUCCESS;
+ }
+
+ command error_t StdControl.stop() {
+ atomic {
+ m_state = S_STOPPED;
+ reset_state();
+ call CSN.set();
+ call InterruptFIFOP.disable();
+ }
+ return SUCCESS;
+ }
+
+
+
+
+ command error_t AddressFilter.set_address(uint16_t mac_short_address, uint32_t mac_extended0, uint32_t mac_extended1)
+ {
+
+ ver_macShortAddress = mac_short_address;
+
+ ver_aExtendedAddress0=mac_extended0;
+ ver_aExtendedAddress1=mac_extended1;
+
+ address_decode = 1;
+
+ //printfUART("sa %i %x %x %x %x\n",address_decode,ver_macShortAddress,ver_aExtendedAddress0,ver_aExtendedAddress1);
+
+
+ return SUCCESS;
+ }
+
+
+ command error_t AddressFilter.set_coord_address(uint16_t mac_coord_address, uint16_t mac_panid)
+ {
+
+ ver_macCoordShortAddress = mac_coord_address;
+ ver_macPANId = mac_panid;
+
+ //printfUART("sca %i %x %x\n",address_decode,ver_macCoordShortAddress,ver_macPANId);
+
+ return SUCCESS;
+ }
+
+
+ command error_t AddressFilter.enable_address_decode(uint8_t enable)
+ {
+
+ address_decode = enable;
+
+ //printfUART("ead %i\n",address_decode);
+
+ return SUCCESS;
+ }
+
+
+
+
+ /***************** Receive Commands ****************/
+ /*
+ command void* Receive.getPayload(message_t* m, uint8_t* len) {
+
+ if (len != NULL) {
+ *len = ((uint8_t*) (call CC2420PacketBody.getHeader( m_p_rx_buf )))[0];
+ }
+ return m->data;
+ }
+
+ command uint8_t Receive.payloadLength(message_t* m) {
+ uint8_t* buf = (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf ));
+ return buf[0];
+ }
+
+ */
+ /***************** CC2420Receive Commands ****************/
+ /**
+ * Start frame delimiter signifies the beginning/end of a packet
+ * See the CC2420 datasheet for details.
+ */
+ /*
+ async command void CC2420Receive.sfd( uint16_t time ) {
+
+ if ( m_timestamp_size < TIMESTAMP_QUEUE_SIZE ) {
+ uint8_t tail = ( ( m_timestamp_head + m_timestamp_size ) %
+ TIMESTAMP_QUEUE_SIZE );
+ m_timestamp_queue[ tail ] = time;
+ m_timestamp_size++;
+ }
+
+ }
+
+ async command void CC2420Receive.sfd_dropped() {
+
+ if ( m_timestamp_size ) {
+ m_timestamp_size--;
+ }
+
+ }
+*/
+ /***************** PacketIndicator Commands ****************/
+ /*
+ command bool PacketIndicator.isReceiving() {
+ bool receiving;
+ atomic {
+ receiving = receivingPacket;
+ }
+ return receiving;
+ }
+
+ */
+ /***************** InterruptFIFOP Events ****************/
+ async event void InterruptFIFOP.fired() {
+
+ ////printfUART("Int %i\n",m_state);
+//call Leds.led1Toggle();
+ //call Leds.led2Toggle();
+
+
+ if ( m_state == S_STARTED ) {
+
+
+ beginReceive();
+
+
+ /*
+ if(call SpiResource.isOwner()) {
+ receive();
+
+ } else if (call SpiResource.immediateRequest() == SUCCESS) {
+ receive();
+
+ } else {
+ call SpiResource.request();
+ }
+*/
+ } else {
+ m_missed_packets++;
+ }
+
+ }
+
+
+ /***************** SpiResource Events ****************/
+ event void SpiResource.granted() {
+ receive();
+ }
+
+ /***************** RXFIFO Events ****************/
+ /**
+ * We received some bytes from the SPI bus. Process them in the context
+ * of the state we're in. Remember the length byte is not part of the length
+ */
+ async event void RXFIFO.readDone( uint8_t* rx_buf, uint8_t rx_len,error_t error ) {
+
+
+ //int i;
+ /*
+ uint8_t len;
+
+ //uint8_t rssi;
+ //uint8_t lqi;
+ int i;
+
+ len = rx_buf[0];
+
+ rssi= 255 - rx_buf[len-1];
+
+ //lqi = rssi & 0x7f;
+ */
+ /*
+
+ //printfUART("r d %i %i\n", len, rssi);
+
+ // len = rx_buf[0];
+ //rssi=rx_buf[len-2];
+
+
+ for (i=0;i<40;i++)
+ {
+ //printfUART("r %i %x\n",i,rx_buf[i]);
+ }
+
+
+
+
+ //signal Receiveframe.receive((uint8_t*)rxmpdu_ptr, rssi);
+
+ receive_count++;
+
+ if (receive_count == 2)
+ { flush();
+ receive_count =0;
+ }
+ */
+
+ atomic{
+ //my code
+ switch(m_state){
+
+ case S_RX_LENGTH:
+
+ rxFrameLength = rx_buf[0];
+
+ m_state = S_RX_FC;
+
+ //verify print
+ ////printfUART("LEN %x %x %i %i\n",rxFrameLength,rxmpdu_ptr->length,m_state,m_bytes_left);
+
+ //printfUART("r%i %i %i\n",rxmpdu_ptr->seq_num,rxFrameLength,MAC_PACKET_SIZE);
+
+ if ( rxFrameLength + 1 > m_bytes_left )
+ {
+ // Length of this packet is bigger than the RXFIFO, flush it out.
+ //printfUART("pkt too big\n","");
+ flush();
+
+ }
+ else
+ {
+ if ( !call FIFO.get() && !call FIFOP.get() )
+ {
+ //printfUART("RED left %x\n",m_bytes_left);
+
+ m_bytes_left -= rxFrameLength + 1;
+ }
+
+ //if(rxFrameLength <= MAC_PACKET_SIZE)
+ //{
+ if(rxFrameLength > 0)
+ {
+ //verify read length and read the frame control field (2 bytes)
+ if(rxFrameLength > 2) {
+ // This packet has an FCF byte plus at least one more byte to read
+ //call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH);
+
+ ////printfUART("LEN OK\n","");
+ //read frame control + sequence number
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 1, 3);
+ }
+ else
+ {
+ // This is really a bad packet, skip FCF and get it out of here.
+ //m_state = S_RX_PAYLOAD;
+
+ m_state = S_RX_DISCARD;
+ //printfUART("bad len\n","");
+
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 1, rxFrameLength);
+ return;
+ }
+ }
+ else
+ {
+ // Length == 0; start reading the next packet
+ atomic receivingPacket = FALSE;
+ call CSN.set();
+ call SpiResource.release();
+ waitForNextPacket();
+ }
+
+ //}
+ //else
+ //{
+ // Length is too large; we have to flush the entire Rx FIFO
+ // //printfUART("pkt too large\n","");
+ // flush();
+
+ // return;
+ //}
+ }
+ break;
+ case S_RX_FC:
+
+ //verify print
+ ////printfUART("FC %x %x %x %i\n",rxmpdu_ptr->frame_control1,rxmpdu_ptr->frame_control2,rxmpdu_ptr->seq_num, m_state);
+
+ if ((rxmpdu_ptr->frame_control1 & 0x7) == TYPE_ACK)
+ {
+ m_state = S_RX_PAYLOAD;
+
+ //printfUART("r ack \n","");
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr+4,2);
+ return;
+ }
+
+
+ if (address_decode == 1)
+ {
+ m_state = S_RX_ADDR;
+
+ destination_address=get_fc2_dest_addr(rxmpdu_ptr->frame_control2);
+
+ if (destination_address > 1)
+ {
+ switch(destination_address)
+ {
+ case SHORT_ADDRESS:
+ //read the short address + destination PAN identifier
+ ////printfUART("s ad","");
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 4, 6);
+ break;
+
+ case LONG_ADDRESS:
+ //read the long address + destination PAN identifier
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 4, 12);
+ break;
+ }
+ }
+ else
+ {
+ //destination address fields not present
+ m_state = S_RX_PAYLOAD;
+ //it is not possible to do the address decoding, there is no destination address fields
+ //send the full packet up
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 4, rxmpdu_ptr->length- 3);
+
+ }
+ }
+ else
+ {
+ //address decode is not activated
+ m_state = S_RX_PAYLOAD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 4, rxmpdu_ptr->length - 3);
+ }
+
+
+ break;
+ case S_RX_ADDR:
+ m_state = S_RX_PAYLOAD;
+
+
+ switch ((rxmpdu_ptr->frame_control1 & 0x7))
+ {
+ case TYPE_BEACON:
+ ////printfUART("RB \n","");
+
+ beacon_addr_short_ptr = (beacon_addr_short *) &rxmpdu_ptr->data[0];
+
+ ////printfUART("pb %x %x %x %x\n",rxmpdu_ptr->seq_num, beacon_addr_short_ptr->destination_PAN_identifier,beacon_addr_short_ptr->destination_address, beacon_addr_short_ptr->source_address);
+
+ /*
+ for (i=0;i<6;i++)
+ {
+ //printfUART("r %i %x %x %x\n",i,rxmpdu_ptr->data[i],rx_buf[i],rx_buf[i+4]);
+ }
+ */
+
+ //printfUART("RB %x %x \n",ver_macCoordShortAddress,ver_macShortAddress);
+
+
+ //avoid VERIFY static assignment of coordinator parent
+ if (beacon_addr_short_ptr->source_address != ver_macCoordShortAddress)
+ {
+ //printfUART("bad bec %x %x\n", beacon_addr_short_ptr->source_address,ver_macCoordShortAddress);
+
+ m_state = S_RX_DISCARD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 10, rxmpdu_ptr->length - 9);
+ return;
+ }
+ /*
+ if (ver_macShortAddress != 0xffff)
+ {
+ if ( beacon_addr_short_ptr->source_address != ver_macShortAddress)
+ {
+ //printfUART("pb %x %x\n", beacon_addr_short_ptr->source_address,ver_macShortAddress);
+
+ m_state = S_RX_DISCARD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 10, rxmpdu_ptr->length - 9);
+ return;
+ }
+ }
+ */
+ break;
+ case TYPE_DATA:
+ case TYPE_CMD:
+
+ //VALIDATION OF DESTINATION ADDRESSES - NOT TO OVERLOAD THE PROCESSOR
+ if (destination_address > 1)
+ {
+ switch(destination_address)
+ {
+ case SHORT_ADDRESS:
+ dest_short_ptr = (dest_short *) &rxmpdu_ptr->data[0];
+
+ if ( dest_short_ptr->destination_address != 0xffff && dest_short_ptr->destination_address != ver_macShortAddress)
+ {
+ //printfUART("nsm %x %x\n", dest_short_ptr->destination_address,ver_macShortAddress);
+
+ m_state = S_RX_DISCARD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 10, rxmpdu_ptr->length - 9);
+ return;
+ }
+
+ //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the
+ //broadcast PAN identifier (0 x ffff).
+ if(dest_short_ptr->destination_PAN_identifier != 0xffff && dest_short_ptr->destination_PAN_identifier != ver_macPANId )
+ {
+ //printfUART("wsP %x %x \n", dest_short_ptr->destination_PAN_identifier,ver_macPANId);
+
+ m_state = S_RX_DISCARD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 10, rxmpdu_ptr->length - 9);
+ return;
+ }
+
+ break;
+
+ case LONG_ADDRESS:
+
+ dest_long_ptr = (dest_long *) &rxmpdu_ptr->data[0];
+ /*
+ if ( dest_long_ptr->destination_address0 !=ver_aExtendedAddress0 && dest_long_ptr->destination_address1 !=ver_aExtendedAddress1 )
+ {
+ //printfUART("nlm %x %x \n",dest_long_ptr->destination_address0,dest_long_ptr->destination_address1);
+
+ m_state = S_RX_DISCARD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 16, rxmpdu_ptr->length - 15);
+ return;
+ }
+
+
+ //If a destination PAN identifier is included in the frame, it shall match macPANId or shall be the
+ //broadcast PAN identifier (0 x ffff).
+ if(dest_long_ptr->destination_PAN_identifier != 0xffff && dest_long_ptr->destination_PAN_identifier != ver_macPANId )
+ {
+ //printfUART("wLP %x %x\n", dest_long_ptr->destination_PAN_identifier,ver_macPANId);
+
+ m_state = S_RX_DISCARD;
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 16, rxmpdu_ptr->length - 15);
+ return;
+ }
+ */
+ break;
+ }
+ }
+
+ break;
+
+ case TYPE_ACK:
+
+ //printfUART("error ack \n","");
+ //call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr);
+
+ return;
+
+ break;
+
+
+ }
+
+ //read the remaining packet
+ switch(destination_address)
+ {
+ case SHORT_ADDRESS:
+ ////printfUART("as %i\n", (rxmpdu_ptr->length - 9));
+
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 10, rxmpdu_ptr->length - 9); //7
+ break;
+
+ case LONG_ADDRESS:
+ ////printfUART("al %i\n", (rxmpdu_ptr->length - 15));
+ call RXFIFO.continueRead((uint8_t*)rxmpdu_ptr + 16, rxmpdu_ptr->length - 15);
+ break;
+ }
+
+ break;
+
+
+ case S_RX_PAYLOAD:
+ call CSN.set();
+ //signal Receiveframe.receive((uint8_t*)rxmpdu_ptr, rssi);
+
+
+ //rssi= 255 - rx_buf[len-1];
+
+ /*
+ for (i=6;i<12;i++)
+ {
+ //printfUART("p %i %x %x\n",i,rxmpdu_ptr->data[i],rx_buf[i-6]);
+ }
+ */
+
+ if(!m_missed_packets) {
+ // Release the SPI only if there are no more frames to download
+ call SpiResource.release();
+ }
+
+ rssi = 255 - rxmpdu_ptr->data[rxmpdu_ptr->length-4];
+
+ //printfUART("pay %i %x %i\n",rxmpdu_ptr->seq_num, rssi,m_missed_packets);
+
+ signal Receiveframe.receive((uint8_t*)rxmpdu_ptr, rssi);
+
+
+ if (m_missed_packets == 0)
+ {
+ flush();
+ }
+ else
+ {
+ waitForNextPacket();
+ }
+
+ break;
+
+
+ case S_RX_DISCARD:
+ atomic receivingPacket = FALSE;
+ call CSN.set();
+ call SpiResource.release();
+ if (m_missed_packets == 0)
+ {
+ flush();
+ }
+ else
+ {
+ waitForNextPacket();
+ }
+
+ break;
+
+ default:
+ atomic receivingPacket = FALSE;
+ call CSN.set();
+ call SpiResource.release();
+ break;
+
+
+ }
+
+ }
+
+
+ /*
+ cc2420_header_t* header = call CC2420PacketBody.getHeader( m_p_rx_buf );
+ cc2420__t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );
+ uint8_t* buf = (uint8_t*) header;
+ rxFrameLength = buf[ 0 ];
+
+ switch( m_state ) {
+
+ case S_RX_LENGTH:
+ m_state = S_RX_FCF;
+ if ( rxFrameLength + 1 > m_bytes_left ) {
+ // Length of this packet is bigger than the RXFIFO, flush it out.
+ flush();
+
+ } else {
+ if ( !call FIFO.get() && !call FIFOP.get() ) {
+ m_bytes_left -= rxFrameLength + 1;
+ }
+
+ if(rxFrameLength <= MAC_PACKET_SIZE) {
+ if(rxFrameLength > 0) {
+ if(rxFrameLength > SACK_HEADER_LENGTH) {
+ // This packet has an FCF byte plus at least one more byte to read
+ call RXFIFO.continueRead(buf + 1, SACK_HEADER_LENGTH);
+
+ } else {
+ // This is really a bad packet, skip FCF and get it out of here.
+ m_state = S_RX_PAYLOAD;
+ call RXFIFO.continueRead(buf + 1, rxFrameLength);
+ }
+
+ } else {
+ // Length == 0; start reading the next packet
+ atomic receivingPacket = FALSE;
+ call CSN.set();
+ call SpiResource.release();
+ waitForNextPacket();
+ }
+
+ } else {
+ // Length is too large; we have to flush the entire Rx FIFO
+ flush();
+ }
+ }
+ break;
+
+ case S_RX_FCF:
+ m_state = S_RX_PAYLOAD;
+
+ /*
+ * The destination address check here is not completely optimized. If you
+ * are seeing issues with dropped acknowledgements, try removing
+ * the address check and decreasing SACK_HEADER_LENGTH to 2.
+ * The length byte and the FCF byte are the only two bytes required
+ * to know that the packet is valid and requested an ack. The destination
+ * address is useful when we want to sniff packets from other transmitters
+ * while acknowledging packets that were destined for our local address.
+ *//*
+ if(call CC2420Config.isAutoAckEnabled() && !call CC2420Config.isHwAutoAckDefault()) {
+ if (((( header->fcf >> IEEE154_FCF_ACK_REQ ) & 0x01) == 1)
+ && (header->dest == call CC2420Config.getShortAddr())
+ && ((( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7) == IEEE154_TYPE_DATA)) {
+ // CSn flippage cuts off our FIFO; SACK and begin reading again
+ call CSN.set();
+ call CSN.clr();
+ call SACK.strobe();
+ call CSN.set();
+ call CSN.clr();
+ call RXFIFO.beginRead(buf + 1 + SACK_HEADER_LENGTH,
+ rxFrameLength - SACK_HEADER_LENGTH);
+ return;
+ }
+
+
+ }
+
+ // Didn't flip CSn, we're ok to continue reading.
+ call RXFIFO.continueRead(buf + 1 + SACK_HEADER_LENGTH,
+ rxFrameLength - SACK_HEADER_LENGTH);
+ break;
+
+ case S_RX_PAYLOAD:
+ call CSN.set();
+
+ if(!m_missed_packets) {
+ // Release the SPI only if there are no more frames to download
+ call SpiResource.release();
+ }
+
+ if ( m_timestamp_size ) {
+ if ( rxFrameLength > 10 ) {
+ metadata->time = m_timestamp_queue[ m_timestamp_head ];
+ m_timestamp_head = ( m_timestamp_head + 1 ) % TIMESTAMP_QUEUE_SIZE;
+ m_timestamp_size--;
+ }
+ } else {
+ metadata->time = 0xffff;
+ }
+
+ // We may have received an ack that should be processed by Transmit
+ // buf[rxFrameLength] >> 7 checks the CRC
+ if ( ( buf[ rxFrameLength ] >> 7 ) && rx_buf ) {
+ uint8_t type = ( header->fcf >> IEEE154_FCF_FRAME_TYPE ) & 7;
+ // signal CC2420Receive.receive( type, m_p_rx_buf );
+ if ( type == IEEE154_TYPE_DATA ) {
+ post receiveDone_task();
+ return;
+ }
+ }
+
+ waitForNextPacket();
+ break;
+
+ default:
+ atomic receivingPacket = FALSE;
+ call CSN.set();
+ call SpiResource.release();
+ break;
+
+ }
+ */
+ }
+
+ async event void RXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
+ }
+
+ /***************** Tasks *****************/
+ /**
+ * Fill in metadata details, pass the packet up the stack, and
+ * get the next packet.
+ */
+ /*
+ task void receiveDone_task() {
+ cc2420_metadata_t* metadata = call CC2420PacketBody.getMetadata( m_p_rx_buf );
+ uint8_t* buf = (uint8_t*) call CC2420PacketBody.getHeader( m_p_rx_buf );;
+
+ metadata->crc = buf[ rxFrameLength ] >> 7;
+ metadata->rssi = buf[ rxFrameLength - 1 ];
+ metadata->lqi = buf[ rxFrameLength ] & 0x7f;
+ m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data,
+ rxFrameLength );
+
+ atomic receivingPacket = FALSE;
+ waitForNextPacket();
+ }
+ */
+ /****************** CC2420Config Events ****************/
+ event void CC2420Config.syncDone( error_t error ) {
+ }
+
+ /****************** Functions ****************/
+ /**
+ * Attempt to acquire the SPI bus to receive a packet.
+ */
+
+ void beginReceive() {
+
+ m_state = S_RX_LENGTH;
+
+ atomic receivingPacket = TRUE;
+
+ ////printfUART("br %i\n",m_state);
+
+ if(call SpiResource.isOwner()) {
+ receive();
+
+ } else if (call SpiResource.immediateRequest() == SUCCESS) {
+ receive();
+
+ } else {
+ call SpiResource.request();
+ }
+ }
+
+ /**
+ * Flush out the Rx FIFO
+ */
+ void flush() {
+ //printfUART("f %i\n",m_state);
+ reset_state();
+ call CSN.set();
+ call CSN.clr();
+ call SFLUSHRX.strobe();
+ call SFLUSHRX.strobe();
+ call CSN.set();
+ call SpiResource.release();
+ waitForNextPacket();
+ }
+
+ /**
+ * The first byte of each packet is the length byte. Read in that single
+ * byte, and then read in the rest of the packet. The CC2420 could contain
+ * multiple packets that have been buffered up, so if something goes wrong,
+ * we necessarily want to flush out the FIFO unless we have to.
+ */
+ void receive() {
+ //call Leds.led2Toggle();
+
+ call CSN.clr();
+
+ //call RXFIFO.beginRead( (uint8_t*)(call CC2420PacketBody.getHeader( m_p_rx_buf )), 1 );
+
+ //call RXFIFO.beginRead ((uint8_t*)rxmpdu_ptr,100);
+
+ //my old
+ call RXFIFO.beginRead((uint8_t*)rxmpdu_ptr,1);
+
+
+
+
+ }
+
+
+ /**
+ * Determine if there's a packet ready to go, or if we should do nothing
+ * until the next packet arrives
+ */
+
+ void waitForNextPacket() {
+ atomic {
+ if ( m_state == S_STOPPED ) {
+ call SpiResource.release();
+ return;
+ }
+
+ //printfUART("wn %i %i\n",m_state,m_missed_packets );
+
+
+ atomic receivingPacket = FALSE;
+
+ if ( ( m_missed_packets && call FIFO.get() ) || !call FIFOP.get() ) {
+ // A new packet is buffered up and ready to go
+ if ( m_missed_packets ) {
+ m_missed_packets--;
+ }
+
+ beginReceive();
+
+ } else {
+ // Wait for the next packet to arrive
+
+
+
+ m_state = S_STARTED;
+
+ //printfUART("wnP %i\n",m_state);
+
+ m_missed_packets = 0;
+ call SpiResource.release();
+ }
+ }
+ }
+
+ /**
+ * Reset this component
+ */
+
+ void reset_state() {
+ m_bytes_left = RXFIFO_SIZE;
+ atomic receivingPacket = FALSE;
+ //m_timestamp_head = 0;
+ //m_timestamp_size = 0;
+ m_missed_packets = 0;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Roman Lim
+ * @version $Revision$ $Date$
+ */
+
+module CC2420SpiP {
+
+ provides {
+ interface ChipSpiResource;
+ interface Resource[ uint8_t id ];
+ interface CC2420Fifo as Fifo[ uint8_t id ];
+ interface CC2420Ram as Ram[ uint16_t id ];
+ interface CC2420Register as Reg[ uint8_t id ];
+ interface CC2420Strobe as Strobe[ uint8_t id ];
+ }
+
+ uses {
+ interface Resource as SpiResource;
+ interface SpiByte;
+ interface SpiPacket;
+ interface State as WorkingState;
+ interface Leds;
+ }
+}
+
+implementation {
+
+ enum {
+ RESOURCE_COUNT = uniqueCount( "CC2420Spi.Resource" ),
+ NO_HOLDER = 0xFF,
+ };
+
+ /** WorkingStates */
+ enum {
+ S_IDLE,
+ S_BUSY,
+ };
+
+ /** Address to read/write on the CC2420, also maintains caller's client id */
+ norace uint16_t m_addr;
+
+ /** Each bit represents a client ID that is requesting SPI bus access */
+ uint8_t m_requests = 0;
+
+ /** The current client that owns the SPI bus */
+ uint8_t m_holder = NO_HOLDER;
+
+ /** TRUE if it is safe to release the SPI bus after all users say ok */
+ bool release;
+
+ /***************** Prototypes ****************/
+ error_t attemptRelease();
+ task void grant();
+
+ /***************** ChipSpiResource Commands ****************/
+ /**
+ * Abort the release of the SPI bus. This must be called only with the
+ * releasing() event
+ */
+ async command void ChipSpiResource.abortRelease() {
+ atomic release = FALSE;
+ }
+
+ /**
+ * Release the SPI bus if there are no objections
+ */
+ async command error_t ChipSpiResource.attemptRelease() {
+ return attemptRelease();
+ }
+
+ /***************** Resource Commands *****************/
+ async command error_t Resource.request[ uint8_t id ]() {
+
+ atomic {
+ if ( call WorkingState.requestState(S_BUSY) == SUCCESS ) {
+ m_holder = id;
+ if(call SpiResource.isOwner()) {
+ post grant();
+
+ } else {
+ call SpiResource.request();
+ }
+
+ } else {
+ m_requests |= 1 << id;
+ }
+ }
+ return SUCCESS;
+ }
+
+ async command error_t Resource.immediateRequest[ uint8_t id ]() {
+ error_t error;
+
+ atomic {
+ if ( call WorkingState.requestState(S_BUSY) != SUCCESS ) {
+ return EBUSY;
+ }
+
+
+ if(call SpiResource.isOwner()) {
+ m_holder = id;
+ error = SUCCESS;
+
+ } else if ((error = call SpiResource.immediateRequest()) == SUCCESS ) {
+ m_holder = id;
+
+ } else {
+ call WorkingState.toIdle();
+ }
+ }
+ return error;
+ }
+
+ async command error_t Resource.release[ uint8_t id ]() {
+ uint8_t i;
+ atomic {
+ if ( m_holder != id ) {
+ return FAIL;
+ }
+
+ m_holder = NO_HOLDER;
+ if ( !m_requests ) {
+ call WorkingState.toIdle();
+ attemptRelease();
+
+ } else {
+ for ( i = m_holder + 1; ; i++ ) {
+ i %= RESOURCE_COUNT;
+
+ if ( m_requests & ( 1 << i ) ) {
+ m_holder = i;
+ m_requests &= ~( 1 << i );
+ post grant();
+ return SUCCESS;
+ }
+ }
+ }
+ }
+
+ return SUCCESS;
+ }
+
+ async command uint8_t Resource.isOwner[ uint8_t id ]() {
+ atomic return (m_holder == id);
+ }
+
+
+ /***************** SpiResource Events ****************/
+ event void SpiResource.granted() {
+ post grant();
+ }
+
+ /***************** Fifo Commands ****************/
+ async command cc2420_status_t Fifo.beginRead[ uint8_t addr ]( uint8_t* data,
+ uint8_t len ) {
+
+ cc2420_status_t status = 0;
+
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return status;
+ }
+ }
+
+ m_addr = addr | 0x40;
+
+ status = call SpiByte.write( m_addr );
+ call Fifo.continueRead[ addr ]( data, len );
+
+ return status;
+
+ }
+
+ async command error_t Fifo.continueRead[ uint8_t addr ]( uint8_t* data,
+ uint8_t len ) {
+ return call SpiPacket.send( NULL, data, len );
+ }
+
+ async command cc2420_status_t Fifo.write[ uint8_t addr ]( uint8_t* data,
+ uint8_t len ) {
+
+ uint8_t status = 0;
+
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return status;
+ }
+ }
+
+ m_addr = addr;
+
+ status = call SpiByte.write( m_addr );
+ call SpiPacket.send( data, NULL, len );
+
+ return status;
+
+ }
+
+ /***************** RAM Commands ****************/
+ async command cc2420_status_t Ram.read[ uint16_t addr ]( uint8_t offset,
+ uint8_t* data,
+ uint8_t len ) {
+
+ cc2420_status_t status = 0;
+
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return status;
+ }
+ }
+
+ addr += offset;
+
+ call SpiByte.write( addr | 0x80 );
+ status = call SpiByte.write( ( ( addr >> 1 ) & 0xc0 ) | 0x20 );
+ for ( ; len; len-- ) {
+ *data++ = call SpiByte.write( 0 );
+ }
+
+ return status;
+
+ }
+
+
+ async command cc2420_status_t Ram.write[ uint16_t addr ]( uint8_t offset,
+ uint8_t* data,
+ uint8_t len ) {
+
+ cc2420_status_t status = 0;
+
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return status;
+ }
+ }
+
+ addr += offset;
+
+ call SpiByte.write( addr | 0x80 );
+ call SpiByte.write( ( addr >> 1 ) & 0xc0 );
+ for ( ; len; len-- ) {
+ status = call SpiByte.write( *data++ );
+ }
+
+ return status;
+
+ }
+
+ /***************** Register Commands ****************/
+ async command cc2420_status_t Reg.read[ uint8_t addr ]( uint16_t* data ) {
+
+ cc2420_status_t status = 0;
+
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return status;
+ }
+ }
+
+ status = call SpiByte.write( addr | 0x40 );
+ *data = (uint16_t)call SpiByte.write( 0 ) << 8;
+ *data |= call SpiByte.write( 0 );
+
+ return status;
+
+ }
+
+ async command cc2420_status_t Reg.write[ uint8_t addr ]( uint16_t data ) {
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return 0;
+ }
+ }
+ call SpiByte.write( addr );
+ call SpiByte.write( data >> 8 );
+ return call SpiByte.write( data & 0xff );
+ }
+
+
+ /***************** Strobe Commands ****************/
+ async command cc2420_status_t Strobe.strobe[ uint8_t addr ]() {
+ atomic {
+ if(call WorkingState.isIdle()) {
+ return 0;
+ }
+ }
+
+ return call SpiByte.write( addr );
+ }
+
+ /***************** SpiPacket Events ****************/
+ async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf,
+ uint16_t len, error_t error ) {
+ if ( m_addr & 0x40 ) {
+ signal Fifo.readDone[ m_addr & ~0x40 ]( rx_buf, len, error );
+ } else {
+ signal Fifo.writeDone[ m_addr ]( tx_buf, len, error );
+ }
+ }
+
+ /***************** Functions ****************/
+ error_t attemptRelease() {
+
+ atomic{
+ if(m_requests > 0
+ || m_holder != NO_HOLDER
+ || !call WorkingState.isIdle()) {
+ return FAIL;
+ }
+ }
+ atomic release = TRUE;
+ signal ChipSpiResource.releasing();
+ atomic {
+ if(release) {
+ call SpiResource.release();
+ return SUCCESS;
+ }
+ }
+
+ return EBUSY;
+ }
+
+ task void grant() {
+ uint8_t holder;
+ atomic {
+ holder = m_holder;
+ }
+ signal Resource.granted[ holder ]();
+ }
+
+ /***************** Defaults ****************/
+ default event void Resource.granted[ uint8_t id ]() {
+ }
+
+ default async event void Fifo.readDone[ uint8_t addr ]( uint8_t* rx_buf, uint8_t rx_len, error_t error ) {
+ }
+
+ default async event void Fifo.writeDone[ uint8_t addr ]( uint8_t* tx_buf, uint8_t tx_len, error_t error ) {
+ }
+
+ default async event void ChipSpiResource.releasing() {
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * Implementation of the transmit path for the ChipCon CC2420 radio.
+ *
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @version $Revision$ $Date$
+ */
+
+#include "IEEE802154.h"
+
+configuration CC2420TransmitC {
+
+ provides {
+ interface StdControl;
+
+ interface ReceiveIndicator as EnergyIndicator;
+ interface ReceiveIndicator as ByteIndicator;
+
+ interface Sendframe;
+ }
+}
+
+implementation {
+
+ components CC2420TransmitP;
+ StdControl = CC2420TransmitP;
+
+ EnergyIndicator = CC2420TransmitP.EnergyIndicator;
+ ByteIndicator = CC2420TransmitP.ByteIndicator;
+
+
+ Sendframe = CC2420TransmitP;
+
+ components MainC;
+ MainC.SoftwareInit -> CC2420TransmitP;
+
+
+ components HplCC2420PinsC as Pins;
+ CC2420TransmitP.CCA -> Pins.CCA;
+ CC2420TransmitP.CSN -> Pins.CSN;
+ CC2420TransmitP.SFD -> Pins.SFD;
+
+ components HplCC2420InterruptsC as Interrupts;
+ CC2420TransmitP.CaptureSFD -> Interrupts.CaptureSFD;
+
+ components new CC2420SpiC() as Spi;
+ CC2420TransmitP.SpiResource -> Spi;
+ CC2420TransmitP.ChipSpiResource -> Spi;
+ CC2420TransmitP.SNOP -> Spi.SNOP;
+ CC2420TransmitP.STXON -> Spi.STXON;
+ CC2420TransmitP.STXONCCA -> Spi.STXONCCA;
+ CC2420TransmitP.SFLUSHTX -> Spi.SFLUSHTX;
+ CC2420TransmitP.TXCTRL -> Spi.TXCTRL;
+ CC2420TransmitP.TXFIFO -> Spi.TXFIFO;
+ CC2420TransmitP.TXFIFO_RAM -> Spi.TXFIFO_RAM;
+ CC2420TransmitP.MDMCTRL1 -> Spi.MDMCTRL1;
+
+ components LedsC;
+ CC2420TransmitP.Leds -> LedsC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2005-2006 Arch Rock Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the
+ * distribution.
+ * - Neither the name of the Arch Rock Corporation nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * ARCHED ROCK OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE
+ */
+
+/**
+ * @author Jonathan Hui <jhui@archrock.com>
+ * @author David Moss
+ * @author Jung Il Choi Initial SACK implementation
+ * @version $Revision$ $Date$
+ */
+
+module CC2420TransmitP {
+
+ provides interface Init;
+ provides interface StdControl;
+
+ provides interface Sendframe;
+
+ provides interface ReceiveIndicator as EnergyIndicator;
+ provides interface ReceiveIndicator as ByteIndicator;
+
+ uses interface GpioCapture as CaptureSFD;
+ uses interface GeneralIO as CCA;
+ uses interface GeneralIO as CSN;
+ uses interface GeneralIO as SFD;
+
+ uses interface Resource as SpiResource;
+ uses interface ChipSpiResource;
+ uses interface CC2420Fifo as TXFIFO;
+ uses interface CC2420Ram as TXFIFO_RAM;
+ uses interface CC2420Register as TXCTRL;
+ uses interface CC2420Strobe as SNOP;
+ uses interface CC2420Strobe as STXON;
+ uses interface CC2420Strobe as STXONCCA;
+ uses interface CC2420Strobe as SFLUSHTX;
+ uses interface CC2420Register as MDMCTRL1;
+
+
+ uses interface Leds;
+}
+
+implementation {
+
+ /** Byte reception/transmission indicator */
+ bool sfdHigh;
+
+
+ /***************** Prototypes ****************/
+
+ void attemptSend();
+
+ error_t acquireSpiResource();
+ error_t releaseSpiResource();
+ void signalDone( error_t err );
+
+
+ /***************** Init Commands *****************/
+ command error_t Init.init() {
+ call CCA.makeInput();
+ call CSN.makeOutput();
+ call SFD.makeInput();
+ return SUCCESS;
+ }
+
+ /***************** StdControl Commands ****************/
+ command error_t StdControl.start() {
+ atomic {
+ call CaptureSFD.captureRisingEdge();
+ }
+
+ return SUCCESS;
+ }
+
+ command error_t StdControl.stop() {
+ atomic {
+
+ call CaptureSFD.disable();
+ call SpiResource.release(); // REMOVE
+ call CSN.set();
+ }
+ return SUCCESS;
+ }
+
+
+/**************** Send Commands ****************/
+
+ async command error_t Sendframe.send(uint8_t* frame, uint8_t frame_length)
+ {
+ //printfUART("Send Command\n", "");
+
+ if ( acquireSpiResource() == SUCCESS ) {
+ call CSN.clr();
+
+ call TXCTRL.write( ( 2 << CC2420_TXCTRL_TXMIXBUF_CUR ) |
+ ( 3 << CC2420_TXCTRL_PA_CURRENT ) |
+ ( 1 << CC2420_TXCTRL_RESERVED ) |
+ ( (CC2420_DEF_RFPOWER & 0x1F) << CC2420_TXCTRL_PA_LEVEL ) );
+
+
+ call TXFIFO.write( (uint8_t*)frame, frame_length);
+
+ }
+ return SUCCESS;
+ }
+
+
+ /***************** Indicator Commands ****************/
+ command bool EnergyIndicator.isReceiving() {
+ return !(call CCA.get());
+ }
+
+ command bool ByteIndicator.isReceiving() {
+ bool high;
+ atomic high = sfdHigh;
+ return high;
+ }
+
+ /**
+ * The CaptureSFD event is actually an interrupt from the capture pin
+ * which is connected to timing circuitry and timer modules. This
+ * type of interrupt allows us to see what time (being some relative value)
+ * the event occurred, and lets us accurately timestamp our packets. This
+ * allows higher levels in our system to synchronize with other nodes.
+ *
+ * Because the SFD events can occur so quickly, and the interrupts go
+ * in both directions, we set up the interrupt but check the SFD pin to
+ * determine if that interrupt condition has already been met - meaning,
+ * we should fall through and continue executing code where that interrupt
+ * would have picked up and executed had our microcontroller been fast enough.
+ */
+ async event void CaptureSFD.captured( uint16_t time ) {
+
+ }
+
+ /***************** ChipSpiResource Events ****************/
+ async event void ChipSpiResource.releasing() {
+ }
+
+
+ /***************** SpiResource Events ****************/
+ event void SpiResource.granted() {
+
+ attemptSend();
+
+ }
+
+ /***************** TXFIFO Events ****************/
+ /**
+ * The TXFIFO is used to load packets into the transmit buffer on the
+ * chip
+ */
+ async event void TXFIFO.writeDone( uint8_t* tx_buf, uint8_t tx_len,error_t error )
+ {
+
+ call CSN.set();
+ attemptSend();
+
+ }
+
+
+ async event void TXFIFO.readDone( uint8_t* tx_buf, uint8_t tx_len,error_t error ) {
+ }
+
+
+ /***************** Functions ****************/
+
+
+ /**
+ * Attempt to send the packet we have loaded into the tx buffer on
+ * the radio chip. The STXONCCA will send the packet immediately if
+ * the channel is clear. If we're not concerned about whether or not
+ * the channel is clear (i.e. m_cca == FALSE), then STXON will send the
+ * packet without checking for a clear channel.
+ *
+ * If the packet didn't get sent, then congestion == TRUE. In that case,
+ * we reset the backoff timer and try again in a moment.
+ *
+ * If the packet got sent, we should expect an SFD interrupt to take
+ * over, signifying the packet is getting sent.
+ */
+ void attemptSend() {
+
+
+
+ //printfUART("attempt Send Command\n", "");
+
+ atomic {
+
+
+ call CSN.clr();
+
+ call STXON.strobe();
+
+ call CSN.set();
+
+ releaseSpiResource();
+ }
+
+
+ signalDone(SUCCESS);
+
+ }
+
+ error_t acquireSpiResource() {
+ error_t error = call SpiResource.immediateRequest();
+
+ //printfUART("acquire spi\n", "");
+ if ( error != SUCCESS ) {
+ call SpiResource.request();
+ }
+ return error;
+ }
+
+ error_t releaseSpiResource() {
+ call SpiResource.release();
+ return SUCCESS;
+ }
+
+
+ void signalDone( error_t err ) {
+
+ call ChipSpiResource.attemptRelease();
+ signal Sendframe.sendDone( err );
+ }
+
+}
+
--- /dev/null
+/**
+ * Low-level abstraction for the receive path implementaiton of the
+ * ChipCon CC2420 radio.
+ *
+ * @author
+ * @version
+ */
+
+interface Receiveframe {
+
+ /**
+ * Signal that a message has been received
+ */
+ async event void receive(uint8_t* frame, uint8_t rssi);
+
+}
--- /dev/null
+/**
+ * Low-level abstraction for the transmit path implementaiton of the
+ * ChipCon CC2420 radio.
+ *
+ * @author
+ * @version
+ */
+
+interface Sendframe {
+
+ /**
+ * Send a message
+
+ * @return SUCCESS if the request was accepted, FAIL otherwise.
+ */
+ async command error_t send(uint8_t* frame, uint8_t frame_length);
+
+ /**
+ * Signal that a message has been sent
+ */
+ async event void sendDone(error_t error );
+
+}
+
--- /dev/null
+Title: ZigBee
+Author: André Cunha - IPP-HURRAY! http://www.open-zb.net
+----------------------------------------------
+
+
+Notes:
+------
+This folder contains the CC2420 modified files and other additional files.
\ No newline at end of file
--- /dev/null
+Title: ZigBee
+Author: André Cunha - IPP-HURRAY! http://www.open-zb.net
+----------------------------------------------
+
+
+Notes:
+------
+This folder contains the main implementation files.
+
+Note that the IEEE 802.15.4 MAC is implemented in the mac and timerasync folders and the IEEE 802.15.4
+with the Zigbee Network layer including the Cluster-tree formation with the TDBS mechanism (refer to http://www.open-zb.net/publications/hurray-tr-070102.pdf)
+is implemented in the macTDBS and timerasyncTDBS
\ No newline at end of file
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+ interface TimerAsync
+ {
+
+ async command error_t start();
+
+ async command error_t stop();
+
+ async command error_t reset();
+
+ /***********************************FIRED EVENTS COMMANDS******************************/
+ //time before BI
+ async event error_t before_bi_fired();
+
+ async event error_t sd_fired();
+
+ async event error_t bi_fired();
+
+ //backoff fired
+ async event error_t backoff_fired();
+
+ //backoff boundary fired
+ async event error_t time_slot_fired();
+
+ async event error_t before_time_slot_fired();
+
+ async event error_t sfd_fired();
+
+ /***********************************INIT/RESET COMMANDS******************************/
+
+ async command error_t set_bi_sd(uint32_t bi_symbols,uint32_t sd_symbols);
+
+ async command error_t set_backoff_symbols(uint8_t symbols);
+
+ async command error_t set_enable_backoffs(bool enable_backoffs);
+
+ async command uint8_t reset_start(uint32_t start_ticks);
+
+ async command error_t reset_process_frame_tick_counter();
+
+ /*****************************************************************************/
+
+ async command error_t set_timers_enable(uint8_t timer);
+
+ /***********************************GET COMMANDS******************************/
+ async command uint32_t get_total_tick_counter();
+
+ async command uint32_t get_current_number_backoff();
+
+ async command uint32_t get_time_slot_backoff_periods();
+
+ async command uint32_t get_current_time_slot();
+
+ async command uint32_t get_current_number_backoff_on_time_slot();
+
+ async command uint32_t get_process_frame_tick_counter();
+
+ async command uint32_t get_time_slot_ticks();
+
+ async command uint32_t get_current_ticks();
+
+ async command uint32_t get_sd_ticks();
+
+ async command uint32_t get_bi_ticks();
+
+ async command uint32_t get_backoff_ticks();
+
+
+ /*****************************************************************************/
+ //TDBS IMPLEMENTATION
+ /*****************************************************************************/
+
+ //track beacon interfaces
+
+ async command error_t set_track_beacon(uint8_t track);
+
+ async command error_t set_track_beacon_start_ticks(uint32_t parent_offset_symbols,uint32_t duration_symbols,uint32_t transmission_delay);
+
+
+ async event error_t before_start_track_beacon_fired();
+
+ async event error_t start_track_beacon_fired();
+
+ async event error_t end_track_beacon_fired();
+
+ }
+
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+ //TIMER ASYNC TELOSB
+
+
+configuration TimerAsyncC
+{
+ //provides interface StdControl;
+ provides interface TimerAsync;
+}
+implementation
+{
+
+ components LedsC;
+ components TimerAsyncM;
+
+ components new Alarm32khz32C() as Alarm;
+
+ //StdControl = TimerAsyncM;
+ TimerAsync = TimerAsyncM;
+
+ TimerAsyncM.Leds -> LedsC;
+
+ TimerAsyncM.AsyncTimer -> Alarm;
+
+}
--- /dev/null
+/*
+ * @author IPP HURRAY http://www.hurray.isep.ipp.pt/art-wise
+ * @author Andre Cunha
+ *
+ */
+
+#define BEFORE_BI_INTERVAL 100
+#define BEFORE_BB_INTERVAL 5
+
+#define SO_EQUAL_BO_DIFFERENCE 2
+
+//#define SYMBOL_DIVISION 4
+
+//temporary
+#define NUMBER_TIME_SLOTS 16
+
+//TDBS Implementation
+#define BEFORE_TRACK_BEACON 40
+
+module TimerAsyncM {
+
+ provides interface TimerAsync;
+
+ uses interface Leds;
+
+ uses interface Alarm<T32khz,uint32_t> as AsyncTimer;
+
+
+
+}
+implementation
+{
+
+uint32_t ticks_counter;
+
+//BEACON INTERVAL VARIABLES
+uint32_t bi_ticks;
+uint32_t bi_backoff_periods;
+uint32_t before_bi_ticks;
+uint32_t sd_ticks;
+
+//number of backoff periods
+uint32_t time_slot_backoff_periods;
+
+//number of ticks in the timeslot
+uint32_t time_slot_ticks;
+uint32_t before_time_slot_ticks;
+uint32_t time_slot_tick_next_fire;
+
+//BACKOFF VARIABLES
+uint32_t backoff_symbols;
+
+//number of ticks in the backoff
+uint32_t backoff_ticks = 5;
+
+//COUNTER VARIABLES
+uint32_t backoff_ticks_counter=0;
+
+//give the current time slot number
+uint8_t current_time_slot=0;
+//counts the current number of time slots of each time slot
+uint32_t current_number_backoff_on_time_slot=0;
+//count the total number of backoffs
+uint32_t current_number_backoff = 0;
+
+//OTHER
+bool backoffs=0;
+bool enable_backoffs=0;
+
+uint8_t previous_sfd=0;
+uint8_t current_sfd = 0;
+
+uint32_t process_frame_tick_counter=0;
+
+uint32_t total_tick_counter=0;
+
+uint8_t timers_enable=0x01;
+
+
+//TDBS Implementation
+
+uint32_t start_track_beacon_ticks=0;
+uint32_t end_track_beacon_ticks=0;
+
+uint8_t track_beacon=0;
+
+
+async command error_t TimerAsync.start()
+{
+
+call AsyncTimer.start(10);
+
+return SUCCESS;
+
+}
+
+async command error_t TimerAsync.stop()
+{
+
+return SUCCESS;
+
+}
+
+/*RESET the tick counter, */
+async command error_t TimerAsync.reset()
+{
+ atomic ticks_counter = 0;
+ call AsyncTimer.start(10);
+ return SUCCESS;
+}
+
+async command error_t TimerAsync.set_bi_sd(uint32_t bi_symbols,uint32_t sd_symbols)
+{
+
+atomic{
+ time_slot_backoff_periods = (sd_symbols / NUMBER_TIME_SLOTS) / backoff_symbols;
+ time_slot_ticks = time_slot_backoff_periods * backoff_ticks;
+ time_slot_tick_next_fire = time_slot_ticks;
+ before_time_slot_ticks = time_slot_ticks - BEFORE_BB_INTERVAL;
+ sd_ticks = time_slot_ticks * NUMBER_TIME_SLOTS;
+
+ if (bi_symbols == sd_symbols )
+ {
+ //in order not to have the same time for both BI and SI
+ sd_ticks = sd_ticks - SO_EQUAL_BO_DIFFERENCE;
+ }
+
+ bi_backoff_periods = bi_symbols/ backoff_symbols;
+ bi_ticks = bi_backoff_periods * backoff_ticks;
+
+ before_bi_ticks = bi_ticks - BEFORE_BI_INTERVAL;
+
+ /*
+ printfUART("bi_ticks %i\n", bi_ticks);
+ printfUART("sd_ticks %i\n", sd_ticks);
+ printfUART("time_slot_ticks %i\n", time_slot_ticks);
+ */
+ }
+return SUCCESS;
+}
+
+
+async command error_t TimerAsync.set_backoff_symbols(uint8_t Backoff_Duration_Symbols)
+{
+
+ atomic
+ {
+ backoff_symbols = Backoff_Duration_Symbols;
+ backoff_ticks = 1;
+ }
+
+ return SUCCESS;
+}
+
+
+async command error_t TimerAsync.set_enable_backoffs(bool enable)
+{
+ atomic enable_backoffs = enable;
+ return SUCCESS;
+}
+
+
+
+async event void AsyncTimer.fired() {
+
+atomic{
+
+ if(timers_enable==0x01)
+ {
+
+ ticks_counter++;
+ process_frame_tick_counter++;
+
+ total_tick_counter++;
+
+ if (ticks_counter == before_bi_ticks)
+ {
+ signal TimerAsync.before_bi_fired();
+ }
+
+ if (ticks_counter == bi_ticks)
+ {
+ //printfUART("bi%d\n", ticks_counter);
+ ticks_counter = 0;
+ current_time_slot=0;
+ backoff_ticks_counter=0;
+ time_slot_tick_next_fire=time_slot_ticks;
+ backoffs=1;
+ enable_backoffs = 1;
+ current_number_backoff =0;
+ signal TimerAsync.bi_fired();
+ }
+
+ if(ticks_counter == sd_ticks)
+ {
+ backoffs=0;
+ signal TimerAsync.sd_fired();
+ }
+
+ if ((enable_backoffs == 1) && (backoffs == 1))
+ {
+ backoff_ticks_counter++;
+
+ if (backoff_ticks_counter == backoff_ticks)
+ {
+
+ backoff_ticks_counter=0;
+ current_number_backoff ++;
+ current_number_backoff_on_time_slot++;
+ signal TimerAsync.backoff_fired();
+ }
+
+ //before time slot boundary
+ if(ticks_counter == before_time_slot_ticks)
+ {
+ signal TimerAsync.before_time_slot_fired();
+ }
+
+ //time slot fired
+ if (ticks_counter == time_slot_tick_next_fire)
+ {
+ time_slot_tick_next_fire = time_slot_tick_next_fire + time_slot_ticks;
+ before_time_slot_ticks = time_slot_tick_next_fire - BEFORE_BB_INTERVAL;
+ backoff_ticks_counter=0;
+ current_number_backoff_on_time_slot=0;
+ current_time_slot++;
+
+ if ((current_time_slot > 0) && (current_time_slot < 16) )
+ signal TimerAsync.time_slot_fired();
+
+
+
+ }
+ }
+
+
+ //will only fires when the node is in the inactive period(backoffs==0) and is tracking the beacon
+ //TDBS Implementation
+ if(track_beacon == 1)
+ {
+
+ if(ticks_counter == (start_track_beacon_ticks - BEFORE_TRACK_BEACON))
+ {
+ //backoff_ticks_counter=0;
+ signal TimerAsync.before_start_track_beacon_fired();
+ }
+
+ if(ticks_counter == start_track_beacon_ticks)
+ {
+ //backoff_ticks_counter=0;
+ signal TimerAsync.start_track_beacon_fired();
+ }
+
+ backoff_ticks_counter++;
+ if(backoff_ticks_counter==backoff_ticks)
+ {
+ backoff_ticks_counter=0;
+ signal TimerAsync.backoff_fired();
+ }
+
+ if(ticks_counter == end_track_beacon_ticks)
+ {
+ signal TimerAsync.end_track_beacon_fired();
+ }
+ }
+ }
+
+ call AsyncTimer.start(10);
+
+ }
+}
+
+
+async command error_t TimerAsync.set_timers_enable(uint8_t timer)
+{
+
+ atomic timers_enable = timer;
+ //printfUART("te%i\n", timers_enable);
+
+
+return SUCCESS;
+}
+
+async command error_t TimerAsync.reset_process_frame_tick_counter()
+{
+atomic process_frame_tick_counter=0;
+
+return SUCCESS;
+}
+
+
+
+/*RESET the tick counter, to the start ticks */
+
+async command uint8_t TimerAsync.reset_start(uint32_t start_ticks)
+{
+ //ticks_counter =0;
+ //ticks_counter = start_ticks;
+
+ current_time_slot = start_ticks / time_slot_ticks;
+
+ if (current_time_slot == 0)
+ {
+ time_slot_tick_next_fire= time_slot_ticks;
+ current_number_backoff = start_ticks / backoff_ticks;
+ current_number_backoff_on_time_slot = current_number_backoff;
+ }
+ else
+ {
+ time_slot_tick_next_fire= ((current_time_slot+1) * time_slot_ticks);
+ current_number_backoff = start_ticks / backoff_ticks;
+ current_number_backoff_on_time_slot = current_number_backoff - (current_time_slot * time_slot_backoff_periods);
+ }
+
+ backoff_ticks_counter=0;
+ backoffs=1;
+ //on_sync = 1;
+
+ total_tick_counter = total_tick_counter + start_ticks;
+ ticks_counter = start_ticks;
+
+/*
+ printfUART("bi_ticks %i\n", bi_ticks);
+ printfUART("sd_ticks %i\n", sd_ticks);
+ printfUART("time_slot_ticks %i\n", time_slot_ticks);
+ printfUART("total_tick_counter %i\n", total_tick_counter);
+ printfUART("ticks_counter %i\n", ticks_counter);
+ printfUART("current_time_slot %i\n", current_time_slot);
+*/
+
+
+
+ return current_time_slot;
+
+ }
+
+/***********************************SET COMMANDS******************************/
+
+/***********************************GET COMMANDS******************************/
+/*get current clock ticks*/
+
+async command uint32_t TimerAsync.get_current_ticks()
+{
+ return ticks_counter;
+}
+/*get current sd ticks*/
+async command uint32_t TimerAsync.get_sd_ticks()
+{
+ return time_slot_ticks * NUMBER_TIME_SLOTS;
+}
+/*get current clock ticks*/
+async command uint32_t TimerAsync.get_bi_ticks()
+{
+ return bi_ticks;
+}
+/*get current backoff ticks*/
+async command uint32_t TimerAsync.get_backoff_ticks()
+{
+ return backoff_ticks;
+}
+/*get current time slot ticks*/
+async command uint32_t TimerAsync.get_time_slot_ticks()
+{
+ return time_slot_ticks;
+}
+
+/*get current backoff ticks*/
+async command uint32_t TimerAsync.get_current_number_backoff()
+{
+return current_number_backoff;
+}
+
+async command uint32_t TimerAsync.get_time_slot_backoff_periods()
+{
+return time_slot_backoff_periods;
+}
+
+async command uint32_t TimerAsync.get_current_time_slot()
+{
+return current_time_slot;
+}
+
+
+async command uint32_t TimerAsync.get_current_number_backoff_on_time_slot()
+{
+
+return current_number_backoff_on_time_slot;
+
+}
+
+async command uint32_t TimerAsync.get_total_tick_counter()
+{
+return total_tick_counter;
+}
+async command uint32_t TimerAsync.get_process_frame_tick_counter()
+{
+ //printfUART("%d\n", process_frame_tick_counter);
+
+return process_frame_tick_counter;
+}
+
+
+//TDBS Implementation
+async command error_t TimerAsync.set_track_beacon(uint8_t track)
+{
+ atomic track_beacon = track;
+
+return SUCCESS;
+}
+
+async command error_t TimerAsync.set_track_beacon_start_ticks(uint32_t parent_offset_symbols,uint32_t duration_symbols,uint32_t transmission_delay)
+{
+
+atomic{
+
+ start_track_beacon_ticks = bi_ticks - ((parent_offset_symbols / backoff_symbols)*backoff_ticks);
+
+ end_track_beacon_ticks = start_track_beacon_ticks + ((duration_symbols / backoff_symbols)*backoff_ticks);
+
+ //verify, the node must synchronyze with the parent beacon offset
+ ticks_counter = (start_track_beacon_ticks - transmission_delay);
+
+
+ //printfUART("start_track_beacon_ticks %i\n", start_track_beacon_ticks);
+ //printfUART("end_track_beacon_ticks %i\n", end_track_beacon_ticks);
+
+
+ }
+return SUCCESS;
+}
+
+
+
+
+
+}
--- /dev/null
+Title: open-zb protocol stack implementation for TinyOS v2.0
+Author: André Cunha - IPP-HURRAY! http://www.open-zb.net
+----------------------------------------------
+
+Implementation of the ZigBee and the beacon-enabled mode of the IEEE 802.15.4.
+
+This project is divided in two, the beacon-enabled mode of the IEEE 802.15.4 without any network level
+and supporting the synchronized star topology, tested in the MicaZ and TelosB motes and the beacon-enabled
+mode of the IEEE 802.15.4 with the ZigBee network layer supporting the Cluster-tree topology.
+
+The current version of the implementation of the IEEE 802.15.4 beacon enabled mode supports the following functionalities:
+
+-CSMA/CA algorithm \96 slotted version;
+-GTS Mechanism;
+-Indirect transmission mechanism;
+-Direct / Indirect / GTS Data Transmission;
+-Beacon Management;
+-Frame construction \96 Short Addressing Fields only and extended addressing
+fields in the association request;
+-Association/Disassociation Mechanism;
+-MAC PIB Management;
+-Frame Reception Conditions;
+-ED and PASSIVE channel scan;
+
+The following functionalities are not implemented or tested in the current
+version of the implementation
+-Unslotted version CSMA/CA;
+-Extended Address Fields of the Frames;
+-IntraPAN Address Fields of the Frames;
+-Active and Orphan channel Scan;
+-Orphan Devices;
+-Frame Reception Conditions (Verify Conditions);
+-Security \96 Out of the scope of this implementation;
+
+The current version of the ZigBee Network Layer, besides the above functionalities, supports
+
+-Creation of the Cluster-tree topology (statically defined) using the TDBS (refer to http://www.open-zb.net/publications/hurray-tr-070510.pdf)
+-Cluster-tree routing protocol
+-Address Assignment
+-NWL PIB management
+
+
+Notes:
+------
+
+The implementation files is organized as follows:
+
+folders:
+
+app
+- IEEE 802.15.4 test applications
+ Contains 4 test applications
+ -AssociationExample - uses the associates with the Coordinator, transmits data messages and dissasociates
+ -DataSendExample - data transmission example
+ -GTSManagementExample - Uses the GTS functions to allocate a GTS slot in the Coordinator, sends GTS messages and deallocate the GTS slot
+ -SimpleRoutingExample - evolution of the DataSendExample used to demonstrate a simple netork layer where two nodes use the Coordinator to route messages
+Notes:
+The objective of these examples is to
+provide a demonstration/testing of the protocol functionalities and allowing a simple
+understanding of the implementation functions.
+All the examples have a configuration file associated (eg <AppName>.h) located in
+the application folder. The configuration include the type of device (eg
+COORDINATOR or END_DEVICE), the logical channel, the beacon order, the
+superframe order, the pan id and the device depth in the network (by default all the end
+devices have a depth of 1 and the coordinator a depth of 0).
+
+- ZigBee Network Layer with the TDBS
+
+ -Test_APL
+This application uses the interfaces provided by the NWKM component and currently is customized
+to use with the TELOSB mote due to the interfacing with the mote user button. The TELOSB mote needs to
+\93warmup\94 before entering into normal operational behaviour, so, the user button is used to start the mote
+operation either by starting to send beacons, in the case of the ZigBee Coordinator, or to associate to a
+network in the case of ZigBee Routers or End Devices.
+In order to test the cluster-tree approach we have forced the association to a specific parent device by
+assigning some static parameters to the device. These parameters are located in the nwk_const.h file under
+the lib.nwk and are the following:
+-TYPE_DEVICE \96 selecting the role of the device in the network;
+-DEVICE_DEPTH \96 selecting the depth of the device in the network. This parameter in be used in
+computing the cskip functions used for the address assignment and for the tree-routing. This value
+will also be used to select the appropriate parent selected for the association.
+Depending of the selected depth the device will select the statically defined parent. The parent values are
+assigned in the NLME_NETWORK_DISCOVERY.request primitive.The parents addresses (short address and
+extended address) are defined in the following variables:
+Activated when the device depth is 0x01
+-D1_PAN_EXT0 0x00000001
+-D1_PAN_EXT1 0x00000001
+-D1_PAN_SHORT 0x0000
+Activated when the device depth is 0x02
+-D2_PAN_EXT0 0x00000002
+-D2_PAN_EXT1 0x00000002
+-D2_PAN_SHORT 0x0001
+Activated when the device depth is 0x03
+-D3_PAN_EXT0 0x00000003
+-D3_PAN_EXT1 0x00000003
+-D3_PAN_SHORT 0x0002
+Activated when the device depth is 0x04
+-D4_PAN_EXT0 0x00000006
+-D4_PAN_EXT1 0x00000006
+-D4_PAN_SHORT 0x0022
+In order for a cluster-tree to work properly there is a need to schedule the beacon frames. This is
+done by assigning a time offset to each routers. The device assigned as a ZigBee
+Coordinator will accept the negotiation requests for beacon transmission. Upon the reception of these
+messages the ZC will execute the process_beacon_scheduling function that already has an offset list for each
+device (based on the short address). This function can be replaced with a scheduling algorithm.
+
+More details in http://www.open-zb.net/publications/hurray-tr-070510.pdf
+
+