]> git.tdb.fi Git - model-railway-devices.git/blob - firmware/timer.c
13db1e8672708289631ec5957146101d1c09049e
[model-railway-devices.git] / firmware / timer.c
1 /* $Id$
2
3 This file is part of the MSP Märklin suite
4 Copyright © 2010  Mikkosoft Productions, Mikko Rasa
5 Distributed under the GPL
6 */
7
8 #include <avr/io.h>
9 #include "timer.h"
10
11 #define BIT(n) (1<<(n))
12
13 static void timer_start(uint8_t num, uint32_t period)
14 {
15         uint8_t cs;
16
17         if(num==0)
18         {
19                 if(period<0x100)
20                 {
21                         cs = BIT(CS00);
22                 }
23                 else if(period<0x800)
24                 {
25                         cs = BIT(CS01);
26                         period /= 8;
27                 }
28                 else if(period<0x4000)
29                 {
30                         cs = BIT(CS01) | BIT(CS00);
31                         period /= 64;
32                 }
33                 else if(period<0x10000)
34                 {
35                         cs = BIT(CS02);
36                         period /= 256;
37                 }
38                 else
39                 {
40                         cs = BIT(CS02) | BIT(CS00);
41                         period /= 1024;
42                         if(period>0xFF)
43                                 period = 0xFF;
44                 }
45                 TCCR0A = BIT(WGM01);
46                 TCCR0B = cs;
47                 OCR0A = period;
48                 TIMSK0 = BIT(OCIE0A);
49         }
50         if(num==1)
51         {
52                 if(period<0x10000)
53                 {
54                         cs = BIT(CS10);
55                 }
56                 else if(period<0x80000)
57                 {
58                         cs = BIT(CS11);
59                         period /= 8;
60                 }
61                 else if(period<0x400000)
62                 {
63                         cs = BIT(CS11) | BIT(CS10);
64                         period /= 64;
65                 }
66                 else if(period<0x1000000)
67                 {
68                         cs = BIT(CS12);
69                         period /= 256;
70                 }
71                 else
72                 {
73                         cs = BIT(CS12) | BIT(CS10);
74                         period /= 1024;
75                         if(period>0xFFFF)
76                                 period = 0xFFFF;
77                 }
78                 TCCR1A = 0;
79                 TCCR1B = BIT(WGM12) | cs;
80                 OCR1AH = period>>8;
81                 OCR1AL = period;
82                 TIMSK1 = BIT(OCIE1A);
83         }
84 }
85
86 void timer_start_hz(uint8_t num, uint32_t freq_p, uint8_t freq_q)
87 {
88         timer_start(num, F_CPU*freq_q/freq_p);
89 }
90
91 void timer_start_us(uint8_t num, uint32_t us)
92 {
93         timer_start(num, F_CPU/1000000*us);
94 }
95
96 void timer_stop(uint8_t num)
97 {
98         if(num==0)
99         {
100                 TCCR0B = 0;
101                 TIMSK0 = 0;
102         }
103         else if(num==1)
104         {
105                 TCCR1B = 0;
106                 TIMSK1 = 0;
107         }
108 }