/**************************************************************************************************
---------------------------------------------------------------------------------------------------
	Copyright (c) 2004-2007, Jonathan Bagg
	All rights reserved.

	 Redistribution and use in source and binary forms, with or without modification, are permitted 
	 provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice, this list of 
	  conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice, this list of 
	  conditions and the following disclaimer in the documentation and/or other materials provided 
	  with the distribution.
    * Neither the name of Jonathan Bagg nor the names of its contributors may be used to 
	  endorse or promote products derived from this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 
  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 
  AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
  POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------------------------------
   Project name : Infidigm AVR Drivers
   Processor	: ATMega64, ATMega128
   File name    : tim.h
---------------------------------------------------------------------------------------------------
   Modifications: 

   Revision 1.0  2004/06/11 	Bagg
   - Cleaned up for release
   
   Revision 1.1  2004/12/15 	Bagg
   - StopWatch Functions added
   
   Revision 1.2  2007/05/12 	Bagg
   - read_systimer() added
---------------------------------------------------------------------------------------------------
   Created      : 05 May 2004     	           Author(s) : Jonathan Bagg
---------------------------------------------------------------------------------------------------
   System Timers / Tick Timer Interrupt Based Driver
---------------------------------------------------------------------------------------------------
**************************************************************************************************/

/**************************************************************************************************
*   System Timer Definitions
**************************************************************************************************/
#define MAXTIMERS	16					//Maximum Timers allowed
#define NOTUSED		0
#define AUTOEXP		3					//Can be 1-250 cycles
#define NOTDONE		(AUTOEXP + 1)
#define ROLLOVER	(NOTDONE + 1)

/**************************************************************************************************
*
*   Signal	          : SIG_OUTPUT_COMPARE0
*
*   Description       : Maintains System timers. Acts as a 'tick' timer. Controls beeper styles.
*
*   Parameters        : None
*
*   Functions Called  : update_timers()
*
*   Returns           : None
*
**************************************************************************************************/

/**************************************************************************************************
*
*   Function          : start_timer
*
*   Description       : Sets up TimerCounter0 with a clock = (Main Oscillator / 128).  Sets TC0 for 
*						CTC mode, enables OC0 Interrupt and sets OCR register to control length of 
*						the tick timer.
*
*   Parameters        : None
*
*   Functions Called  : None
*
*   Returns           : None
*
**************************************************************************************************/
void start_timer(void);

/**************************************************************************************************
*
*   Function          : update_timers ( INTERNAL )
*
*   Description       : This Function is called by the TC0 OCR IRS when the tick timer (systemer)
*						overflows.  The function updates the 'type' element for each of the timers.
*
*   Parameters        : None
*
*   Functions Called  : None
*
*   Returns           : None
*
**************************************************************************************************/

/**************************************************************************************************
*
*   Function          : read_systimer
*
*   Description       : This Function is used to read the value of systimer for exturnal use.
*
*   Parameters        : None
*
*   Functions Called  : None
*
*   Returns           : The value of systimer
*
**************************************************************************************************/
unsigned int read_systimer(void);

/**************************************************************************************************
*
*   Function          : timer_get
*
*   Description       : This Function finds the next free timer, initializes the timer, and sets
* 						time time until it expires
*
*   Parameters        : time until expiration
*
*   Functions Called  : timer_reset()
*
*   Returns           : the number of the timer (0 to MAXTIMERS)
*
**************************************************************************************************/
unsigned char timer_get(unsigned int time);

/**************************************************************************************************
*
*   Function          : timer_reset
*
*   Description       : This Function reset the timer that is passed to it with the expiration time 
*						that it is passed to it. Also updated the timer type element apropriatly
*
*   Parameters        : timer number, time until expiration
*
*   Functions Called  : None
*
*   Returns           : None
*
**************************************************************************************************/
void timer_reset(unsigned char timer, unsigned int time);

/**************************************************************************************************
*
*   Function          : timer_expired
*
*   Description       : This Function compares the timer expiration value against the systimer to 
*						test for expiration. 
*
*   Parameters        : timer number
*
*   Functions Called  : None
*
*   Returns           : 0 if not expired, 1 if expired
*
**************************************************************************************************/
unsigned char timer_expired(unsigned char timer);

/**************************************************************************************************
*
*   Function          : timer_release
*
*   Description       : This Function frees / releases the timer that is passed to it.
*
*   Parameters        : timer number
*
*   Functions Called  : None
*
*   Returns           : None
*
**************************************************************************************************/
void timer_release(unsigned char timer);

/**************************************************************************************************
*
*   Function          : stopwatch_get
*
*   Description       : This Function finds the next free timer, and then calls stopwatch_reset()
*						Similar to timer_get().
*
*   Parameters        : None
*
*   Functions Called  : stopwatch_reset()
*
*   Returns           : the number of the timer (0 to MAXTIMERS)
*
**************************************************************************************************/
unsigned char stopwatch_get(void);

/**************************************************************************************************
*
*   Function          : stopwatch_reset
*
*   Description       : This Function initializes the timer, and records
* 						the valve of systimer for later comparison. Similar to timer_reset().
*
*   Parameters        : timer to use
*
*   Functions Called  : None
*
*   Returns           : None
*
**************************************************************************************************/
void stopwatch_reset(unsigned char timer);

/**************************************************************************************************
*
*   Function          : stopwatch_check
*
*   Description       : This Function compares the systimer to the recorded value of systimer to
*						determine the amount of time that has elapsed.  If a time longer that the 
*						maximum time has elapsed, the function returns the maximum amount of time.
*						NOTE: ONLY pass timers to this function that has been gotten by
*						stopwatch_get()!  If timers are passed to this funcion that have been 
*						gotten by timer_get(), an incorrect time will be returned!
*
*   Parameters        : timer number
*
*   Functions Called  : None
*
*   Returns           : The ammount of time that has passed since the the timer was gotten.
*
**************************************************************************************************/
unsigned int stopwatch_check(unsigned char timer);

#define stopwatch_release(timer)	timer_release(timer)


/**************************************************************************************************
*
*   Function          : delay
*
*   Description       : This Function waits in a loop until the amount of time passed to it expires
*
*   Parameters        : time to wait
*
*   Functions Called  : timer_get(), timer_expired(), timer_release()
*
*   Returns           : None
*
**************************************************************************************************/
void delay(unsigned int time);
