]> oss.titaniummirror.com Git - tinyos-2.x.git/commitdiff
a nicer version, w/ cleaner HPL access
authoridgay <idgay>
Thu, 29 Mar 2007 21:07:25 +0000 (21:07 +0000)
committeridgay <idgay>
Thu, 29 Mar 2007 21:07:25 +0000 (21:07 +0000)
in particular, HPL for timer0 now has less magic in it (this means that
users of it have to be more aware of the asynchronous timer access rules,
though)

tos/chips/atm128/timer/Atm128AlarmAsyncC.nc
tos/chips/atm128/timer/Atm128AlarmAsyncP.nc
tos/chips/atm128/timer/Atm128Timer.h
tos/chips/atm128/timer/HplAtm128Timer0AsyncC.nc
tos/chips/atm128/timer/HplAtm128Timer0AsyncP.nc
tos/chips/atm128/timer/HplAtm128TimerAsync.nc [new file with mode: 0644]

index 6acee17c0e8df75ada1b9fcd02ddf40d81d2a0f9..46f1af115758c28dc6eecea3c5945dfc2f3dda28 100644 (file)
@@ -11,11 +11,11 @@ implementation
     HplAtm128Timer0AsyncC;
 
   Init = Atm128AlarmAsyncP;
-  Init = HplAtm128Timer0AsyncC;
   Alarm = Atm128AlarmAsyncP;
   Counter = Atm128AlarmAsyncP;
 
   Atm128AlarmAsyncP.Timer -> HplAtm128Timer0AsyncC;
   Atm128AlarmAsyncP.TimerCtrl -> HplAtm128Timer0AsyncC;
   Atm128AlarmAsyncP.Compare -> HplAtm128Timer0AsyncC;
+  Atm128AlarmAsyncP.TimerAsync -> HplAtm128Timer0AsyncC;
 }
index 269c6552020cd50c86d7fb07646cc90b6c633c02..a97c69e3938925d61b9bf37d000d7d08bd2f8988 100644 (file)
@@ -1,6 +1,6 @@
 // $Id$
 /*
- * Copyright (c) 2005-2006 Intel Corporation
+ * Copyright (c) 2007 Intel Corporation
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached INTEL-LICENSE     
@@ -17,6 +17,8 @@
  * 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.
+ *
+ * @author David Gay
  */
 generic module Atm128AlarmAsyncP(typedef precision, int divider) {
   provides {
@@ -28,6 +30,7 @@ generic module Atm128AlarmAsyncP(typedef precision, int divider) {
     interface HplAtm128Timer<uint8_t> as Timer;
     interface HplAtm128TimerCtrl8 as TimerCtrl;
     interface HplAtm128Compare<uint8_t> as Compare;
+    interface HplAtm128TimerAsync as TimerAsync;
   }
 }
 implementation
@@ -53,12 +56,13 @@ implementation
       {
        Atm128TimerControl_t x;
 
-       call Compare.start();
+       call TimerAsync.setTimer0Asynchronous();
        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);
+       call Compare.set(MAXT); /* setInterrupt needs a valid value here */
+       call Compare.start();
        setInterrupt();
       }
     return SUCCESS;
@@ -66,21 +70,18 @@ implementation
 
   /* 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)
+    while (call TimerAsync.compareBusy())
       ;
-    if (n == TCNT0)
+    if (n == call Timer.get())
       n++;
-#if 1
     /* 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;
-#endif
-    OCR0 = n; 
+    call Compare.set(n);
   }
 
   void fire() {
@@ -149,10 +150,8 @@ implementation
     /* Compare register fired. Update time knowledge */
     base += call Compare.get() + 1; // interrupt is 1ms late
     setInterrupt();
-#if 1
     if (!base)
       overflow();
-#endif
   }  
 
   async command uint32_t Counter.get() {
@@ -177,17 +176,12 @@ implementation
   }
 
   async command bool Counter.isOverflowPending() {
-#if 0
-    return FALSE;
-#else
     atomic
       return (call TimerCtrl.getInterruptFlag()).bits.ocf0 &&
        !(base + call Compare.get() + 1);
-#endif
   }
 
   async command void Counter.clearOverflow() { 
-#if 1
     atomic
       if (call Counter.isOverflowPending())
        {
@@ -195,7 +189,6 @@ implementation
          call Compare.reset();
          setInterrupt();
        }
-#endif
   }
 
   async command void Alarm.start(uint32_t ndt) {
index 9cf0c4e95531b1ec1d60acf6eeb97e369508b01f..fe7b58dda9397813491b11acfbc3b8bb83f875e8 100644 (file)
@@ -118,7 +118,7 @@ typedef union
     uint8_t as0    : 1;  //!< Asynchronous Timer/Counter (off=CPU,on=32KHz osc)
     uint8_t rsvd   : 4;  //!< Reserved
   } bits;
-} Atm128_ASSR_t;
+} Atm128Assr_t;
 
 /* Timer/Counter Interrupt Mask Register */
 typedef union
index cd610a3c51e7104ec725dd6e470b54d9808825d9..0838d5867ea174943c005b5d7fa2522fcf0c47c6 100644 (file)
@@ -35,6 +35,7 @@
  * wires it to McuSleepC for low-power calculations..
  *
  * @author Philip Levis
+ * @author David Gay
  */
 
 #include <Atm128Timer.h>
 configuration HplAtm128Timer0AsyncC
 {
   provides {
-    interface Init @atleastonce();
     // 8-bit Timers
     interface HplAtm128Timer<uint8_t>   as Timer;
     interface HplAtm128TimerCtrl8       as TimerCtrl;
     interface HplAtm128Compare<uint8_t> as Compare;
+    interface HplAtm128TimerAsync       as TimerAsync;
   }
 }
 implementation
@@ -56,9 +57,8 @@ implementation
 
   McuSleepC.McuPowerOverride -> HplAtm128Timer0AsyncP;
 
-  Init = HplAtm128Timer0AsyncP;
   Timer = HplAtm128Timer0AsyncP;
   TimerCtrl = HplAtm128Timer0AsyncP;
   Compare = HplAtm128Timer0AsyncP;
-  
+  TimerAsync = HplAtm128Timer0AsyncP;
 }
index 4d81a5e17ce1b3939636532848cbb8d62518b529..ce05c7567d2ab8700ed6a176812ddd36e875e423 100644 (file)
 
 module HplAtm128Timer0AsyncP {
   provides {
-    interface Init @atleastonce();
     // 8-bit Timers
     interface HplAtm128Timer<uint8_t>   as Timer;
     interface HplAtm128TimerCtrl8       as TimerCtrl;
     interface HplAtm128Compare<uint8_t> as Compare;
     interface McuPowerOverride;
+    interface HplAtm128TimerAsync       as TimerAsync;
   }
 }
 implementation
 {
-  command error_t Init.init() {
-    SET_BIT(ASSR, AS0);  // set Timer/Counter0 to asynchronous mode
-    return SUCCESS;
-  }
-
   //=== Read the current timer value. ===================================
   async command uint8_t  Timer.get() { return TCNT0; }
 
   //=== Set/clear the current timer value. ==============================
   async command void Timer.set(uint8_t t)  {
-    while (ASSR & 1 << TCN0UB)
-      ;
     TCNT0 = t;
   }
 
@@ -81,8 +74,6 @@ implementation
 
   //=== Write the control registers. ====================================
   async command void TimerCtrl.setControl( Atm128TimerControl_t x ) { 
-    while (ASSR & 1 << TCR0UB)
-      ;
     TCCR0 = x.flat; 
   }
 
@@ -142,16 +133,11 @@ implementation
 
   //=== Write the compare registers. ====================================
   async command void Compare.set(uint8_t t)   { 
-    atomic
-      {
-       while (ASSR & 1 << OCR0UB)
-         ;
-       OCR0 = t; 
-      }
+    OCR0 = t; 
   }
 
   //=== Timer interrupts signals ========================================
-  void stabiliseTimer0() {
+  inline void stabiliseTimer0() {
     TCCR0 = TCCR0;
     while (ASSR & 1 << TCR0UB)
       ;
@@ -174,7 +160,7 @@ implementation
       // need to wait for timer 0 updates propagate before sleeping
       // (we don't need to worry about reentering sleep mode too early,
       // as the wake ups from timer0 wait at least one TOSC1 cycle
-      // anyway - see the stabiliseTimer0 function in HplAtm128Timer0AsyncC)
+      // anyway - see the stabiliseTimer0 function)
       while (ASSR & (1 << TCN0UB | 1 << OCR0UB | 1 << TCR0UB))
        ;
       diff = OCR0 - TCNT0;
@@ -199,4 +185,29 @@ implementation
     stabiliseTimer0();
     signal Timer.overflow();
   }
+
+  // Asynchronous status register support
+  async command Atm128Assr_t TimerAsync.getAssr() {
+    return *(Atm128Assr_t *)&ASSR;
+  }
+
+  async command void TimerAsync.setAssr(Atm128Assr_t x) {
+    ASSR = x.flat;
+  }
+
+  async command void TimerAsync.setTimer0Asynchronous() {
+    ASSR |= 1 << AS0;
+  }
+
+  async command bool TimerAsync.controlBusy() {
+    return (ASSR & (1 << TCR0UB)) != 0;
+  }
+
+  async command bool TimerAsync.compareBusy() {
+    return (ASSR & (1 << OCR0UB)) != 0;
+  }
+
+  async command bool TimerAsync.countBusy() {
+    return (ASSR & (1 << TCN0UB)) != 0;
+  }
 }
diff --git a/tos/chips/atm128/timer/HplAtm128TimerAsync.nc b/tos/chips/atm128/timer/HplAtm128TimerAsync.nc
new file mode 100644 (file)
index 0000000..0965e98
--- /dev/null
@@ -0,0 +1,52 @@
+// $Id$
+/*
+ * Copyright (c) 2007 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 David Gay
+ */
+interface HplAtm128TimerAsync
+{
+  /**
+   * Read timer0 asynchronous status register (ASSR)
+   * @return Current value of ASSR
+   */
+  async command Atm128Assr_t getAssr();
+
+  /**
+   * Set timer0 asynchronous status register (ASSR)
+   * @param x New value for ASSR
+   */
+  async command void setAssr(Atm128Assr_t x);
+
+  /**
+   * Turn on timer 0 asynchronous mode
+   */
+  async command void setTimer0Asynchronous();
+
+  /**
+   * Check if control register TCCR0 is busy (should not be updated if true)
+   * @return TRUE if TCCR0 is busy, FALSE otherwise (can be updated)
+   */
+  async command bool controlBusy();
+
+  /**
+   * Check if compare register OCR0 is busy (should not be updated if true)
+   * @return TRUE if OCR0 is busy, FALSE otherwise (can be updated)
+   */
+  async command bool compareBusy();
+
+  /**
+   * Check if current timer value (TCNT0) is busy (should not be updated if true)
+   * @return TRUE if TCNT0 is busy, FALSE otherwise (can be updated)
+   */
+  async command bool countBusy();
+
+}