]> git.tdb.fi Git - model-railway-devices.git/blobdiff - firmware/timer.c
Support multiple timers (currently 0 and 1)
[model-railway-devices.git] / firmware / timer.c
index 043dff8a4037389afbc0bb894548753fbb0881f1..13db1e8672708289631ec5957146101d1c09049e 100644 (file)
+/* $Id$
+
+This file is part of the MSP Märklin suite
+Copyright © 2010  Mikkosoft Productions, Mikko Rasa
+Distributed under the GPL
+*/
+
 #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)
+static void timer_start(uint8_t num, uint32_t period)
 {
-       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)
+       if(num==0)
        {
-               cs = BIT(CS12);
-               period /= 256;
+               if(period<0x100)
+               {
+                       cs = BIT(CS00);
+               }
+               else if(period<0x800)
+               {
+                       cs = BIT(CS01);
+                       period /= 8;
+               }
+               else if(period<0x4000)
+               {
+                       cs = BIT(CS01) | BIT(CS00);
+                       period /= 64;
+               }
+               else if(period<0x10000)
+               {
+                       cs = BIT(CS02);
+                       period /= 256;
+               }
+               else
+               {
+                       cs = BIT(CS02) | BIT(CS00);
+                       period /= 1024;
+                       if(period>0xFF)
+                               period = 0xFF;
+               }
+               TCCR0A = BIT(WGM01);
+               TCCR0B = cs;
+               OCR0A = period;
+               TIMSK0 = BIT(OCIE0A);
        }
-       else
+       if(num==1)
        {
-               cs = BIT(CS12) | BIT(CS10);
-               period /= 1024;
-               if(period>0xFFFF)
-                       period = 0xFFFF;
+               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;
+               TIMSK1 = BIT(OCIE1A);
        }
-       TCCR1A = 0;
-       TCCR1B = BIT(WGM12) | cs;
-       OCR1AH = period>>8;
-       OCR1AL = period;
 }
 
-void timer_set_callback(TimerCallback *cb)
+void timer_start_hz(uint8_t num, uint32_t freq_p, uint8_t freq_q)
+{
+       timer_start(num, F_CPU*freq_q/freq_p);
+}
+
+void timer_start_us(uint8_t num, uint32_t us)
 {
-       timer_callback = cb;
-       TIMSK1 |= BIT(OCIE1A);
+       timer_start(num, F_CPU/1000000*us);
 }
 
-ISR(TIMER1_COMPA_vect)
+void timer_stop(uint8_t num)
 {
-       timer_callback();
+       if(num==0)
+       {
+               TCCR0B = 0;
+               TIMSK0 = 0;
+       }
+       else if(num==1)
+       {
+               TCCR1B = 0;
+               TIMSK1 = 0;
+       }
 }