- add eepromdata.h
[moodlight.git] / timers.c
1 /* $Id: timers.c,v 1.1 2010/06/27 22:18:26 simimeie Exp $
2  * Functions for timing.
3  * This mainly allows you to get a timestamp value
4  */
5
6 #include <avr/io.h>
7 #include <avr/interrupt.h>
8 #include "timers.h"
9
10 /* Internal ticks */
11 static volatile uint16_t ticks = 0;
12
13 /* FIXME TCNT1H TCNT1L */
14
15 /* Executes every 65536 cpu cycles when the timer overflows */
16 ISR(TIMER1_OVF_vect)
17 {
18   ticks++;
19 }
20
21 uint16_t getticks(void)
22 {
23   uint16_t res;
24   cli();
25   res = ticks;
26   sei();
27   return res;
28 }
29
30 uint16_t getticks_noirq(void)
31 {
32   return ticks;
33 }
34
35 struct timestamp gettimestamp(void)
36 {
37   uint16_t cou1, cou2, tick1;
38   struct timestamp res;
39   /* Low byte must be read first for 16bit registers */
40   cou1 = TCNT1L;
41   cou1 |= (uint16_t)(TCNT1H) << 8;
42   tick1 = getticks(); /* enables interrupts! */
43   cou2 = TCNT1L;
44   cou2 |= (uint16_t)(TCNT1H) << 8;
45   if (cou1 > cou2) { /* An overflow occured in between */
46     /* get new ticks value - we could already have it, but we do not know
47      * for sure. If we get another one now, we do - because there is no
48      * way we're going to need another 65k cpu cycles. */
49     res.ticks = getticks();
50   } else { /* no overflow. */
51     res.ticks = tick1;
52   }
53   res.partticks = cou2;
54   return res;
55 }
56
57 struct timestamp gettimestamp_noirq(void)
58 {
59   uint16_t cou1, cou2; uint8_t ovf;
60   struct timestamp res;
61   /* Low byte must be read first for 16bit registers */
62   cou1 = TCNT1L;
63   cou1 |= (uint16_t)(TCNT1H) << 8;
64   /* Check if there is an overflow pending */
65   ovf = TIFR1 & _BV(TOV1);
66   if (ovf) {
67     /* Overflow pending, reread the counter to be sure */
68     cou2 = TCNT1L;
69     cou2 |= (uint16_t)(TCNT1H) << 8;
70     res.ticks = ticks + 1;
71     res.partticks = cou2;
72   } else {
73     res.ticks = ticks;
74     res.partticks = cou1;
75   }
76   return res;
77 }
78
79 void timers_init(void)
80 {
81   /* Enable counter1, no prescaling (1 increment per clock cycle!) */
82   TCCR1B |= _BV(CS10);
83   /* Enable interrupt when timer overflows (at 65536) */
84   TIMSK1 |= _BV(TOIE1);
85 }
This page took 0.052374 seconds and 3 git commands to generate.