You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.0 KiB

/** @file timer.c
@author M. P. Hayes, UCECE
@date 23 August 2010
@brief Timer module
*/
#include <avr/io.h>
#include "timer.h"
#include "system.h"
/* Timer/counter1 is a 16-bit counter with prescale options 1, 8, 64,
256, and 1024. With F_CPU = 8e6 this corresponds to clock rates of
8 MHz, 1 MHz, 125 kHz, 31.25 kHz, 7.8125 kHz. The counter will
roll over every 8.192 ms, 65.536 ms, 524.288 ms, 2.097s, and 8.389 s. */
#if TIMER_CLOCK_DIVISOR == 1
#define TCCR1B_INIT 0x01
#elif TIMER_CLOCK_DIVISOR == 8
#define TCCR1B_INIT 0x02
#elif TIMER_CLOCK_DIVISOR == 64
#define TCCR1B_INIT 0x03
#elif TIMER_CLOCK_DIVISOR == 256
#define TCCR1B_INIT 0x04
#elif TIMER_CLOCK_DIVISOR == 1024
#define TCCR1B_INIT 0x05
#else
#error Invalid TIMER_CLOCK_DIVISOR
#endif
/** Initialise timer. */
void timer_init (void)
{
/* Start timer in normal mode so that it rolls over at 65535 to 0. */
TCCR1A = 0x00;
TCCR1B = TCCR1B_INIT;
TCNT1 = 0;
}
/** Get current time:
@return current time in ticks. */
timer_tick_t timer_get (void)
{
return TCNT1;
}
/** Wait until specified time:
@param when time to sleep until
@return current time. */
timer_tick_t timer_wait_until (timer_tick_t when)
{
while (1)
{
timer_tick_t diff;
timer_tick_t now;
now = timer_get ();
/* Note, both when and now are unsigned so they wrap around to
zero when they overflow. The difference is also unsigned
so when now < when then the result wraps around to a large
positive value and fails the following test. */
diff = now - when;
/* There is a possibility that we are called when when < now.
So we allow a possible overrun defined by
TIMER_OVERRUN_MAX. */
if (diff < TIMER_OVERRUN_MAX)
return now;
}
}
/** Wait for specified period:
@param period how long to wait
@return current time. */
timer_tick_t timer_wait (timer_tick_t period)
{
return timer_wait_until (timer_get () + period);
}