X-Git-Url: http://git.rrze.uni-erlangen.de/gitweb/?p=moodlight.git;a=blobdiff_plain;f=timers.c;fp=timers.c;h=754db0605cb48d5facf94771aa78f6bee11bf4fa;hp=0000000000000000000000000000000000000000;hb=10ee5c5d2f67244662b528199b9f0d406fd2fefa;hpb=17aea8ef6cd47a0469e248a4e7325bcde394ea51 diff --git a/timers.c b/timers.c new file mode 100644 index 0000000..754db06 --- /dev/null +++ b/timers.c @@ -0,0 +1,85 @@ +/* $Id: timers.c,v 1.1 2010/06/27 22:18:26 simimeie Exp $ + * Functions for timing. + * This mainly allows you to get a timestamp value + */ + +#include +#include +#include "timers.h" + +/* Internal ticks */ +static volatile uint16_t ticks = 0; + +/* FIXME TCNT1H TCNT1L */ + +/* Executes every 65536 cpu cycles when the timer overflows */ +ISR(TIMER1_OVF_vect) +{ + ticks++; +} + +uint16_t getticks(void) +{ + uint16_t res; + cli(); + res = ticks; + sei(); + return res; +} + +uint16_t getticks_noirq(void) +{ + return ticks; +} + +struct timestamp gettimestamp(void) +{ + uint16_t cou1, cou2, tick1; + struct timestamp res; + /* Low byte must be read first for 16bit registers */ + cou1 = TCNT1L; + cou1 |= (uint16_t)(TCNT1H) << 8; + tick1 = getticks(); /* enables interrupts! */ + cou2 = TCNT1L; + cou2 |= (uint16_t)(TCNT1H) << 8; + if (cou1 > cou2) { /* An overflow occured in between */ + /* get new ticks value - we could already have it, but we do not know + * for sure. If we get another one now, we do - because there is no + * way we're going to need another 65k cpu cycles. */ + res.ticks = getticks(); + } else { /* no overflow. */ + res.ticks = tick1; + } + res.partticks = cou2; + return res; +} + +struct timestamp gettimestamp_noirq(void) +{ + uint16_t cou1, cou2; uint8_t ovf; + struct timestamp res; + /* Low byte must be read first for 16bit registers */ + cou1 = TCNT1L; + cou1 |= (uint16_t)(TCNT1H) << 8; + /* Check if there is an overflow pending */ + ovf = TIFR1 & _BV(TOV1); + if (ovf) { + /* Overflow pending, reread the counter to be sure */ + cou2 = TCNT1L; + cou2 |= (uint16_t)(TCNT1H) << 8; + res.ticks = ticks + 1; + res.partticks = cou2; + } else { + res.ticks = ticks; + res.partticks = cou1; + } + return res; +} + +void timers_init(void) +{ + /* Enable counter1, no prescaling (1 increment per clock cycle!) */ + TCCR1B |= _BV(CS10); + /* Enable interrupt when timer overflows (at 65536) */ + TIMSK1 |= _BV(TOIE1); +}