aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common/avr/timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core/common/avr/timer.c')
-rw-r--r--tmk_core/common/avr/timer.c69
1 files changed, 40 insertions, 29 deletions
diff --git a/tmk_core/common/avr/timer.c b/tmk_core/common/avr/timer.c
index 292b41c3a..369015200 100644
--- a/tmk_core/common/avr/timer.c
+++ b/tmk_core/common/avr/timer.c
@@ -17,6 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18#include <avr/io.h> 18#include <avr/io.h>
19#include <avr/interrupt.h> 19#include <avr/interrupt.h>
20#include <util/atomic.h>
20#include <stdint.h> 21#include <stdint.h>
21#include "timer_avr.h" 22#include "timer_avr.h"
22#include "timer.h" 23#include "timer.h"
@@ -24,38 +25,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
24 25
25// counter resolution 1ms 26// counter resolution 1ms
26// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }} 27// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
27volatile uint32_t timer_count = 0; 28volatile uint32_t timer_count;
28 29
29void timer_init(void) 30void timer_init(void)
30{ 31{
31 // Timer0 CTC mode
32 TCCR0A = 0x02;
33
34#if TIMER_PRESCALER == 1 32#if TIMER_PRESCALER == 1
35 TCCR0B = 0x01; 33 uint8_t prescaler = 0x01;
36#elif TIMER_PRESCALER == 8 34#elif TIMER_PRESCALER == 8
37 TCCR0B = 0x02; 35 uint8_t prescaler = 0x02;
38#elif TIMER_PRESCALER == 64 36#elif TIMER_PRESCALER == 64
39 TCCR0B = 0x03; 37 uint8_t prescaler = 0x03;
40#elif TIMER_PRESCALER == 256 38#elif TIMER_PRESCALER == 256
41 TCCR0B = 0x04; 39 uint8_t prescaler = 0x04;
42#elif TIMER_PRESCALER == 1024 40#elif TIMER_PRESCALER == 1024
43 TCCR0B = 0x05; 41 uint8_t prescaler = 0x05;
44#else 42#else
45# error "Timer prescaler value is NOT vaild." 43# error "Timer prescaler value is NOT vaild."
46#endif 44#endif
47 45
46#ifndef __AVR_ATmega32A__
47 // Timer0 CTC mode
48 TCCR0A = 0x02;
49
50 TCCR0B = prescaler;
51
48 OCR0A = TIMER_RAW_TOP; 52 OCR0A = TIMER_RAW_TOP;
49 TIMSK0 = (1<<OCIE0A); 53 TIMSK0 = (1<<OCIE0A);
54#else
55 // Timer0 CTC mode
56 TCCR0 = (1 << WGM01) | prescaler;
57
58 OCR0 = TIMER_RAW_TOP;
59 TIMSK = (1 << OCIE0);
60#endif
50} 61}
51 62
52inline 63inline
53void timer_clear(void) 64void timer_clear(void)
54{ 65{
55 uint8_t sreg = SREG; 66 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
56 cli();
57 timer_count = 0; 67 timer_count = 0;
58 SREG = sreg; 68 }
59} 69}
60 70
61inline 71inline
@@ -63,10 +73,9 @@ uint16_t timer_read(void)
63{ 73{
64 uint32_t t; 74 uint32_t t;
65 75
66 uint8_t sreg = SREG; 76 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
67 cli(); 77 t = timer_count;
68 t = timer_count; 78 }
69 SREG = sreg;
70 79
71 return (t & 0xFFFF); 80 return (t & 0xFFFF);
72} 81}
@@ -76,10 +85,9 @@ uint32_t timer_read32(void)
76{ 85{
77 uint32_t t; 86 uint32_t t;
78 87
79 uint8_t sreg = SREG; 88 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
80 cli(); 89 t = timer_count;
81 t = timer_count; 90 }
82 SREG = sreg;
83 91
84 return t; 92 return t;
85} 93}
@@ -89,10 +97,9 @@ uint16_t timer_elapsed(uint16_t last)
89{ 97{
90 uint32_t t; 98 uint32_t t;
91 99
92 uint8_t sreg = SREG; 100 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
93 cli(); 101 t = timer_count;
94 t = timer_count; 102 }
95 SREG = sreg;
96 103
97 return TIMER_DIFF_16((t & 0xFFFF), last); 104 return TIMER_DIFF_16((t & 0xFFFF), last);
98} 105}
@@ -102,16 +109,20 @@ uint32_t timer_elapsed32(uint32_t last)
102{ 109{
103 uint32_t t; 110 uint32_t t;
104 111
105 uint8_t sreg = SREG; 112 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
106 cli(); 113 t = timer_count;
107 t = timer_count; 114 }
108 SREG = sreg;
109 115
110 return TIMER_DIFF_32(t, last); 116 return TIMER_DIFF_32(t, last);
111} 117}
112 118
113// excecuted once per 1ms.(excess for just timer count?) 119// excecuted once per 1ms.(excess for just timer count?)
114ISR(TIMER0_COMPA_vect) 120#ifndef __AVR_ATmega32A__
121#define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect
122#else
123#define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect
124#endif
125ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK)
115{ 126{
116 timer_count++; 127 timer_count++;
117} 128}