-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimers.c
104 lines (66 loc) · 1.89 KB
/
timers.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdint.h>
#include "timers.h"
void timer0_init (void)
{
// place timer 0 in CTC mode
TCCR0A |= (2 << WGM00);
// set timer 0 clock source to core clock divided by 1,024
TCCR0B |= (5 << CS00);
// enable timer 0 compare match A interrupt
TIMSK |= (1 << OCIE0A);
// set compare match A frequency to 100 Hz based on 16-MHz core clock
OCR0A = 0x9C;
}
void timer1_init (void)
{
// set timer 1 clock source to core clock divided by 8
TCCR1B |= (2 << CS10);
// enable timer 1 input capture interrupt
TIMSK |= (1 << ICIE1);
// reset edge type
timer1_edge_type = TIMER1_EDGE_NONE;
}
ISR (TIMER0_COMPA_vect)
{
static uint8_t timer0_tick;
// set heartbeat flag based on divided-down tick rate
if (timer0_tick < TIMER0_TICK_RATE)
{
timer0_tick++;
} else {
timer0_tick = 0;
timer0_tick_flag = 1;
} // if (tick)
}
ISR (TIMER1_CAPT_vect)
{
// reset counter
TCNT1 = 0x0000;
// record edge type based on edge-detect polarity
if (TCCR1B & (1 << ICES1))
{
// mark positive edge as invalid if timer previously overflowed
if (TIFR & (1 << TOV1))
{
TIFR |= (1 << TOV1);
timer1_edge_type = TIMER1_EDGE_POS_TRASH;
} else {
timer1_edge_type = TIMER1_EDGE_POS;
} // if (overflow)
} else {
// mark negative edge as invalid if timer previously overflowed
if (TIFR & (1 << TOV1))
{
TIFR |= (1 << TOV1);
timer1_edge_type = TIMER1_EDGE_NEG_TRASH;
} else {
timer1_edge_type = TIMER1_EDGE_NEG;
} // if (overflow)
} // if (polarity)
// invert edge-detect polarity
TCCR1B ^= (1 << ICES1);
// clear interrupt flag following polarity change (as per data sheet)
TIFR |= (1 << ICF1);
}