/*
**	Project:	Delay Functions
**	Purpose:	Define a series of functions to delay for a specified
**				time -- every millisecond or every ~50 microseconds.
**
**	Author:		Steven Pickles
**	Date:		Saturday, July 02, 2005
**
**	Notes:		The timer delays were tested using an oscilloscope, but
**				still are not 100% exact... although they are close.
*/


/*
**	Compiler Include Directives
*/
#include "delay.h"


/*
**	Global Variables
*/

volatile uint16_t delayCount;




/*
**	Function:		initializeDelayTimerMicrosecond
**	Parameters:		<none>
**	Purpose:		Initialize timer 0 to use the system clock and output
**					compare 0 to generate an interrupt once per	microsecond.
**					This is then used for any general purpose delay.
**	Returns:		<none>
*/
void initializeDelayTimerMicrosecond(void)
{
	//	Clear the timer/counter control register 0
	TCCR0 = 0;
	
	//	Set the output compare match interrupt enable, and overflow
	//	interrupt enable bits of the timer/counter interrupt flag register
	TIFR |= _BV(OCF0);
	
	//	Set the waveform generation mode to accept register OCR0 as the
	//	top value and clear the timer on a compare match (CTC) mode.  The
	//	timer clock is equal to the system clock divided by 8.
	TCCR0 = _BV(WGM01) | _BV(CS01);
	
	//	Clear the timer/counter register 0
	TCNT0 = 0;
	
	//	Set the output compare flag, and overflow flag bits of the
	//	timer/counter interrupt mask register
	TIMSK |= _BV(OCIE0);
	
	//	Set the top value of the counter by setting the
	//	OCR register to the predetermined value
	OCR0  = OCR_1MICROSECOND;
}


/*
**	Function:		initializeDelayTimerMillisecond
**	Parameters:		<none>
**	Purpose:		Initialize timer 0 to use the system clock and output
**					compare 0 to generate an interrupt once per millisecond.
**					This is then used for any general purpose delay.
**	Returns:		<none>
*/
void initializeDelayTimerMillisecond(void)
{
	//	Clear the timer/counter control register 0
	TCCR0 = 0;
	
	//	Set the output compare match interrupt enable, and overflow
	//	interrupt enable bits of the timer/counter interrupt flag register
	TIFR |= _BV(OCF0);
	
	//	Set the waveform generation mode to accept register OCR0 as the
	//	top value and clear the timer on a compare match (CTC) mode.  There
	//	is a clock prescaler of 64 since the delay is 1 millisecond.
	TCCR0 = _BV(WGM01) | _BV(CS02);
	
	//	Clear the timer/counter register 0
	TCNT0 = 0;
	
	//	Set the output compare flag, and overflow flag bits of the
	//	timer/counter interrupt mask register
	TIMSK |= _BV(OCIE0);
	
	//	Set the top value of the counter by setting the
	//	OCR register to the predetermined value
	OCR0  = OCR_1MILLISECOND;
}


/*
**	Function:		runDelay
**	Parameters:		delayUnits - the number of times the interrupt must fire
**								 in order for the delay to be complete
**	Purpose:		Performs a delay for a specified number of units.
**	Returns:		<none>
*/
void runDelay(uint16_t delayUnits)
{
	//	Clear the timer/counter register 0
	TCNT0  = 0;
	
	//	Clear the delay counter variable
	delayCount = 0;
	
	//	Perform the delay with a simple loop until finished
	while (delayCount != delayUnits)
		;
}


/*
**	Function:		delay50us
**	Parameters:		delayUnits - the number of times the interrupt must fire
**								 in order for the delay to be complete
**	Purpose:		Performs a delay for a specified number of units.
**					This is basically a wrapper function and is meant to be
**					used as a wrapper for the actual delay function.
**	Returns:		<none>
*/
void delay50us(uint16_t delayUnits)
{
	//	Run the delay for delayUnits time
	runDelay(delayUnits);
}

