]> oss.titaniummirror.com Git - rgblamp.git/commitdiff
Add tmr32 module
authorR. Steve McKown <rsmckown@gmail.com>
Mon, 12 Dec 2011 02:46:33 +0000 (19:46 -0700)
committerR. Steve McKown <rsmckown@gmail.com>
Mon, 12 Dec 2011 02:46:33 +0000 (19:46 -0700)
* tmr32 module uses Timer 1 + crystal
* Use tmr32 to time auto on and off events
* Put the CPU in sleep when off, either by switch or timer.
  Use the tmr32 module or a button ISR to wake back up.

isr.c
main.c
task_defs.h
tmr32.c [new file with mode: 0644]
tmr32.h [new file with mode: 0644]

diff --git a/isr.c b/isr.c
index 8db018f3672723d06a24b8e2799d8cb0cdba7fc1..957fc49ccf107c745c05eef37c7c7d73385d4855 100644 (file)
--- a/isr.c
+++ b/isr.c
@@ -7,6 +7,7 @@
 
 #include <htc.h>
 #include "tmr.h"
+#include "tmr32.h"
 #include "btn.h"
 #include "task.h"
 
@@ -32,9 +33,8 @@ void interrupt isr()
 {
   tmr_isr();
   btn_isr();
+  tmr32_isr();
 
-  if (tmr_fired(TMR_AUTO_OFFON))
-    task_post(TASK_AUTO_OFFON);
   if (tmr_fired(TMR_FADE))
     task_post(TASK_FADE);
   if (tmr_fired(TMR_INCOLOR))
diff --git a/main.c b/main.c
index 6d20042721cb8aebf0956e3c62fd80d47f0b1b58..0726aafb2942763587a24b3e4a3c8e0f2d907156 100644 (file)
--- a/main.c
+++ b/main.c
 #include "btn.h"
 #include "rgb.h"
 #include "tmr.h"
+#include "tmr32.h"
 #include "task.h"
 #include "adc_random.h"
 
-#define AUTO_OFF_COUNT          549316UL  /*  5 hrs in 32.768 ms units */
-#define AUTO_ON_COUNT           2087402UL /* 19 hrs in 32.768 ms units */
+#if 1
+#define AUTO_OFF_COUNT          1800U  /*  1 hr  in 2 sec units */
+#define AUTO_ON_COUNT           19800U /* 11 hrs in 2 sec units */
+#else
+#define AUTO_OFF_COUNT          9000U  /*  5 hrs in 2 sec units */
+#define AUTO_ON_COUNT           34200U /* 19 hrs in 2 sec units */
+#endif
 #define leds_set(r,g,b,w)       rgb_set((r).value >> 7, (g).value >> 7, \
                                     (b).value >> 7, 0)
 #define dbgpin_init()           do { \
@@ -136,6 +142,7 @@ void turnOff()
   tmr_stop(TMR_FADE);
   rgb_off();
   dbgpin_low();
+  SLEEP();
   on = 0;
 }
 
@@ -153,19 +160,19 @@ void pb_task()
 
 void rs_task()
 {
+  btn_rsen();
   switch (btn_rs()) {
     case BTN_RS_OFF:
-      tmr_stop(TMR_AUTO_OFFON);
+      tmr32_set(0);
       turnOff();
       break;
     case BTN_RS_RIGHT:
-      tmr_start(TMR_AUTO_OFFON, AUTO_OFF_COUNT);
+      tmr32_set(AUTO_OFF_COUNT);
       /* fall through */
     case BTN_RS_LEFT:
       turnOn();
       break;
   }
-  btn_rsen();
 }
 
 void fade_task()
@@ -194,11 +201,11 @@ void auto_offon_task()
   if (on) {
     turnOff();
     if (btn_rs() == BTN_RS_RIGHT)
-      tmr_start(TMR_AUTO_OFFON, AUTO_ON_COUNT);
+      tmr32_set(AUTO_ON_COUNT);
   } else /* off */ {
     turnOn();
     if (btn_rs() == BTN_RS_RIGHT)
-      tmr_start(TMR_AUTO_OFFON, AUTO_OFF_COUNT);
+      tmr32_set(AUTO_OFF_COUNT);
   }
 }
 
@@ -227,7 +234,7 @@ void user_tasks(unsigned char block)
       case TASK_INCOLOR:        /* in-color timer has fired */
         start_fade();
         break;
-      case TASK_AUTO_OFFON:     /* auto on/off timer has fired */
+      case TASK_TMR32:          /* auto on/off event */
         auto_offon_task();
         break;
     }
@@ -242,6 +249,7 @@ int main(void)
   btn_init();
   rgb_init();
   tmr_init();
+  tmr32_init();
   task_init();
   dbgpin_init();
 
index 2a43168c320c99f2f34daf4e2656ecf8a7dd2262..dac07dddb2228fb33851641c10c59efda7761125 100644 (file)
@@ -21,7 +21,7 @@ enum {
   TASK_BTN_RS,
   TASK_FADE,
   TASK_INCOLOR,
-  TASK_AUTO_OFFON,
+  TASK_TMR32,
 
   TASK_COUNT
 };
diff --git a/tmr32.c b/tmr32.c
new file mode 100644 (file)
index 0000000..a5dc5d5
--- /dev/null
+++ b/tmr32.c
@@ -0,0 +1,43 @@
+/*
+ * File:   tmr32.c
+ *
+ * A very simple module that triggers an ISR once every 2 seconds.  tmr32 relies
+ * on Timer 1 and a watch crystal.
+ */
+
+
+#include <htc.h>
+#include "tmr32.h"
+#include "isr.h"
+#include "task.h"
+
+static unsigned _tmr32_count;
+
+void tmr32_init()
+{
+  /* Configure Timer 1 */
+  T1CON = 0b10001001;
+  while (!T1OSCR);
+
+  /* Setup timer to run during sleep, and wake CPU on overflow */
+  nT1SYNC = 1;
+  TMR1IE = 1;
+  PEIE = 1;
+  GIE = 1;
+}
+
+void tmr32_set(unsigned twosecs)
+{
+  ndi();
+  _tmr32_count = twosecs;
+  nei();
+}
+
+void tmr32_isr()
+{
+  if (TMR1IF) {
+    TMR1IF = 0;
+    if (_tmr32_count && --_tmr32_count == 0)
+      task_post(TASK_TMR32);
+  }
+}
diff --git a/tmr32.h b/tmr32.h
new file mode 100644 (file)
index 0000000..f5691b8
--- /dev/null
+++ b/tmr32.h
@@ -0,0 +1,35 @@
+/*
+ * File:   tmr32.h
+ *
+ * A very simple module that triggers an ISR once every 2 seconds.  tmr32 relies
+ * on Timer 1 and a watch crystal.
+ *
+ * Later tmr and tmr32 modules can merge into a generic solution.  To that end,
+ * one should note that Timer 1 must be in sync to use a compare moudule when
+ * the CPU is running, and it must not be synced to run while the CPU is in
+ * sleep.  When in sleep, the comparator can't work, but Timer 1 overflow events
+ * will trigger and wake the CPU.
+ */
+
+#ifndef _TMR32_H
+#define _TMR32_H
+
+/* Initialize the tmr subsystem */
+void tmr32_init();
+
+/* Set the number of seconds, which is decremented by 2 every 2 seconds.  When
+ * zero is reached, TASK_TMR32 is posted.
+ */
+void tmr32_set(unsigned twosecs);
+
+/* The tmr32 isr */
+void tmr32_isr();
+
+/* Wait for c clocks, 0 <= c < 32768. */
+#define tmr32_cwait(c) \
+  do { \
+    unsigned t0 = TMR1; \
+    while (TMR0 - t0 <= c); \
+  } while (0)
+
+#endif