[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/atm128/timer Atm128AlarmAsyncP.nc, 1.2, 1.3

David Gay idgay at users.sourceforge.net
Mon Mar 26 15:38:41 PDT 2007


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/timer
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv16220

Modified Files:
	Atm128AlarmAsyncP.nc 
Log Message:
comments, overflow and increase mindt

still under test


Index: Atm128AlarmAsyncP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/timer/Atm128AlarmAsyncP.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** Atm128AlarmAsyncP.nc	26 Mar 2007 21:46:01 -0000	1.2
--- Atm128AlarmAsyncP.nc	26 Mar 2007 22:38:39 -0000	1.3
***************
*** 1,2 ****
--- 1,22 ----
+ // $Id$
+ /*
+  * Copyright (c) 2005-2006 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.
+  */
+ /**
+  * Build a 32-bit alarm and counter from the atmega128's 8-bit timer 0
+  * in asynchronous mode. Attempting to use the generic Atm128AlarmC
+  * component and the generic timer components runs into problems
+  * apparently related to letting timer 0 overflow.
+  * 
+  * So, instead, this version (inspired by the 1.x code and a remark from
+  * Martin Turon) directly builds a 32-bit alarm and counter on top of timer 0
+  * and never lets timer 0 overflow.
+  */
  generic module Atm128AlarmAsyncP(typedef precision, int divider) {
    provides {
***************
*** 13,25 ****
  implementation
  {
!   uint8_t set;
!   uint32_t t0, dt;
!   uint32_t base;
  
    enum {
!     MINDT = 2,
!     MAXT = 230
    };
  
    void setOcr0(uint8_t n) {
      while (ASSR & 1 << OCR0UB)
--- 33,72 ----
  implementation
  {
!   uint8_t set; 			/* Is the alarm set? */
!   uint32_t t0, dt;		/* Time of the next alarm */
!   uint32_t base;		/* base+TCNT0 is the current time if no
! 				   interrupt is pending. See Counter.get()
! 				   for the full details. */
  
    enum {
!     MINDT = 3,			/* Minimum interval between interrupts */
!     MAXT = 230			/* Maximum value to let timer 0 reach
! 				   (from Joe Polastre and Robert Szewczyk's
! 				   painful experiences with the 1.x timer ;-)) */
    };
  
+   void setInterrupt();
+ 
+   /* Configure timer 0 */
+   command error_t Init.init() {
+     atomic
+       {
+ 	Atm128TimerControl_t x;
+ 
+ 	call Compare.start();
+ 	x.flat = 0;
+ 	x.bits.cs = divider;
+ 	x.bits.wgm1 = 1; /* We use the clear-on-compare mode */
+ 	call TimerCtrl.setControl(x);
+ 	call Compare.set(MAXT);
+ 	setInterrupt();
+       }
+     return SUCCESS;
+   }
+ 
+   /* Set compare register for timer 0 to n. But increment n by 1 if TCNT0 
+      reaches this value before we can set the compare register.
+      Direct register access used because the HPL doesn't allow us to do this.
+   */
    void setOcr0(uint8_t n) {
      while (ASSR & 1 << OCR0UB)
***************
*** 27,33 ****
--- 74,93 ----
      if (n == TCNT0)
        n++;
+     /* Support for overflow. Force interrupt at wrap around value. 
+        This does not cause a backwards-in-time value as we do this
+        every time we set OCR0. */
+     if (base + n + 1 < base)
+       n = -base - 1;
      OCR0 = n; 
    }
  
+   void fire() {
+     __nesc_enable_interrupt();
+     signal Alarm.fired();
+   }
+ 
+   /* Update the compare register to trigger an interrupt at the
+      appropriate time based on the current alarm settings
+    */
    void setInterrupt() {
      bool fired = FALSE;
***************
*** 35,38 ****
--- 95,101 ----
      atomic
        {
+ 	/* interrupt_in is the time to the next interrupt. Note that
+ 	   compare register values are off by 1 (i.e., if you set OCR0 to
+ 	   3, the interrupt will happen whjen TCNT0 is 4) */
  	uint8_t interrupt_in = 1 + call Compare.get() - call Timer.get();
  	uint8_t newOcr0;
***************
*** 40,43 ****
--- 103,108 ----
  	if (interrupt_in < MINDT || (call TimerCtrl.getInterruptFlag()).bits.ocf0)
  	  return; // wait for next interrupt
+ 
+ 	/* When no alarm is set, we just ask for an interrupt every MAXT */
  	if (!set)
  	  newOcr0 = MAXT;
***************
*** 46,49 ****
--- 111,115 ----
  	    uint32_t now = call Counter.get();
  
+ 	    /* Check if alarm expired */
  	    if ((uint32_t)(now - t0) >= dt)
  	      {
***************
*** 54,57 ****
--- 120,125 ----
  	    else
  	      {
+ 		/* No. Set compare register to time of next alarm if it's
+ 		   within the next MAXT units */
  		uint32_t alarm_in = (t0 + dt) - base;
  
***************
*** 68,95 ****
        }
      if (fired)
!       signal Alarm.fired();
    }
  
    async event void Compare.fired() {
!     base += call Compare.get() + 1;
      setInterrupt();
    }  
  
-   command error_t Init.init() {
-     atomic
-       {
- 	Atm128TimerControl_t x;
- 
- 	call Compare.start();
- 	x.flat = 0;
- 	x.bits.cs = divider;
- 	x.bits.wgm1 = 1;
- 	call TimerCtrl.setControl(x);
- 	call Compare.set(MAXT);
- 	setInterrupt();
-       }
-     return SUCCESS;
-   }
- 
    async command uint32_t Counter.get() {
      uint32_t now;
--- 136,155 ----
        }
      if (fired)
!       fire();
!   }
! 
!   void overflow() {
!     __nesc_enable_interrupt();
!     signal Counter.overflow();
    }
  
    async event void Compare.fired() {
!     /* Compare register fired. Update time knowledge */
!     base += call Compare.get() + 1; // interrupt is 1ms late
      setInterrupt();
+     if (!base)
+       overflow();
    }  
  
    async command uint32_t Counter.get() {
      uint32_t now;
***************
*** 97,105 ****
      atomic
        {
  	uint8_t now8 = call Timer.get();
  
  	if ((call TimerCtrl.getInterruptFlag()).bits.ocf0)
! 	  now = base + call Counter.get() + call Timer.get();
  	else
  	  now = base + now8;
        }
--- 157,171 ----
      atomic
        {
+ 	/* Current time is base+TCNT0 if no interrupt is pending. But if
+ 	   an interrupt is pending, then it's base + compare value + 1 + TCNT0 */
  	uint8_t now8 = call Timer.get();
  
  	if ((call TimerCtrl.getInterruptFlag()).bits.ocf0)
! 	  /* We need to reread TCNT0 as it might've overflowed after we
! 	     read TCNT0 the first time */
! 	  now = base + call Counter.get() + 1 + call Timer.get();
  	else
+ 	  /* We need to use the value of TCNT0 from before we check the
+ 	     interrupt flag, as it might wrap around after the check */
  	  now = base + now8;
        }
***************
*** 108,115 ****
  
    async command bool Counter.isOverflowPending() {
!     return FALSE;
    }
  
!   async command void Counter.clearOverflow() { }
  
    async command void Alarm.start(uint32_t ndt) {
--- 174,191 ----
  
    async command bool Counter.isOverflowPending() {
!     atomic
!       return (call TimerCtrl.getInterruptFlag()).bits.ocf0 &&
! 	!(base + call Counter.get() + 1);
    }
  
!   async command void Counter.clearOverflow() { 
!     atomic
!       if (call Counter.isOverflowPending())
! 	{
! 	  base = 0;
! 	  call Compare.reset();
! 	  setInterrupt();
! 	}
!   }
  
    async command void Alarm.start(uint32_t ndt) {



More information about the Tinyos-2-commits mailing list