]> git.tdb.fi Git - model-railway-devices.git/blob - firmware/timer.c
043dff8a4037389afbc0bb894548753fbb0881f1
[model-railway-devices.git] / firmware / timer.c
1 #include <avr/io.h>
2 #include <avr/interrupt.h>
3 #include "timer.h"
4
5 #define BIT(n) (1<<(n))
6
7 static TimerCallback *timer_callback;
8
9 void timer_init(uint16_t freq_p, uint8_t freq_q)
10 {
11         uint32_t period = F_CPU*freq_q/freq_p;
12         uint8_t cs;
13
14         if(period<0x10000)
15         {
16                 cs = BIT(CS10);
17         }
18         else if(period<0x80000)
19         {
20                 cs = BIT(CS11);
21                 period /= 8;
22         }
23         else if(period<0x400000)
24         {
25                 cs = BIT(CS11) | BIT(CS10);
26                 period /= 64;
27         }
28         else if(period<0x1000000)
29         {
30                 cs = BIT(CS12);
31                 period /= 256;
32         }
33         else
34         {
35                 cs = BIT(CS12) | BIT(CS10);
36                 period /= 1024;
37                 if(period>0xFFFF)
38                         period = 0xFFFF;
39         }
40         TCCR1A = 0;
41         TCCR1B = BIT(WGM12) | cs;
42         OCR1AH = period>>8;
43         OCR1AL = period;
44 }
45
46 void timer_set_callback(TimerCallback *cb)
47 {
48         timer_callback = cb;
49         TIMSK1 |= BIT(OCIE1A);
50 }
51
52 ISR(TIMER1_COMPA_vect)
53 {
54         timer_callback();
55 }