[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