--- /dev/null
+/*
+ * 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