[Tinyos-contrib-commits]
CVS: tinyos-1.x/contrib/SP/tos/platform/micaz
HPLClock.nc, NONE, 1.1 LocalTime.nc, NONE, 1.1 TimerC.nc, NONE,
1.1 TimerM.nc, NONE, 1.1
Arsalan Tavakoli
arsalant at users.sourceforge.net
Mon Jul 24 13:14:26 PDT 2006
Update of /cvsroot/tinyos/tinyos-1.x/contrib/SP/tos/platform/micaz
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv10552
Added Files:
HPLClock.nc LocalTime.nc TimerC.nc TimerM.nc
Log Message:
--- NEW FILE: HPLClock.nc ---
// $Id: HPLClock.nc,v 1.1 2006/07/24 20:14:23 arsalant 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.
*/
/*
*
* Authors: Jason Hill, David Gay, Philip Levis
* Date last modified: 6/25/02
*
*/
// The Mica-specific parts of the hardware presentation layer.
/**
* @author Jason Hill
* @author David Gay
* @author Philip Levis
*/
module HPLClock {
provides interface Clock;
provides interface StdControl;
}
implementation
{
uint8_t set_flag;
uint8_t mscale, nextScale, minterval ;
command result_t StdControl.init() {
atomic {
mscale = DEFAULT_SCALE;
minterval = DEFAULT_INTERVAL;
}
return SUCCESS;
}
command result_t StdControl.start() {
uint8_t mi, ms;
atomic {
mi = minterval;
ms = mscale;
}
call Clock.setRate(mi, ms);
return SUCCESS;
}
command result_t StdControl.stop() {
uint8_t mi;
atomic {
mi = minterval;
}
call Clock.setRate(mi, 0);
return SUCCESS;
}
async command void Clock.setInterval(uint8_t value) {
outp(value, OCR0);
}
async command void Clock.setNextInterval(uint8_t value) {
atomic {
minterval = value;
set_flag = 1;
}
}
async command uint8_t Clock.getInterval() {
return inp(OCR0);
}
async command uint8_t Clock.getScale() {
uint8_t ms;
atomic {
ms = mscale;
}
return ms;
}
async command void Clock.setNextScale(uint8_t scale) {
atomic {
nextScale= scale;
set_flag=1;
}
}
async command result_t Clock.setIntervalAndScale(uint8_t interval, uint8_t scale) {
if (scale >7) return FAIL;
scale|=0x8;
atomic {
cbi(TIMSK, OCIE0);
outp(scale, TCCR0);
mscale = scale;
outp(0,TCNT0);
outp(interval, OCR0);
minterval = interval;
sbi(TIMSK, OCIE0);
}
return SUCCESS;
}
async command uint8_t Clock.readCounter() {
return (inp(TCNT0));
}
async command void Clock.setCounter(uint8_t n) {
outp(n, TCNT0);
}
async command void Clock.intDisable() {
cbi(TIMSK, OCIE0);
}
async command void Clock.intEnable() {
sbi(TIMSK, OCIE0);
}
async command result_t Clock.setRate(char interval, char scale) {
scale &= 0x7;
// scale |= 0x8;
atomic {
cbi(TIMSK, TOIE0);
cbi(TIMSK, OCIE0); //Disable TC0 interrupt
sbi(ASSR, AS0); //set Timer/Counter0 to be asynchronous
//from the CPU clock with a second external
//clock(32,768kHz)driving it.
outp(scale, TCCR0); //prescale the timer to be clock/128 to make it
outp(0, TCNT0);
outp(interval, OCR0);
sbi(TIMSK, OCIE0);
}
return SUCCESS;
}
default async event result_t Clock.fire() { return SUCCESS; }
TOSH_INTERRUPT(SIG_OUTPUT_COMPARE0) {
atomic {
if (set_flag) {
mscale = nextScale;
nextScale|=0x8;
outp(nextScale, TCCR0);
outp(minterval, OCR0);
set_flag=0;
}
}
signal Clock.fire();
}
}
--- NEW FILE: LocalTime.nc ---
//$Id: LocalTime.nc,v 1.1 2006/07/24 20:14:23 arsalant Exp $
/* "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."
*/
// @author Cory Sharp <cssharp at eecs.berkeley.edu>
interface LocalTime
{
async command uint32_t read();
}
--- NEW FILE: TimerC.nc ---
// $Id: TimerC.nc,v 1.1 2006/07/24 20:14:23 arsalant 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.
*/
/*
* Authors: Su Ping, (converted to nesC by Sam Madden)
* David Gay, Intel Research Berkeley Lab
* Phil Levis
* Date: 4/12/2002
* NesC conversion: 6/28/2002
* interface cleanup: 7/16/2002
* Configuration: 8/12/2002
*/
/**
* @author Su Ping
* @author (converted to nesC by Sam Madden)
* @author David Gay
* @author Intel Research Berkeley Lab
* @author Phil Levis
*/
configuration TimerC {
provides interface Timer[uint8_t id];
provides interface LocalTime;
provides interface StdControl;
}
implementation {
components TimerM, ClockC, NoLeds as Leds, HPLPowerManagementM;
TimerM.Leds -> Leds;
TimerM.Clock -> ClockC;
TimerM.PowerManagement -> HPLPowerManagementM;
StdControl = TimerM;
LocalTime = TimerM;
Timer = TimerM;
}
--- NEW FILE: TimerM.nc ---
// $Id: TimerM.nc,v 1.1 2006/07/24 20:14:23 arsalant 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.
*/
/*
*
* Authors: Joe Polastre <polastre at cs.berkeley.edu>
* Rob Szewczyk <szewczyk at cs.berkeley.edu>
* David Gay <dgay at intel-research.net>
* David Moore
*
* Revision: $Id: TimerM.nc,v 1.1 2006/07/24 20:14:23 arsalant Exp $
* This implementation assumes that DEFAULT_SCALE is 3.
*/
/**
* @author Su Ping <sping at intel-research.net>
*/
module TimerM {
provides interface Timer[uint8_t id];
provides interface LocalTime;
provides interface StdControl;
uses {
interface Leds;
interface Clock;
interface PowerManagement;
}
}
implementation {
uint32_t mState; // each bit represent a timer state
uint8_t setIntervalFlag;
uint8_t mScale, mInterval;
int8_t queue_head;
int8_t queue_tail;
uint8_t queue_size;
uint8_t queue[NUM_TIMERS];
volatile uint16_t interval_outstanding;
// for LocalTime
uint32_t localTime;
struct timer_s {
uint8_t type; // one-short or repeat timer
int32_t ticks; // clock ticks for a repeat timer
int32_t ticksLeft; // ticks left before the timer expires
} mTimerList[NUM_TIMERS];
enum {
maxTimerInterval = 230
};
command result_t StdControl.init() {
mState=0;
setIntervalFlag = 0;
queue_head = queue_tail = -1;
queue_size = 0;
mScale = 3;
mInterval = maxTimerInterval;
atomic localTime = 0;
return call Clock.setRate(mInterval, mScale) ;
}
command result_t StdControl.start() {
return SUCCESS;
}
command result_t StdControl.stop() {
mState=0;
mInterval = maxTimerInterval;
setIntervalFlag = 0;
return SUCCESS;
}
command result_t Timer.start[uint8_t id](char type,
uint32_t interval) {
uint8_t diff;
if (id >= NUM_TIMERS) return FAIL;
if (type > TIMER_ONE_SHOT) return FAIL;
// PAL:
// The current implementation of TimerM cannot support
// continuous timers that fire faster than every 3 ticks (3ms).
// The problem is due to the possibility that the hardware clock
// could increment while setting the compare value, which would lead
// to 256 ms until it fires, instead of 1-2.
if ((type == TIMER_REPEAT) && interval <= 2) return FAIL;
mTimerList[id].ticks = interval ;
mTimerList[id].type = type;
atomic {
diff = call Clock.readCounter();
interval += diff;
mTimerList[id].ticksLeft = interval;
mState|=(0x1L<<id);
if (interval < mInterval) {
mInterval=interval;
call Clock.setInterval(mInterval);
setIntervalFlag = 0;
call PowerManagement.adjustPower();
}
}
return SUCCESS;
}
static void adjustInterval() {
uint8_t i, val = maxTimerInterval;
if ( mState) {
for (i=0;i<NUM_TIMERS;i++) {
if ((mState&(0x1L<<i)) && (mTimerList[i].ticksLeft <val )) {
val = mTimerList[i].ticksLeft;
}
}
/* DCM: If the interval is set to be less than the current
* counter value, the timer will count an extra 256 ticks before
* hitting the interrupt. Thus, we check for this condition
* and avoid it. */
/* PAL: This piece of code sets a maximum interrupt rate
* that TimerM will request for continuous timers. TimerM
* will never request an interrupt less than 3ms from the
* current time; it therefore returns FAIL on continuous
* timers with an interval <= 2 (see Timer.start()). */
atomic {
uint8_t counter = call Clock.readCounter();
if (val >= counter)
val -= counter;
i = call Clock.readCounter() + 3;
if (val < i) {
val = i;
}
mInterval = val;
call Clock.setInterval(mInterval);
setIntervalFlag = 0;
}
} else {
atomic {
// mInterval=maxTimerInterval;
//call Clock.setInterval(mInterval);
setIntervalFlag = 0;
}
}
call PowerManagement.adjustPower();
}
command result_t Timer.stop[uint8_t id]() {
if (id>=NUM_TIMERS) return FAIL;
if (mState&(0x1L<<id)) { // if the timer is running
atomic mState &= ~(0x1L<<id);
if (!mState) {
setIntervalFlag = 1;
}
return SUCCESS;
}
return FAIL; //timer not running
}
default event result_t Timer.fired[uint8_t id]() {
return SUCCESS;
}
void enqueue(uint8_t value) {
if (queue_tail == NUM_TIMERS - 1)
queue_tail = -1;
queue_tail++;
queue_size++;
queue[(uint8_t)queue_tail] = value;
}
uint8_t dequeue() {
if (queue_size == 0)
return NUM_TIMERS;
if (queue_head == NUM_TIMERS - 1)
queue_head = -1;
queue_head++;
queue_size--;
return queue[(uint8_t)queue_head];
}
task void signalOneTimer() {
uint8_t itimer = dequeue();
if (itimer < NUM_TIMERS)
signal Timer.fired[itimer]();
}
task void HandleFire() {
uint8_t i;
uint16_t int_out;
setIntervalFlag = 1;
/* DCM: read the number of ticks elapsed since the last firing
* was handled. */
atomic {
int_out = interval_outstanding;
interval_outstanding = 0;
}
if (mState) {
for (i=0;i<NUM_TIMERS;i++) {
if (mState&(0x1L<<i)) {
mTimerList[i].ticksLeft -= int_out;
if (mTimerList[i].ticksLeft<=2) {
/* DCM: only update the timer structure if the
* signalOneTimer() task was able to be posted. */
if (post signalOneTimer()) {
if (mTimerList[i].type==TIMER_REPEAT) {
mTimerList[i].ticksLeft += mTimerList[i].ticks;
} else {// one shot timer
mState &=~(0x1L<<i);
}
enqueue(i);
}
else {
dbg(DBG_ERROR, "TimerM: Have to wait another timer interval.\n");
/* DCM: wait another interval in hopes that
* the task queue will clear out. */
atomic mTimerList[i].ticksLeft = mInterval;
}
}
}
}
}
/* DCM: don't bother adjusting the interval if another interrupt
* is hot on our tail. */
atomic int_out = interval_outstanding;
if (int_out == 0)
adjustInterval();
}
async event result_t Clock.fire() {
atomic {
localTime += call Clock.readCounter();
outp(0, TCNT0);
/* DCM: Once we've posted HandleFire(), don't post it again until
* the original one is handled. This prevents the task queue
* from getting flooded when mInterval is small. */
if (interval_outstanding == 0)
post HandleFire();
else
dbg(DBG_ERROR, "Don't post handle fire, we're not ready\n");
/* DCM: Keep track of the interval since the last interrupt */
interval_outstanding += call Clock.getInterval() + 1;
}
return SUCCESS;
}
// JWH: for 32-bit local time
async command uint32_t LocalTime.read() {
uint32_t now;
atomic {
now = localTime;
// check for pending overflow
if ( inp(TIFR) & 0x2 ) {
// account for compare match
now += call Clock.getInterval();
}
// calculate local time
now += call Clock.readCounter();
}
return now;
}
}
More information about the Tinyos-contrib-commits
mailing list