/*
Copyright 2007, Freie Universitaet Berlin. All rights reserved.

These sources were developed at the Freie Universität Berlin, Computer
Systems and Telematics group.

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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is"
basis, without any representations or warranties of any kind, express
or implied including, but not limited to, representations or
warranties of non-infringement, merchantability or fitness for a
particular purpose. In no event shall FUB 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.

This implementation was developed by the CST group at the FUB.

For documentation and questions please use the web site
http://scatterweb.mi.fu-berlin.de and the mailinglist
scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website).
Berlin, 2007
*/

/**
 @file		ScatterWeb.Timers.h
 @ingroup	kernel						
 @brief		The ScatterWeb.Timers provides the Timer component, which allows you to raise an event on a specified interval.
 @version	$Revision: 501 $					
 @since		1.0
 @author	Marco Hutta

 The Timer component is a hardware-based timer, which allows you to specify
 a recurring interval at which the Elapsed event is raised in your
 application. You can then handle this event to provide regular processing.
 <p>
 Software timers
 <p>
 With theses function you can implement delays asynchronously. Just give a
 time and a pointer to a function which should get called when the time has
 elapsed. 
 <p>
 The timer entries are kept in a fixed size array (MAX_TIMERS, timers, 
 numberTimers). The entry at position 0 will always contain the next timer to
 expire. The ticks in the timer entries are not decreased with every system
 tick but first accumulated into _ticks until one of two things happen:
 <p>
 - _ticks becomes greater than timers[0].ticks, what means that at least
   timers[0] has elapsed (if no timer is running timers[0].ticks is set to
   0xFFFFFFFF, so this will never happen then). The interrupt routine sets 
   callTimer to 1 and Timers_eventHandler will execute. It calls _Timers_consolidate
   and all elapsed timers (where ticks==0).
 - An overflow when adding a new timer is detected. For example a timer with
   50000 ticks was added. _ticks has run up to 30000 and then a new timer
   with 40000 ticks comes in. To get the correct offset for the timer it has
   to be added internally with 30000+40000=70000 ticks, but that is greater
   than maximum integer value 65535. _Timers_consolidate is called which decreases
   first timer to 20000, _ticks to 0, the second timer is then added with
   40000 ticks.
 <p>
 _Timers_consolidate reads _ticks and subtracts the value from all timers[i].ticks
 (or sets them to 0 if they are already smaller) and _ticks itself. This is a
 safe way to synchronize with the interrupt and better than setting _ticks to
 0, because if _ticks is just increased by the interrupt in between read and
 write the single tick will not get lost.

 $Id: ScatterWeb.Timers.h 501 2008-01-30 09:59:02Z hutta@PCPOOL.MI.FU-BERLIN.DE $
 */

/**
 @ingroup kernel
 @{
 */

#ifndef ScatterWeb_Timers
#define ScatterWeb_Timers

/**
 @brief	Timer callback function pointer type.

 @see	Timers_add
 @see	Timers_remove

 @since	1.0
 */
typedef void(*fp_timer)(void*); 

/**
 @brief		Initialization of DCO, TimerA, TimerB and software timer table.

 @return	<code>True</code> always.

 @since		1.0

 This method first calls SetDCO and initializes variables for timers.
 Timer_A is initialized to run from the divided 32,768 Hz Crystal at 4096 Hz.
 Timer_B is initialized to run from the self-regulated DCO at 4,505600 MHz.
 <p>
 Timer_A0 is used to generate an interrupt every 4 ticks once a 1024/second
 near to a millisecond.)
 Timer_A1(-3) is used by watchdog.c to implement a software watchdog.
 Timer_B0 is used by recir.c to capture RC5 signals every 890 us.  
 Timer_B1(-6) is used to measure the DCO continously with TB6.
 */ 
bool Timers_init();

/**
 @brief				Strictly adds a timer, also if it exists already.

 @see				fp_timer
 @param[in]			t			ticks for elapse
 @param[in]			fp		function to call if expired
 @param[in]			data	parameter to call function (without: use 0xFFFF)
 @return					<code>True</code> if successful;
							<code>False</code> otherwise.

 @since				1.0

 If ticks are passed, the given functions is called.
 */
bool Timers_add(uint32_t t, fp_timer fp, void* data);

/**
 @brief				Removes timer if data is matching.

 @see				fp_timer
 @param[in]			fp		function to call if expired
 @param[in]			data	parameter to call function
 @return					<code>True</code> if successful;
							<code>False</code> otherwise. 

 @since				1.0
 */
bool Timers_remove(fp_timer fp, void* data);

/* 
 @brief	This member supports the ScatterWeb infrastructure and is not intended to be used directly from your code.

 @since	1.0
 */
bool Timers_eventHandler();

#endif

/** @} */
