completely redid PWM: Now calculate 'microprograms', i.e. pairs of
[moodlight.git] / timers.c
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
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 void ledpwm_TIMER1OVF_hook(void);
14
15 /* Executes every 65536 cpu cycles when the timer overflows */
16 ISR(TIMER1_OVF_vect)
17 {
18   ticks++;
19   ledpwm_TIMER1OVF_hook();
20 }
21
22 uint16_t getticks(void)
23 {
24   uint16_t res;
25   cli();
26   res = ticks;
27   sei();
28   return res;
29 }
30
31 uint16_t getticks_noirq(void)
32 {
33   return ticks;
34 }
35
36 struct timestamp gettimestamp(void)
37 {
38   uint16_t cou1, cou2, tick1;
39   struct timestamp res;
40   /* Low byte must be read first for 16bit registers */
41   cou1 = TCNT1L;
42   cou1 |= (uint16_t)(TCNT1H) << 8;
43   tick1 = getticks(); /* enables interrupts! */
44   cou2 = TCNT1L;
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. */
52     res.ticks = tick1;
53   }
54   res.partticks = cou2;
55   return res;
56 }
57
58 struct timestamp gettimestamp_noirq(void)
59 {
60   uint16_t cou1, cou2; uint8_t ovf;
61   struct timestamp res;
62   /* Low byte must be read first for 16bit registers */
63   cou1 = TCNT1L;
64   cou1 |= (uint16_t)(TCNT1H) << 8;
65   /* Check if there is an overflow pending */
66   ovf = TIFR1 & _BV(TOV1);
67   if (ovf) {
68     /* Overflow pending, reread the counter to be sure */
69     cou2 = TCNT1L;
70     cou2 |= (uint16_t)(TCNT1H) << 8;
71     res.ticks = ticks + 1;
72     res.partticks = cou2;
73   } else {
74     res.ticks = ticks;
75     res.partticks = cou1;
76   }
77   return res;
78 }
79
80 void timers_init(void)
81 {
82   /* Enable counter1, no prescaling (1 increment per clock cycle!) */
83   TCCR1B |= _BV(CS10);
84   /* Enable interrupt when timer overflows (at 65536) */
85   TIMSK1 |= _BV(TOIE1);
86 }
This page took 0.050203 seconds and 3 git commands to generate.