diff options
author | 2017-02-21 20:31:16 -0600 | |
---|---|---|
committer | 2017-02-21 20:31:16 -0600 | |
commit | e51001efcc3ff8b64f8264e8bd4c2dbea15f3364 (patch) | |
tree | bdf5a0a4b44d5e63ba1376b70d94f64c77f3c90c /tmk_core/common/avr/timer.c | |
parent | c56693f858cb3409e4a68a8e65a1370c022a51ed (diff) | |
parent | 7ff41df32c29bca4e3a6efc3047b8fa93bb99b92 (diff) | |
download | qmk_firmware-e51001efcc3ff8b64f8264e8bd4c2dbea15f3364.tar.gz |
Merge remote-tracking branch 'qmk/master'
Diffstat (limited to 'tmk_core/common/avr/timer.c')
-rw-r--r-- | tmk_core/common/avr/timer.c | 69 |
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/>. #include <avr/io.h> #include <avr/interrupt.h> +#include <util/atomic.h> #include <stdint.h> #include "timer_avr.h" #include "timer.h" @@ -24,38 +25,47 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. // counter resolution 1ms // NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }} -volatile uint32_t timer_count = 0; +volatile uint32_t timer_count; void timer_init(void) { - // Timer0 CTC mode - TCCR0A = 0x02; - #if TIMER_PRESCALER == 1 - TCCR0B = 0x01; + uint8_t prescaler = 0x01; #elif TIMER_PRESCALER == 8 - TCCR0B = 0x02; + uint8_t prescaler = 0x02; #elif TIMER_PRESCALER == 64 - TCCR0B = 0x03; + uint8_t prescaler = 0x03; #elif TIMER_PRESCALER == 256 - TCCR0B = 0x04; + uint8_t prescaler = 0x04; #elif TIMER_PRESCALER == 1024 - TCCR0B = 0x05; + uint8_t prescaler = 0x05; #else # error "Timer prescaler value is NOT vaild." #endif +#ifndef __AVR_ATmega32A__ + // Timer0 CTC mode + TCCR0A = 0x02; + + TCCR0B = prescaler; + OCR0A = TIMER_RAW_TOP; TIMSK0 = (1<<OCIE0A); +#else + // Timer0 CTC mode + TCCR0 = (1 << WGM01) | prescaler; + + OCR0 = TIMER_RAW_TOP; + TIMSK = (1 << OCIE0); +#endif } inline void timer_clear(void) { - uint8_t sreg = SREG; - cli(); + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { timer_count = 0; - SREG = sreg; + } } inline @@ -63,10 +73,9 @@ uint16_t timer_read(void) { uint32_t t; - uint8_t sreg = SREG; - cli(); - t = timer_count; - SREG = sreg; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return (t & 0xFFFF); } @@ -76,10 +85,9 @@ uint32_t timer_read32(void) { uint32_t t; - uint8_t sreg = SREG; - cli(); - t = timer_count; - SREG = sreg; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return t; } @@ -89,10 +97,9 @@ uint16_t timer_elapsed(uint16_t last) { uint32_t t; - uint8_t sreg = SREG; - cli(); - t = timer_count; - SREG = sreg; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return TIMER_DIFF_16((t & 0xFFFF), last); } @@ -102,16 +109,20 @@ uint32_t timer_elapsed32(uint32_t last) { uint32_t t; - uint8_t sreg = SREG; - cli(); - t = timer_count; - SREG = sreg; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { + t = timer_count; + } return TIMER_DIFF_32(t, last); } // excecuted once per 1ms.(excess for just timer count?) -ISR(TIMER0_COMPA_vect) +#ifndef __AVR_ATmega32A__ +#define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect +#else +#define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect +#endif +ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK) { timer_count++; } |