4 * Copyright 2005 Develer S.r.l. (http://www.develer.com/)
5 * This file is part of DevLib - See README.devlib for information.
10 * \author Bernardo Innocenti <bernie@develer.com>
11 * \author Francesco Sacchi <batt@develer.com>
13 * \brief Low-level timer module for AVR (implementation).
18 *#* Revision 1.4 2006/07/19 12:56:26 bernie
19 *#* Convert to new Doxygen style.
21 *#* Revision 1.3 2006/06/12 21:37:02 marco
22 *#* implemented some commands (ver and sleep)
24 *#* Revision 1.2 2006/05/18 00:37:58 bernie
25 *#* Don't include unneeded header hw.h.
27 *#* Revision 1.1 2005/07/19 07:28:36 bernie
28 *#* Refactor to decouple timer ticks from milliseconds.
30 *#* Revision 1.1 2005/05/24 09:17:58 batt
31 *#* Move drivers to top-level.
34 #include <drv/timer_avr.h>
35 #include <cfg/macros.h> // BV()
37 #include <avr/interrupt.h>
40 /** HW dependent timer initialization */
41 #if (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE0)
43 static void timer_hw_init(void)
46 IRQ_SAVE_DISABLE(flags);
48 /* Reset Timer flags */
49 TIFR = BV(OCF0) | BV(TOV0);
51 /* Setup Timer/Counter interrupt */
52 ASSR = 0x00; /* Internal system clock */
53 TCCR0 = BV(WGM01) /* Clear on Compare match */
54 #if TIMER_PRESCALER == 64
57 #error Unsupported value of TIMER_PRESCALER
60 TCNT0 = 0x00; /* Initialization of Timer/Counter */
61 OCR0 = OCR_DIVISOR; /* Timer/Counter Output Compare Register */
63 /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */
70 INLINE hptime_t timer_hw_hpread(void)
75 #elif (CONFIG_TIMER == TIMER_ON_OVERFLOW1)
77 static void timer_hw_init(void)
80 IRQ_SAVE_DISABLE(flags);
82 /* Reset Timer overflow flag */
85 /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */
86 #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9)
89 TCCR1B |= BV(WGM12) | BV(CS10);
90 TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12));
91 /* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */
92 #elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8)
95 TCCR1B |= BV(WGM12) | BV(CS10);
96 TCCR1B &= ~(BV(WGM13) | BV(CS11) | BV(CS12));
98 #error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS
101 TCNT1 = 0x00; /* initialization of Timer/Counter */
103 /* Enable timer interrupt: Timer/Counter1 Overflow */
109 INLINE hptime_t timer_hw_hpread(void)
114 #elif (CONFIG_TIMER == TIMER_ON_OUTPUT_COMPARE2)
116 static void timer_hw_init(void)
119 IRQ_SAVE_DISABLE(flags);
121 /* Reset Timer flags */
122 TIFR = BV(OCF2) | BV(TOV2);
124 /* Setup Timer/Counter interrupt */
126 #if TIMER_PRESCALER == 64
127 | BV(CS21) | BV(CS20)
129 #error Unsupported value of TIMER_PRESCALER
132 /* Clear on Compare match & prescaler = 64, internal sys clock.
133 When changing prescaler change TIMER_HW_HPTICKS_PER_SEC too */
134 TCNT2 = 0x00; /* initialization of Timer/Counter */
135 OCR2 = OCR_DIVISOR; /* Timer/Counter Output Compare Register */
137 /* Enable timer interrupts: Timer/Counter2 Output Compare (OCIE2) */
144 INLINE hptime_t timer_hw_hpread(void)
148 #elif (CONFIG_TIMER == TIMER_ON_OVERFLOW3)
150 static void timer_hw_init(void)
153 IRQ_SAVE_DISABLE(flags);
155 /* Reset Timer overflow flag */
158 /* Fast PWM mode, 9 bit, 24 kHz, no prescaling. */
159 #if (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 9)
161 TCCR3A &= ~BV(WGM30);
162 TCCR3B |= BV(WGM32) | BV(CS30);
163 TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32));
164 /* Fast PWM mode, 8 bit, 24 kHz, no prescaling. */
165 #elif (TIMER_PRESCALER == 1) && (TIMER_HW_BITS == 8)
167 TCCR3A &= ~BV(WGM31);
168 TCCR3B |= BV(WGM32) | BV(CS30);
169 TCCR3B &= ~(BV(WGM33) | BV(CS31) | BV(CS32));
171 #error Unsupported value of TIMER_PRESCALER or TIMER_HW_BITS
174 TCNT3 = 0x00; /* initialization of Timer/Counter */
176 /* Enable timer interrupt: Timer/Counter3 Overflow */
177 /* ATTENTION! TOIE3 is only on ETIMSK, not TIMSK */
183 INLINE hptime_t timer_hw_hpread(void)
189 #error Unimplemented value for CONFIG_TIMER
190 #endif /* CONFIG_TIMER */