1 /* $Id: timers.c,v 1.2 2010/07/25 20:40:44 simimeie Exp $
2 * Functions for timing.
3 * This mainly allows you to get a timestamp value
7 #include <avr/interrupt.h>
11 static volatile uint16_t ticks = 0;
13 void ledpwm_TIMER1OVF_hook(void);
15 /* Executes every 65536 cpu cycles when the timer overflows */
19 ledpwm_TIMER1OVF_hook();
22 uint16_t getticks(void)
31 uint16_t getticks_noirq(void)
36 struct timestamp gettimestamp(void)
38 uint16_t cou1, cou2, tick1;
40 /* Low byte must be read first for 16bit registers */
42 cou1 |= (uint16_t)(TCNT1H) << 8;
43 tick1 = getticks(); /* enables interrupts! */
45 cou2 |= (uint16_t)(TCNT1H) << 8;
46 if (cou1 > cou2) { /* An overflow occured in between */
47 /* get new ticks value - we could already have it, but we do not know
48 * for sure. If we get another one now, we do - because there is no
49 * way we're going to need another 65k cpu cycles. */
50 res.ticks = getticks();
51 } else { /* no overflow. */
58 struct timestamp gettimestamp_noirq(void)
60 uint16_t cou1, cou2; uint8_t ovf;
62 /* Low byte must be read first for 16bit registers */
64 cou1 |= (uint16_t)(TCNT1H) << 8;
65 /* Check if there is an overflow pending */
66 ovf = TIFR1 & _BV(TOV1);
68 /* Overflow pending, reread the counter to be sure */
70 cou2 |= (uint16_t)(TCNT1H) << 8;
71 res.ticks = ticks + 1;
80 void timers_init(void)
82 /* Enable counter1, no prescaling (1 increment per clock cycle!) */
84 /* Enable interrupt when timer overflows (at 65536) */