]> oss.titaniummirror.com Git - rgblamp.git/commitdiff
Clock loop start to loop start using Timer 0
authorR. Steve McKown <rsmckown@gmail.com>
Wed, 7 Dec 2011 00:16:33 +0000 (17:16 -0700)
committerR. Steve McKown <rsmckown@gmail.com>
Wed, 7 Dec 2011 00:16:33 +0000 (17:16 -0700)
Timer 0 is configured to overflow every 32 msec, which is the period we
wait when driving the main control loop.  Once a loop iteration has
completed its processing, it calls timer_owait() to wait on the next
overflow.

main.c
timer.c [new file with mode: 0644]
timer.h [new file with mode: 0644]

diff --git a/main.c b/main.c
index 4f36d146b1133f58aa7e32e07ddd4c05f9fc5831..b998176d06e98b1a497434ee09c715b72f419b3b 100644 (file)
--- a/main.c
+++ b/main.c
 #include <htc.h>
 #include <stdlib.h>
 #include "picinit.h"
+#include "unused.h"
 #include "buttons.h"
 #include "rgb.h"
-#include "unused.h"
+#include "timer.h"
 
-#define STEP_SIZE               32 /* ms */
 #define reset_steps()           do { incolor_steps = 1; fade_steps = 0; } \
                                   while (0)
 #define rand_u8()               (rand() & 0xff)
@@ -90,6 +90,7 @@ int main(void)
     unused_init();
     buttons_init();
     rgb_init();
+    timer_init();
     dbgpin_init();
 
     reset_steps();
@@ -153,7 +154,7 @@ int main(void)
               wht.remainder = neww - (wht.value + wht.increment * fade_steps);
             }
             dbgpin_low();
-            __delay_ms(STEP_SIZE); /* step should be start to start... */
+            timer_owait(); /* wait 32 ms since last return from last call() */
             dbgpin_high();
         } else {
             rgb_off();
diff --git a/timer.c b/timer.c
new file mode 100644 (file)
index 0000000..a76e2c2
--- /dev/null
+++ b/timer.c
@@ -0,0 +1,40 @@
+/*
+ * File:   timer.c
+ *
+ * Timer 0 + Timer 1 for timekeeping
+ */
+
+
+#include <htc.h>
+
+void timer_uwait(unsigned us)
+{
+  unsigned t0 = TMR0;
+
+  TMR0IF = 0;
+  while (us >= 32768) {
+    timer_owait();
+    us -= 32768;
+  }
+  while (us >= 16384) {
+    timer_cwait(128);
+    us -= 16384;
+  }
+  timer_cwait(us / 128);
+}
+
+void timer_mwait(unsigned ms)
+{
+  unsigned t0 = TMR0;
+
+  TMR0IF = 0;
+  while (ms >= 32) {
+    timer_owait();
+    ms -= 32;
+  }
+  while (ms >= 16) {
+    timer_cwait(128);
+    ms -= 16;
+  }
+  timer_cwait(ms * 8);
+}
diff --git a/timer.h b/timer.h
new file mode 100644 (file)
index 0000000..c28ed0b
--- /dev/null
+++ b/timer.h
@@ -0,0 +1,53 @@
+/*
+ * File:   timer.h
+ *
+ * Timer 0 + Timer 1 for timekeeping
+ */
+
+
+#ifndef _TIMER_H
+#define _TIMER_H
+
+/* Timer 0 with 1:256 prescale given Fosc (_XTAL_FREQ).
+ * Timer 0 is clocked by Fosc/4.
+ *
+ * Fosc       Overflow, ms
+ * -------    ----------
+ *  32 MHz         8.192
+ *  16 MHz        16.384
+ *   8 MHz        32.768
+ *   4 MHz        65.536
+ *   2 MHz       131.072
+ *   1 MHz       262.144
+ * 500 KHz       524.288
+ * 250 KHz     1,048.576
+ * 125 KHz     2,097.152
+ */
+
+/* Configure Timer0 to overflow every 32 msec.  Adjust with
+ * Fosc as set in picinit.[ch].  At 2 MHz, prescale is 1:64.
+ */
+#define timer_init() \
+  do { \
+    /* TMR0CS = 0, PSA = 0, PS = 0b101 */ \
+    OPTION_REG = (OPTION_REG & 0b11010000) + 0b0101; \
+  } while (0)
+
+/* Wait for the timer to overflow.  This is 32 msec from the last overflow. */
+#define timer_owait() \
+  { \
+    while (!TMR0IF); \
+    TMR0IF = 0; \
+  } while (0)
+
+/* Wait for c clocks, 0 <= c < 128. */
+#define timer_cwait(c) \
+  { \
+    unsigned t0 = TMR0; \
+    while ((TMR0 - t0) <= c); \
+  } while (0)
+
+void timer_uwait(unsigned us);
+void timer_mwait(unsigned ms);
+
+#endif