[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/atm128/timer
Atm128AlarmAsyncC.nc, NONE, 1.1 Atm128AlarmAsyncP.nc, NONE, 1.1
David Gay
idgay at users.sourceforge.net
Mon Mar 26 14:23:22 PDT 2007
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/atm128/timer
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv15788
Added Files:
Atm128AlarmAsyncC.nc Atm128AlarmAsyncP.nc
Log Message:
more reliable alarm system on async timer - avoid overflow, which seems to
cause problems
should have less interrupt overhead too
preliminary version - no wrap around support
--- NEW FILE: Atm128AlarmAsyncC.nc ---
generic configuration Atm128AlarmAsyncC(typedef precision, int divider) {
provides {
interface Init @atleastonce();
interface Alarm<precision, uint32_t>;
interface Counter<precision, uint32_t>;
}
}
implementation
{
components new Atm128AlarmAsyncP(precision, divider),
HplAtm128Timer0AsyncC;
Init = Atm128AlarmAsyncP;
Init = HplAtm128Timer0AsyncC;
Alarm = Atm128AlarmAsyncP;
Counter = Atm128AlarmAsyncP;
Atm128AlarmAsyncP.Timer -> HplAtm128Timer0AsyncC;
Atm128AlarmAsyncP.TimerCtrl -> HplAtm128Timer0AsyncC;
Atm128AlarmAsyncP.Compare -> HplAtm128Timer0AsyncC;
}
--- NEW FILE: Atm128AlarmAsyncP.nc ---
generic module Atm128AlarmAsyncP(typedef precision, int divider) {
provides {
interface Init;
interface Alarm<precision, uint32_t>;
interface Counter<precision, uint32_t>;
}
uses {
interface HplAtm128Timer<uint8_t> as Timer;
interface HplAtm128TimerCtrl8 as TimerCtrl;
interface HplAtm128Compare<uint8_t> as Compare;
}
}
implementation
{
uint8_t set;
uint32_t t0, dt;
uint32_t base, lastNow;
void oopsT0() {
}
void oopsNow() {
}
enum {
MINDT = 10,
MAXT = 230
};
void setOcr0(uint8_t n) {
while (ASSR & 1 << OCR0UB)
;
if (n == TCNT0)
n++;
OCR0 = n;
}
void setInterrupt() {
bool fired = FALSE;
atomic
{
uint8_t interrupt_in = 1 + call Compare.get() - call Timer.get();
uint8_t newOcr0;
if (interrupt_in < MINDT || (call TimerCtrl.getInterruptFlag()).bits.ocf0)
return; // wait for next interrupt
if (!set)
newOcr0 = MAXT;
else
{
uint32_t now = call Counter.get();
if (now < t0)
{
oopsT0();
t0 = now;
}
if (now - t0 >= dt)
{
set = FALSE;
fired = TRUE;
newOcr0 = MAXT;
}
else
{
uint32_t alarm_in = (t0 + dt) - base;
if (alarm_in > MAXT)
newOcr0 = MAXT;
else if (alarm_in < MINDT)
newOcr0 = MINDT;
else
newOcr0 = alarm_in;
}
}
newOcr0--; // interrupt is 1ms late
setOcr0(newOcr0);
}
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;
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;
if (now < lastNow)
{
oopsNow();
now = lastNow;
}
lastNow = now;
}
return now;
}
async command bool Counter.isOverflowPending() {
return FALSE;
}
async command void Counter.clearOverflow() { }
async command void Alarm.start(uint32_t ndt) {
call Alarm.startAt(call Counter.get(), ndt);
}
async command void Alarm.stop() {
atomic set = FALSE;
}
async command bool Alarm.isRunning() {
atomic return set;
}
async command void Alarm.startAt(uint32_t nt0, uint32_t ndt) {
atomic
{
set = TRUE;
t0 = nt0;
dt = ndt;
}
setInterrupt();
}
async command uint32_t Alarm.getNow() {
return call Counter.get();
}
async command uint32_t Alarm.getAlarm() {
atomic return t0 + dt;
}
async event void Timer.overflow() { }
}
More information about the Tinyos-2-commits
mailing list