/*!
* This flag is used to loop through the main several times in order to be sure
* that all pending events have been processed.
*/
volatile uint8_t HasLoopedThroughMain = 0;
/*!
* Timers list head pointer
*/
static TimerEvent_t *TimerListHead = NULL;
/*!
* \brief Adds or replace the head timer of the list.
*
* \remark The list is automatically sorted. The list head always contains the
* next timer to expire.
*
* \param [IN] obj Timer object to be become the new head
* \param [IN] remainingTime Remaining time of the previous head to be replaced
*/
static void TimerInsertNewHeadTimer( TimerEvent_t *obj, uint32_t remainingTime );
/*!
* \brief Adds a timer to the list.
*
* \remark The list is automatically sorted. The list head always contains the
* next timer to expire.
*
* \param [IN] obj Timer object to be added to the list
* \param [IN] remainingTime Remaining time of the running head after which the object may be added
*/
static void TimerInsertTimer( TimerEvent_t *obj, uint32_t remainingTime );
/*!
* \brief Sets a timeout with the duration "timestamp"
*
* \param [IN] timestamp Delay duration
*/
static void TimerSetTimeout( TimerEvent_t *obj );
/*!
* \brief Check if the Object to be added is not already in the list
*
* \param [IN] timestamp Delay duration
* \retval true (the object is already in the list) or false
*/
static bool TimerExists( TimerEvent_t *obj );
/*!
* \brief Read the timer value of the currently running timer
*
* \retval value current timer value
*/
TimerTime_t TimerGetValue( void );
static void TimerInsertTimer( TimerEvent_t *obj, uint32_t remainingTime )
{
uint32_t aggregatedTimestamp = 0; // hold the sum of timestamps
uint32_t aggregatedTimestampNext = 0; // hold the sum of timestamps up to the next event
TimerEvent_t* prev = TimerListHead;
TimerEvent_t* cur = TimerListHead->Next;
if( cur == NULL )
{ // obj comes just after the head
obj->Timestamp -= remainingTime;
prev->Next = obj;
obj->Next = NULL;
}
else
{
aggregatedTimestamp = remainingTime;
aggregatedTimestampNext = remainingTime + cur->Timestamp;
while( prev != NULL )
{
if( aggregatedTimestampNext > obj->Timestamp )
{
obj->Timestamp -= aggregatedTimestamp;
if( cur != NULL )
{
cur->Timestamp -= obj->Timestamp;
}
prev->Next = obj;
obj->Next = cur;
break;
}
else
{
prev = cur;
cur = cur->Next;
if( cur == NULL )
{ // obj comes at the end of the list
aggregatedTimestamp = aggregatedTimestampNext;
obj->Timestamp -= aggregatedTimestamp;
prev->Next = obj;
obj->Next = NULL;
break;
}
else
{
aggregatedTimestamp = aggregatedTimestampNext;
aggregatedTimestampNext = aggregatedTimestampNext + cur->Timestamp;
}
}
}
}
}