completely redid PWM: Now calculate 'microprograms', i.e. pairs of
[moodlight.git] / timers.c
CommitLineData
4307b86a 1/* $Id: timers.c,v 1.2 2010/07/25 20:40:44 simimeie Exp $
10ee5c5d 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 */
11static volatile uint16_t ticks = 0;
12
4307b86a 13void ledpwm_TIMER1OVF_hook(void);
10ee5c5d 14
15/* Executes every 65536 cpu cycles when the timer overflows */
16ISR(TIMER1_OVF_vect)
17{
18 ticks++;
4307b86a 19 ledpwm_TIMER1OVF_hook();
10ee5c5d 20}
21
22uint16_t getticks(void)
23{
24 uint16_t res;
25 cli();
26 res = ticks;
27 sei();
28 return res;
29}
30
31uint16_t getticks_noirq(void)
32{
33 return ticks;
34}
35
36struct 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
58struct 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
80void 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.099952 seconds and 4 git commands to generate.