]> git.tdb.fi Git - model-railway-devices.git/blobdiff - firmware/timer.c
Add some utility functions for interfacing with hardware
[model-railway-devices.git] / firmware / timer.c
diff --git a/firmware/timer.c b/firmware/timer.c
new file mode 100644 (file)
index 0000000..043dff8
--- /dev/null
@@ -0,0 +1,55 @@
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "timer.h"
+
+#define BIT(n) (1<<(n))
+
+static TimerCallback *timer_callback;
+
+void timer_init(uint16_t freq_p, uint8_t freq_q)
+{
+       uint32_t period = F_CPU*freq_q/freq_p;
+       uint8_t cs;
+
+       if(period<0x10000)
+       {
+               cs = BIT(CS10);
+       }
+       else if(period<0x80000)
+       {
+               cs = BIT(CS11);
+               period /= 8;
+       }
+       else if(period<0x400000)
+       {
+               cs = BIT(CS11) | BIT(CS10);
+               period /= 64;
+       }
+       else if(period<0x1000000)
+       {
+               cs = BIT(CS12);
+               period /= 256;
+       }
+       else
+       {
+               cs = BIT(CS12) | BIT(CS10);
+               period /= 1024;
+               if(period>0xFFFF)
+                       period = 0xFFFF;
+       }
+       TCCR1A = 0;
+       TCCR1B = BIT(WGM12) | cs;
+       OCR1AH = period>>8;
+       OCR1AL = period;
+}
+
+void timer_set_callback(TimerCallback *cb)
+{
+       timer_callback = cb;
+       TIMSK1 |= BIT(OCIE1A);
+}
+
+ISR(TIMER1_COMPA_vect)
+{
+       timer_callback();
+}