]> oss.titaniummirror.com Git - rgblamp.git/blobdiff - tmr.h
Incorporate new tmr and isr code
[rgblamp.git] / tmr.h
diff --git a/tmr.h b/tmr.h
new file mode 100644 (file)
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