aboutsummaryrefslogtreecommitdiff
path: root/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'timer.c')
-rw-r--r--timer.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/timer.c b/timer.c
new file mode 100644
index 0000000..7d82b0f
--- /dev/null
+++ b/timer.c
@@ -0,0 +1,47 @@
+#include <avr/io.h>
+#include <stdint.h>
+
+#include "timer.h"
+
+/* On AVR, two 16-bit timers are used:
+ * timer1 for emitting a low frequency IRQ to update the display
+ * timer3 freerunning quickly for timestamping purposes
+ *
+ * XXX note: most of the functions in this module must be called with
+ * interrupts already disabled in order to be safe
+ */
+
+/* XXX hardcoded based upon TCCR3B selecting /256 prescaled clock */
+#define TIMER_HZ (F_CPU / 256)
+
+static void timer_init(void)
+{
+ /* timer1 has /1024 prescaler, 1 Hz comparator val, enable IRQ */
+ TCCR1B |= (1 << CS10) | (1 << CS12) | (1 << WGM12);
+ TIMSK1 |= (1 << OCIE1A);
+ OCR1A = F_CPU / 1024;
+
+ /* timer3 has /256 prescaler, no comparartor (free-running with overflow)
+ * and no IRQ enabled. /256 chosen so that the counter doesn't overflow
+ * within a 1 second window */
+
+ TCCR3B |= (1 << CS32);
+}
+
+static float timer_stamps_to_seconds(uint16_t start, uint16_t end)
+{
+ return (float)(end - start) / TIMER_HZ;
+}
+
+static uint16_t timer_get_value(void)
+{
+ return TCNT3;
+}
+
+/**/
+
+void get_system_timer(struct timer *timer)
+{
+ timer->init = timer_init;
+ timer->get_time = timer_get_value;
+}