[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