[Tinyos-2-commits] CVS: tinyos-2.x/apps/BaseStationCC2420
BaseStationC.nc, NONE, 1.1.2.1 BaseStationP.nc, NONE,
1.1.2.1 CC2420ControlP.nc, NONE, 1.1.2.1 Makefile, NONE,
1.1.2.1 README.txt, NONE, 1.1.2.1
Phil Levis
scipio at users.sourceforge.net
Mon Oct 30 13:53:06 PST 2006
Update of /cvsroot/tinyos/tinyos-2.x/apps/BaseStationCC2420
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv4618/BaseStationCC2420
Added Files:
Tag: tinyos-2_0_devel-BRANCH
BaseStationC.nc BaseStationP.nc CC2420ControlP.nc Makefile
README.txt
Log Message:
Base station that works on CC2420 platforms.
--- NEW FILE: BaseStationC.nc ---
// $Id: BaseStationC.nc,v 1.1.2.1 2006/10/30 21:53:03 scipio Exp $
/* tab:4
* "Copyright (c) 2000-2003 The Regents of the University of California.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2003 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/**
* The TinyOS 2.x base station that forwards packets between the UART
* and radio.It replaces the GenericBase of TinyOS 1.0 and the
* TOSBase of TinyOS 1.1.
*
* <p>On the serial link, BaseStation sends and receives simple active
* messages (not particular radio packets): on the radio link, it
* sends radio active messages, whose format depends on the network
* stack being used. BaseStation will copy its compiled-in group ID to
* messages moving from the serial link to the radio, and will filter
* out incoming radio messages that do not contain that group ID.</p>
*
* <p>BaseStation includes queues in both directions, with a guarantee
* that once a message enters a queue, it will eventually leave on the
* other interface. The queues allow the BaseStation to handle load
* spikes.</p>
*
* <p>BaseStation acknowledges a message arriving over the serial link
* only if that message was successfully enqueued for delivery to the
* radio link.</p>
*
* <p>The LEDS are programmed to toggle as follows:</p>
* <ul>
* <li><b>RED Toggle:</b>: Message bridged from serial to radio</li>
* <li><b>GREEN Toggle:</b> Message bridged from radio to serial</li>
* <li><b>YELLOW/BLUE Toggle:</b> Dropped message due to queue overflow in either direction</li>
* </ul>
*
* @author Phil Buonadonna
* @author Gilman Tolle
* @author David Gay
* @author Philip Levis
* @date August 10 2005
*/
configuration BaseStationC {
}
implementation {
components MainC, BaseStationP, LedsC;
components ActiveMessageC as Radio, SerialActiveMessageC as Serial;
MainC.Boot <- BaseStationP;
BaseStationP.RadioControl -> Radio;
BaseStationP.SerialControl -> Serial;
BaseStationP.UartSend -> Serial;
BaseStationP.UartReceive -> Serial;
BaseStationP.UartPacket -> Serial;
BaseStationP.UartAMPacket -> Serial;
BaseStationP.RadioSend -> Radio;
BaseStationP.RadioReceive -> Radio.Receive;
BaseStationP.RadioPacket -> Radio;
BaseStationP.RadioAMPacket -> Radio;
BaseStationP.Leds -> LedsC;
}
--- NEW FILE: BaseStationP.nc ---
// $Id: BaseStationP.nc,v 1.1.2.1 2006/10/30 21:53:03 scipio Exp $
/* tab:4
* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
` *
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
* CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
*
* Copyright (c) 2002-2005 Intel Corporation
* All rights reserved.
*
* This file is distributed under the terms in the attached INTEL-LICENSE
* file. If you do not find these files, copies can be found by writing to
* Intel Research Berkeley, 2150 Shattuck Avenue, Suite 1300, Berkeley, CA,
* 94704. Attention: Intel License Inquiry.
*/
/*
* @author Phil Buonadonna
* @author Gilman Tolle
* @author David Gay
* Revision: $Id: BaseStationP.nc,v 1.1.2.1 2006/10/30 21:53:03 scipio Exp $
*/
/*
* BaseStationP bridges packets between a serial channel and the radio.
* Messages moving from serial to radio will be tagged with the group
* ID compiled into the TOSBase, and messages moving from radio to
* serial will be filtered by that same group id.
*/
#include "AM.h"
#include "Serial.h"
module BaseStationP {
uses {
interface Boot;
interface SplitControl as SerialControl;
interface SplitControl as RadioControl;
interface AMSend as UartSend[am_id_t id];
interface Receive as UartReceive[am_id_t id];
interface Packet as UartPacket;
interface AMPacket as UartAMPacket;
interface AMSend as RadioSend[am_id_t id];
interface Receive as RadioReceive[am_id_t id];
interface Packet as RadioPacket;
interface AMPacket as RadioAMPacket;
interface Leds;
}
}
implementation
{
enum {
UART_QUEUE_LEN = 12,
RADIO_QUEUE_LEN = 12,
};
message_t uartQueueBufs[UART_QUEUE_LEN];
message_t *uartQueue[UART_QUEUE_LEN];
uint8_t uartIn, uartOut;
bool uartBusy, uartFull;
message_t radioQueueBufs[RADIO_QUEUE_LEN];
message_t *radioQueue[RADIO_QUEUE_LEN];
uint8_t radioIn, radioOut;
bool radioBusy, radioFull;
task void uartSendTask();
task void radioSendTask();
void dropBlink() {
call Leds.led2Toggle();
}
void failBlink() {
call Leds.led2Toggle();
}
event void Boot.booted() {
uint8_t i;
for (i = 0; i < UART_QUEUE_LEN; i++)
uartQueue[i] = &uartQueueBufs[i];
uartIn = uartOut = 0;
uartBusy = FALSE;
uartFull = TRUE;
for (i = 0; i < RADIO_QUEUE_LEN; i++)
radioQueue[i] = &radioQueueBufs[i];
radioIn = radioOut = 0;
radioBusy = FALSE;
radioFull = TRUE;
call RadioControl.start();
call SerialControl.start();
}
event void RadioControl.startDone(error_t error) {
if (error == SUCCESS) {
radioFull = FALSE;
}
}
event void SerialControl.startDone(error_t error) {
if (error == SUCCESS) {
uartFull = FALSE;
}
}
event void SerialControl.stopDone(error_t error) {}
event void RadioControl.stopDone(error_t error) {}
uint8_t count = 0;
event message_t *RadioReceive.receive[am_id_t id](message_t *msg,
void *payload,
uint8_t len) {
message_t *ret = msg;
atomic {
if (!uartFull)
{
ret = uartQueue[uartIn];
uartQueue[uartIn] = msg;
uartIn = (uartIn + 1) % UART_QUEUE_LEN;
if (uartIn == uartOut)
uartFull = TRUE;
if (!uartBusy)
{
post uartSendTask();
uartBusy = TRUE;
}
}
else
dropBlink();
}
return ret;
}
uint8_t tmpLen;
task void uartSendTask() {
uint8_t len;
am_id_t id;
am_addr_t addr;
message_t* msg;
atomic
if (uartIn == uartOut && !uartFull)
{
uartBusy = FALSE;
return;
}
msg = uartQueue[uartOut];
tmpLen = len = call RadioPacket.payloadLength(msg);
id = call RadioAMPacket.type(msg);
addr = call RadioAMPacket.destination(msg);
if (call UartSend.send[id](addr, uartQueue[uartOut], len) == SUCCESS)
call Leds.led1Toggle();
else
{
failBlink();
post uartSendTask();
}
}
event void UartSend.sendDone[am_id_t id](message_t* msg, error_t error) {
if (error != SUCCESS)
failBlink();
else
atomic
if (msg == uartQueue[uartOut])
{
if (++uartOut >= UART_QUEUE_LEN)
uartOut = 0;
if (uartFull)
uartFull = FALSE;
}
post uartSendTask();
}
event message_t *UartReceive.receive[am_id_t id](message_t *msg,
void *payload,
uint8_t len) {
message_t *ret = msg;
bool reflectToken = FALSE;
atomic
if (!radioFull)
{
reflectToken = TRUE;
ret = radioQueue[radioIn];
radioQueue[radioIn] = msg;
if (++radioIn >= RADIO_QUEUE_LEN)
radioIn = 0;
if (radioIn == radioOut)
radioFull = TRUE;
if (!radioBusy)
{
post radioSendTask();
radioBusy = TRUE;
}
}
else
dropBlink();
if (reflectToken) {
//call UartTokenReceive.ReflectToken(Token);
}
return ret;
}
task void radioSendTask() {
uint8_t len;
am_id_t id;
am_addr_t addr;
message_t* msg;
atomic
if (radioIn == radioOut && !radioFull)
{
radioBusy = FALSE;
return;
}
msg = radioQueue[radioOut];
len = call UartPacket.payloadLength(msg);
addr = call UartAMPacket.destination(msg);
id = call UartAMPacket.type(msg);
if (call RadioSend.send[id](addr, msg, len) == SUCCESS)
call Leds.led0Toggle();
else
{
failBlink();
post radioSendTask();
}
}
event void RadioSend.sendDone[am_id_t id](message_t* msg, error_t error) {
if (error != SUCCESS)
failBlink();
else
atomic
if (msg == radioQueue[radioOut])
{
if (++radioOut >= RADIO_QUEUE_LEN)
radioOut = 0;
if (radioFull)
radioFull = FALSE;
}
post radioSendTask();
}
}
--- NEW FILE: CC2420ControlP.nc ---
/*
* 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 at archrock.com>
* @version $Revision: 1.1.2.1 $ $Date: 2006/10/30 21:53:03 $
*/
#include "Timer.h"
module CC2420ControlP {
provides interface Init;
provides interface Resource;
provides interface CC2420Config;
provides interface CC2420Power;
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 Resource as SpiResource;
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 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 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 = CC2420_DEF_CHANNEL;
uint8_t m_tx_power = CC2420_DEF_RFPOWER;
uint16_t m_pan = TOS_AM_GROUP;
uint16_t m_short_addr;
bool m_sync_busy;
task void syncDone_task();
norace cc2420_control_state_t m_state = S_VREG_STOPPED;
command error_t Init.init() {
call CSN.makeOutput();
call RSTN.makeOutput();
call VREN.makeOutput();
m_short_addr = call AMPacket.address();
return SUCCESS;
}
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();
}
}
event void SpiResource.granted() {
call CSN.clr();
signal Resource.granted();
}
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 event void StartupTimer.fired() {
if ( m_state == S_VREG_STARTING ) {
m_state = S_VREG_STARTED;
call RSTN.clr();
call RSTN.set();
signal CC2420Power.startVRegDone();
}
}
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 InterruptCCA.enableRisingEdge();
call SXOSCON.strobe();
call IOCFG0.write( ( 1 << CC2420_IOCFG0_FIFOP_POLARITY ) |
( 127 << CC2420_IOCFG0_FIFOP_THR ) );
call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
( ( (m_channel - 11)*5+357 )
<< CC2420_FSCTRL_FREQ ) );
call MDMCTRL0.write( ( 1 << CC2420_MDMCTRL0_RESERVED_FRAME_MODE ) |
( 2 << CC2420_MDMCTRL0_CCA_HYST ) |
( 3 << CC2420_MDMCTRL0_CCA_MOD ) |
( 1 << CC2420_MDMCTRL0_AUTOCRC ) |
( 2 << CC2420_MDMCTRL0_PREAMBLE_LENGTH ) );
}
return SUCCESS;
}
async event void InterruptCCA.fired() {
nxle_uint16_t id[ 2 ];
m_state = S_XOSC_STARTED;
id[ 0 ] = m_pan;
id[ 1 ] = m_short_addr;
call InterruptCCA.disable();
call IOCFG1.write( 0 );
call PANID.write( 0, (uint8_t*)&id, 4 );
call CSN.set();
call CSN.clr();
signal CC2420Power.startOscillatorDone();
}
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;
}
command uint8_t CC2420Config.getChannel() {
atomic return m_channel;
}
command void CC2420Config.setChannel( uint8_t channel ) {
atomic m_channel = channel;
}
command uint16_t CC2420Config.getShortAddr() {
atomic return m_short_addr;
}
command void CC2420Config.setShortAddr( uint16_t addr ) {
atomic m_short_addr = addr;
}
command uint16_t CC2420Config.getPanAddr() {
return m_pan;
}
command void CC2420Config.setPanAddr( uint16_t pan ) {
atomic m_pan = pan;
}
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_task();
}
return SUCCESS;
}
event void SyncResource.granted() {
nxle_uint16_t id[ 2 ];
uint8_t channel;
atomic {
channel = m_channel;
id[ 0 ] = m_pan;
id[ 1 ] = m_short_addr;
}
call CSN.clr();
call FSCTRL.write( ( 1 << CC2420_FSCTRL_LOCK_THR ) |
( ( (channel - 11)*5+357 ) << CC2420_FSCTRL_FREQ ) );
call PANID.write( 0, (uint8_t*)id, sizeof( id ) );
call CSN.set();
call SyncResource.release();
post syncDone_task();
}
task void syncDone_task() {
atomic m_sync_busy = FALSE;
signal CC2420Config.syncDone( SUCCESS );
}
default event void CC2420Config.syncDone( error_t error ) {}
}
--- NEW FILE: Makefile ---
COMPONENT=BaseStationC
include $(MAKERULES)
--- NEW FILE: README.txt ---
README for BaseStationCC2420
Author/Contact: tinyos-help at millennium.berkeley.edu
Description:
BaseStation is an application that acts as a simple Active Message
bridge between the serial and radio links. It replaces the GenericBase
of TinyOS 1.0 and the TOSBase of TinyOS 1.1. This base station
is for CC2420-based platforms (e.g., micaz, telos).
On the serial link, BaseStation sends and receives simple active
messages (not particular radio packets): on the radio link, it sends
radio active messages, whose format depends on the network stack being
used. BaseStation will copy its compiled-in group ID to messages
moving from the serial link to the radio, and will filter out incoming
radio messages that do not contain that group ID.
BaseStation includes queues in both directions, with a guarantee that
once a message enters a queue, it will eventually leave on the other
interface. The queues allow the BaseStation to handle load spikes more
gracefully.
BaseStation acknowledges a message arriving over the serial link only if
that message was successfully enqueued for delivery to the radio link.
The LEDS are programmed to toggle as follows:
RED Toggle - Message bridged from serial to radio
GREEN Toggle - Message bridged from radio to serial
YELLOW/BLUE Toggle - Dropped message due to queue overflow
in either direction
Tools:
tools/java/net/tinyos/sf/SerialForwarder.
See doc/serialcomm/index.html for more information using these tools.
More information about the Tinyos-2-commits
mailing list