]> git.tdb.fi Git - model-railway-devices.git/blob - common/timer.c
Provide peak current since last read
[model-railway-devices.git] / common / timer.c
1 #include <avr/io.h>
2 #include "timer.h"
3
4 #define BIT(n) (1<<(n))
5
6 static void timer_start(uint8_t num, uint32_t period)
7 {
8         uint8_t cs;
9
10         if(num==0)
11         {
12                 if(period<0x100)
13                         cs = BIT(CS00);
14                 else if(period<0x800)
15                 {
16                         cs = BIT(CS01);
17                         period /= 8;
18                 }
19                 else if(period<0x4000)
20                 {
21                         cs = BIT(CS01) | BIT(CS00);
22                         period /= 64;
23                 }
24                 else if(period<0x10000)
25                 {
26                         cs = BIT(CS02);
27                         period /= 256;
28                 }
29                 else
30                 {
31                         cs = BIT(CS02) | BIT(CS00);
32                         period /= 1024;
33                         if(period>0xFF)
34                                 period = 0xFF;
35                 }
36                 TCCR0A = BIT(WGM01);
37                 TCCR0B = cs;
38                 OCR0A = period;
39                 TIMSK0 = BIT(OCIE0A);
40         }
41         else if(num==1)
42         {
43                 if(period<0x10000)
44                         cs = BIT(CS10);
45                 else if(period<0x80000)
46                 {
47                         cs = BIT(CS11);
48                         period /= 8;
49                 }
50                 else if(period<0x400000)
51                 {
52                         cs = BIT(CS11) | BIT(CS10);
53                         period /= 64;
54                 }
55                 else if(period<0x1000000)
56                 {
57                         cs = BIT(CS12);
58                         period /= 256;
59                 }
60                 else
61                 {
62                         cs = BIT(CS12) | BIT(CS10);
63                         period /= 1024;
64                         if(period>0xFFFF)
65                                 period = 0xFFFF;
66                 }
67                 TCCR1A = 0;
68                 TCCR1B = BIT(WGM12) | cs;
69                 OCR1AH = period>>8;
70                 OCR1AL = period;
71                 TIMSK1 = BIT(OCIE1A);
72         }
73         else if(num==2)
74         {
75                 if(period<0x100)
76                         cs = BIT(CS20);
77                 else if(period<0x800)
78                 {
79                         cs = BIT(CS21);
80                         period /= 8;
81                 }
82                 else if(period<0x2000)
83                 {
84                         cs = BIT(CS21) | BIT(CS20);
85                         period /= 32;
86                 }
87                 else if(period<0x4000)
88                 {
89                         cs = BIT(CS22);
90                         period /= 64;
91                 }
92                 else if(period<0x8000)
93                 {
94                         cs = BIT(CS22) | BIT(CS20);
95                         period /= 128;
96                 }
97                 else if(period<0x10000)
98                 {
99                         cs = BIT(CS22) | BIT(CS21);
100                         period /= 256;
101                 }
102                 else
103                 {
104                         cs = BIT(CS22) | BIT(CS21) | BIT(CS20);
105                         period /= 1024;
106                         if(period>0xFF)
107                                 period = 0xFF;
108                 }
109                 TCCR2A = BIT(WGM21);
110                 TCCR2B = cs;
111                 OCR2A = period;
112                 TIMSK2 = BIT(OCIE2A);
113         }
114 }
115
116 void timer_start_hz(uint8_t num, uint32_t freq_p, uint8_t freq_q)
117 {
118         timer_start(num, F_CPU*freq_q/freq_p);
119 }
120
121 void timer_start_us(uint8_t num, uint32_t us)
122 {
123         timer_start(num, F_CPU/1000000*us);
124 }
125
126 void timer_stop(uint8_t num)
127 {
128         if(num==0)
129         {
130                 TCCR0B = 0;
131                 TIMSK0 = 0;
132         }
133         else if(num==1)
134         {
135                 TCCR1B = 0;
136                 TIMSK1 = 0;
137         }
138         else if(num==2)
139         {
140                 TCCR2B = 0;
141                 TIMSK2 = 0;
142         }
143 }