HplAtm128Timer0AsyncC;
Init = Atm128AlarmAsyncP;
- Init = HplAtm128Timer0AsyncC;
Alarm = Atm128AlarmAsyncP;
Counter = Atm128AlarmAsyncP;
Atm128AlarmAsyncP.Timer -> HplAtm128Timer0AsyncC;
Atm128AlarmAsyncP.TimerCtrl -> HplAtm128Timer0AsyncC;
Atm128AlarmAsyncP.Compare -> HplAtm128Timer0AsyncC;
+ Atm128AlarmAsyncP.TimerAsync -> HplAtm128Timer0AsyncC;
}
// $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
* 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 {
interface HplAtm128Timer<uint8_t> as Timer;
interface HplAtm128TimerCtrl8 as TimerCtrl;
interface HplAtm128Compare<uint8_t> as Compare;
+ interface HplAtm128TimerAsync as TimerAsync;
}
}
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;
/* 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() {
/* 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() {
}
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())
{
call Compare.reset();
setInterrupt();
}
-#endif
}
async command void Alarm.start(uint32_t ndt) {
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
* 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
McuSleepC.McuPowerOverride -> HplAtm128Timer0AsyncP;
- Init = HplAtm128Timer0AsyncP;
Timer = HplAtm128Timer0AsyncP;
TimerCtrl = HplAtm128Timer0AsyncP;
Compare = HplAtm128Timer0AsyncP;
-
+ TimerAsync = HplAtm128Timer0AsyncP;
}
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;
}
//=== Write the control registers. ====================================
async command void TimerCtrl.setControl( Atm128TimerControl_t x ) {
- while (ASSR & 1 << TCR0UB)
- ;
TCCR0 = x.flat;
}
//=== 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)
;
// 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;
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;
+ }
}
--- /dev/null
+// $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();
+
+}