Fix RG Sleep issues for Teensy Controllers
[jackhill/qmk/firmware.git] / tmk_core / common / avr / timer.c
CommitLineData
a074364c 1/*
2Copyright 2011 Jun Wako <wakojun@gmail.com>
3
4This program is free software: you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation, either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program. If not, see <http://www.gnu.org/licenses/>.
16*/
17
18#include <avr/io.h>
19#include <avr/interrupt.h>
be4e7542 20#include <util/atomic.h>
a074364c 21#include <stdint.h>
22#include "timer_avr.h"
23#include "timer.h"
24
25
26// counter resolution 1ms
27// NOTE: union { uint32_t timer32; struct { uint16_t dummy; uint16_t timer16; }}
be4e7542 28volatile uint32_t timer_count;
a074364c 29
7c9d5ace 30/** \brief timer initialization
31 *
32 * FIXME: needs doc
33 */
a074364c 34void timer_init(void)
35{
a074364c 36#if TIMER_PRESCALER == 1
f7462aaa 37 uint8_t prescaler = 0x01;
a074364c 38#elif TIMER_PRESCALER == 8
f7462aaa 39 uint8_t prescaler = 0x02;
a074364c 40#elif TIMER_PRESCALER == 64
f7462aaa 41 uint8_t prescaler = 0x03;
a074364c 42#elif TIMER_PRESCALER == 256
f7462aaa 43 uint8_t prescaler = 0x04;
a074364c 44#elif TIMER_PRESCALER == 1024
f7462aaa 45 uint8_t prescaler = 0x05;
a074364c 46#else
47# error "Timer prescaler value is NOT vaild."
48#endif
49
f7462aaa
LR
50#ifndef __AVR_ATmega32A__
51 // Timer0 CTC mode
52 TCCR0A = 0x02;
53
54 TCCR0B = prescaler;
55
a074364c 56 OCR0A = TIMER_RAW_TOP;
57 TIMSK0 = (1<<OCIE0A);
f7462aaa
LR
58#else
59 // Timer0 CTC mode
60 TCCR0 = (1 << WGM01) | prescaler;
61
62 OCR0 = TIMER_RAW_TOP;
63 TIMSK = (1 << OCIE0);
64#endif
a074364c 65}
66
7c9d5ace 67/** \brief timer clear
68 *
69 * FIXME: needs doc
70 */
a074364c 71inline
72void timer_clear(void)
73{
be4e7542 74 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
a074364c 75 timer_count = 0;
be4e7542 76 }
a074364c 77}
78
7c9d5ace 79/** \brief timer read
80 *
81 * FIXME: needs doc
82 */
a074364c 83inline
84uint16_t timer_read(void)
85{
86 uint32_t t;
87
be4e7542
WF
88 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
89 t = timer_count;
90 }
a074364c 91
92 return (t & 0xFFFF);
93}
94
7c9d5ace 95/** \brief timer read32
96 *
97 * FIXME: needs doc
98 */
a074364c 99inline
100uint32_t timer_read32(void)
101{
102 uint32_t t;
103
be4e7542
WF
104 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
105 t = timer_count;
106 }
a074364c 107
108 return t;
109}
110
7c9d5ace 111/** \brief timer elapsed
112 *
113 * FIXME: needs doc
114 */
a074364c 115inline
116uint16_t timer_elapsed(uint16_t last)
117{
118 uint32_t t;
119
be4e7542
WF
120 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
121 t = timer_count;
122 }
a074364c 123
124 return TIMER_DIFF_16((t & 0xFFFF), last);
125}
126
7c9d5ace 127/** \brief timer elapsed32
128 *
129 * FIXME: needs doc
130 */
a074364c 131inline
132uint32_t timer_elapsed32(uint32_t last)
133{
134 uint32_t t;
135
be4e7542
WF
136 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
137 t = timer_count;
138 }
a074364c 139
140 return TIMER_DIFF_32(t, last);
141}
142
143// excecuted once per 1ms.(excess for just timer count?)
f7462aaa
LR
144#ifndef __AVR_ATmega32A__
145#define TIMER_INTERRUPT_VECTOR TIMER0_COMPA_vect
146#else
147#define TIMER_INTERRUPT_VECTOR TIMER0_COMP_vect
148#endif
149ISR(TIMER_INTERRUPT_VECTOR, ISR_NOBLOCK)
a074364c 150{
151 timer_count++;
152}