X-Git-Url: https://oss.titaniummirror.com/gitweb?a=blobdiff_plain;f=tmr.h;fp=tmr.h;h=716ff65a6d5b68d24f6f937efe5d100811bb74c0;hb=5fa3659d382d2055d1bdb1c06b6b82dcfc68bb95;hp=0000000000000000000000000000000000000000;hpb=2c0e3168697a040a21ee29a8dfe68d266fc98298;p=rgblamp.git diff --git a/tmr.h b/tmr.h new file mode 100644 index 0000000..716ff65 --- /dev/null +++ b/tmr.h @@ -0,0 +1,105 @@ +/* + * File: tmr.h + * + * Generic timer module. Currently uses Timer0 to generate ticks every + * 32 ms. Later will use Timer1, a crystal, and optionally a compare + * module to be able to generate ticks and wake up from sleep. + * + * The user code must call tmr_isr() from the interrupt function. It then + * will call tmr functions to activate and query timers. For example: + * + * void interrupt isr() + * { + * tmr_isr(); + * + * // ISR may take actions based on timers being fired. + * if (tmr_fired(TMR_SOMESUCH)) { + * // do something that is critically time important + * } + * } + * + * void main() + * { + * tmr_init(); + * tmr_startPeriodic(TMR_SOMESUCH, 1000); + * tmr_startPeriodic(TMR_ANOTHER, 500); + * + * while (1) { + * if (tmr_fired(TMR_ANOTHER)) { + * // Do stuff that doesn't have to be in the ISR + * } + * SLEEP(); + * } + * } + */ + + +#ifndef _TMR_H +#define _TMR_H + +#include "tmr_defs.h" +#include "isr.h" +#include "bit.h" + +/* Only access when in ISR or if interrupts are disabled */ +extern persistent tmr_time_t _tmr_ticks; + +/* Initialize the tmr subsystem */ +void tmr_init(); + +/* Return non-zero if the timer is on */ +/* FIXME: this may not be atomic WRT ISR */ +#define tmr_on(t) (bit_get(_tmr_on, (t))) + +/* Return non-zero if the timer is periodic */ +/* FIXME: this may not be atomic WRT ISR */ +#define tmr_periodic(t) (bit_get(_tmr_periodic, (t))) + +/* Start a timer, expecting it to fire in elapsed ticks */ +void tmr_start(tmr_bitno_t t, tmr_time_t elapsed); + +/* Start a timer, expecting it to fire in elapsed ticks from t0 */ +void tmr_startAt(tmr_bitno_t t, tmr_time_t t0, tmr_time_t elapsed); + +/* Start a periodic timer, expecting it to fire every elapsed ticks */ +void tmr_startPeriodic(tmr_bitno_t t, tmr_time_t elapsed); + +/* Start a periodic timer, expecting it to fire every elapsed ticks */ +void tmr_startPeriodicAt(tmr_bitno_t t, tmr_time_t t0, tmr_time_t elapsed); + +/* Stop a timer */ +#define tmr_stop(t) \ + do { \ + ndi(); \ + bit_clr(_tmr_on, (t)); \ + nei(); \ + } while(0) + +/* Return 1 if the timer has fired, resetting the fired bit */ +bit tmr_fired(tmr_bitno_t t); + +/* Return the current number of timer ticks, for use outside ISR */ +#define tmr_time(ptr_time) \ + do { \ + ndi(); \ + *(ptr_time) = _tmr_ticks; \ + nei(); \ + } while (0) + +/* Used in the ISR to update timer */ +void tmr_isr(); + +/* Wait for c clocks, 0 <= c < 128. */ +#define tmr_cwait(c) \ + do { \ + unsigned t0 = TMR0; \ + while ((unsigned)(TMR0 - t0) <= c); /* cast prevents integral promotion */ \ + } while (0) + +/* Wait for a number of us. This is pretty accurate. */ +void tmr_uwait(unsigned us); + +/* Wait for a number of ms. Each 32 ms actually waits about 32,768 us */ +void tmr_mwait(unsigned ms); + +#endif