Subversion Repositories HomeAutomation

Rev

Rev 492 | Details | Compare with Previous | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
361 andfri 1
/**
2
 * Timebase software module. Utilizes timer0 to provide a 32bit timebase with
3
 * millisecond-granularity to the application.
4
 *
5
 * @author  Martin Thomas
6
 * @author  Jimmy Myhrman
7
 *
8
 * @date    2006-11-19
9
 */
10
 
11
/*-----------------------------------------------------------------------------
12
 * Includes
13
 *---------------------------------------------------------------------------*/
14
#include <inttypes.h>
15
#include <avr/io.h>
16
#include <avr/interrupt.h>
17
 
18
#include <config.h>
19
#include <drivers/timer/timebase.h>
20
 
21
 
22
/*-----------------------------------------------------------------------------
23
 * Globals
24
 *---------------------------------------------------------------------------*/
25
volatile uint32_t gMilliSecTick;
26
 
27
 
28
/*-----------------------------------------------------------------------------
29
 * Interrupt Service Routines
30
 *---------------------------------------------------------------------------*/
408 andfri 31
#if defined(TIMEBASE_NEW_IMPLEMENTATION)
32
 
33
#if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
361 andfri 34
#if defined(TIMER2)
408 andfri 35
ISR(TIMER2_COMPA_vect) {
36
#else //!defined(TIMER2)
37
ISR(TIMER0_COMPA_vect) {
38
#endif //defined(TIMER2)
39
#else //!defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
40
ISR(TIMER2_COMP_vect) {
41
#endif //defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
42
    gMilliSecTick++;
43
}
44
 
45
#else //!defined(TIMEBASE_NEW_IMPLEMENTATION)
46
 
47
#if defined(TIMER2)
361 andfri 48
ISR(SIG_OVERFLOW2) {
49
    TCNT2 = TIMEBASE_RELOAD;
50
    gMilliSecTick++;
51
}
52
#else
53
ISR(SIG_OVERFLOW0) {
54
    TCNT0 = TIMEBASE_RELOAD;
55
    gMilliSecTick++;
56
}
57
#endif
58
 
408 andfri 59
#endif //defined(TIMEBASE_NEW_IMPLEMENTATION)
361 andfri 60
 
408 andfri 61
 
361 andfri 62
/*-----------------------------------------------------------------------------
63
 * Public Functions
64
 *---------------------------------------------------------------------------*/
65
 
66
/**
67
 * Initializes the timebase. The hardware timer interrupt source will be
68
 * enabled, but global interrupts need to be enabled by the application.
69
 */
70
void Timebase_Init() {
408 andfri 71
#if defined(TIMEBASE_NEW_IMPLEMENTATION)
72
 
361 andfri 73
#if defined(TIMER2)
74
    #if defined(__AVR_ATmega8__)
408 andfri 75
    TCCR2 = (1<<WGM21); // CTC mode
361 andfri 76
    #if TIMEBASE_PRESCALE == 64
77
    TCCR2 = (1<<CS22);  // prescaler: 64
78
    #elif TIMEBASE_PRESCALE == 256
79
    TCCR2 = (1<<CS22) | (1<<CS21); // prescaler: 256
80
    #endif
408 andfri 81
    OCR2 = TIMEBASE_HITS_PER_1MS; // set timer period
82
    TIFR  |= (1<<OCF2);  // clear ouput compare match flag
83
    TIMSK |= (1<<OCIE2); // enable output compare match interrupt
84
    #endif
85
 
86
    #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
87
    TCCR2A = (1<<WGM21); // CTC mode
88
    #if TIMEBASE_PRESCALE == 64
89
    TCCR2B = (1<<CS22); // prescaler: 64
90
    #elif TIMEBASE_PRESCALE == 256
91
    TCCR2B = (1<<CS22)|(1<<CS21);               // prescaler: 256
92
    #endif
93
    OCR2A = TIMEBASE_HITS_PER_1MS; // set timer period
94
    TIFR2  |= (1<<OCF2A);  // clear ouput compare match flag
415 noddan 95
    TIMSK2 |= (1<<OCIE2A); // enable output compare match interrupt
408 andfri 96
    #endif
97
#else /* Use timer0 */
98
    #if defined(__AVR_ATmega8__)
99
    #error TIMER0 not supported in ATmega8 with TIMEBASE_NEW_IMPLEMENTATION set!
100
    #endif
101
 
102
    #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
103
    TCCR0A = (1<<WGM01); // CTC mode
104
    #if TIMEBASE_PRESCALE == 64
105
    TCCR0B = (1<<CS01) | (1<<CS00); // prescaler: 64
106
    #elif TIMEBASE_PRESCALE == 256
107
    TCCR0B = (1<<CS02);             // prescaler: 256
108
    #endif
109
    OCR0A = TIMEBASE_HITS_PER_1MS; // set timer period
110
    TIFR0  |= (1<<OCF0A);  // clear ouput compare match flag
492 arune 111
    TIMSK0 |= (1<<OCIE0A); // enable output compare match interrupt
408 andfri 112
    #endif
113
#endif
114
 
115
 
116
#else //!defined(TIMEBASE_NEW_IMPLEMENTATION)
117
 
118
#if defined(TIMER2)
119
    #if defined(__AVR_ATmega8__)
120
    #if TIMEBASE_PRESCALE == 64
121
    TCCR2 = (1<<CS22);  // prescaler: 64
122
    #elif TIMEBASE_PRESCALE == 256
123
    TCCR2 = (1<<CS22) | (1<<CS21); // prescaler: 256
124
    #endif
361 andfri 125
    TCNT2 = TIMEBASE_RELOAD; // set initial reload-value
126
    TIFR  |= (1<<TOV2);  // clear overflow int.
127
    TIMSK |= (1<<TOIE2); // enable overflow-interrupt
128
    #endif
129
 
372 arune 130
    #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
361 andfri 131
    #if TIMEBASE_PRESCALE == 64
132
    TCCR2B = (1<<CS22); // prescaler: 64
133
    #elif TIMEBASE_PRESCALE == 256
134
    TCCR2B = (1<<CS22)|(1<<CS21);               // prescaler: 256
135
    #endif
136
    TCNT2 = TIMEBASE_RELOAD; // set initial reload-value
137
    TIFR2  |= (1<<TOV2);  // clear overflow int.
138
    TIMSK2 |= (1<<TOIE2); // enable overflow-interrupt
139
    #endif
140
#else /* Use timer0 */
141
    #if defined(__AVR_ATmega8__)
142
    #if TIMEBASE_PRESCALE == 64
143
    TCCR0 = (1<<CS01) | (1<<CS00);  // prescaler: 64
144
    #elif TIMEBASE_PRESCALE == 256
145
    TCCR0 = (1<<CS02);              // prescaler: 256
146
    #endif
147
    TCNT0 = TIMEBASE_RELOAD; // set initial reload-value
148
    TIFR  |= (1<<TOV0);  // clear overflow int.
149
    TIMSK |= (1<<TOIE0); // enable overflow-interrupt
150
    #endif
151
 
372 arune 152
    #if defined(__AVR_ATmega88__) || defined(__AVR_ATmega168__)
361 andfri 153
    #if TIMEBASE_PRESCALE == 64
154
    TCCR0B = (1<<CS01) | (1<<CS00); // prescaler: 64
155
    #elif TIMEBASE_PRESCALE == 256
156
    TCCR0B = (1<<CS02);             // prescaler: 256
157
    #endif
158
    TCNT0 = TIMEBASE_RELOAD; // set initial reload-value
159
    TIFR0  |= (1<<TOV0);  // clear overflow int.
160
    TIMSK0 |= (1<<TOIE0); // enable overflow-interrupt
161
    #endif
162
#endif
408 andfri 163
 
164
#endif //defined(TIMEBASE_NEW_IMPLEMENTATION)
361 andfri 165
}
166
 
167
 
168
/**
169
 * Reads the current time.
170
 *
171
 * @return
172
 *      The current time in milliseconds (32bit value).
173
 */
174
uint32_t Timebase_CurrentTime(void) {
175
    uint8_t sreg;
362 andfri 176
    uint32_t res;
361 andfri 177
    sreg=SREG;
178
    cli();
179
    res = gMilliSecTick;
180
    SREG=sreg;
181
    return res;
182
}
183
 
184
 
185
/**
186
 * Checks how much time has passed since a given timestamp.
187
 *
188
 * @param t0
189
 *      The timestamp.
190
 * @return
191
 *      Number of milliseconds that have passed since t0.
192
 */
193
uint32_t Timebase_PassedTimeMillis(uint32_t t0) {
194
    uint8_t sreg;
362 andfri 195
    uint32_t res;
361 andfri 196
    sreg=SREG;
197
    cli();
362 andfri 198
    res = (uint32_t)(gMilliSecTick-t0);
361 andfri 199
    SREG=sreg;
200
    return res;
201
}