void TimerIrqHandler( void ) { uint32_t elapsedTime = 0; if( LowPowerModeEnable == false ) { if( TimerListHead == NULL ) { return; // Only necessary when the standard timer is used as a time base } } elapsedTime = TimerGetValue( ); TimerEvent_t* elapsedTimer = NULL; if( elapsedTime > TimerListHead->Timestamp ) { TimerListHead->Timestamp = 0; } else { TimerListHead->Timestamp -= elapsedTime; } // save TimerListHead elapsedTimer = TimerListHead; // remove all the expired object from the list while( ( TimerListHead != NULL ) && ( TimerListHead->Timestamp == 0 ) ) { if( TimerListHead->Next != NULL ) { TimerListHead = TimerListHead->Next; } else { TimerListHead = NULL; } } // execute the callbacks of all the expired objects // this is to avoid potential issues between the callback and the object list while( ( elapsedTimer != NULL ) && ( elapsedTimer->Timestamp == 0 ) ) { if( elapsedTimer->Callback != NULL ) { elapsedTimer->Callback( ); } elapsedTimer = elapsedTimer->Next; } // start the next TimerListHead if it exists if( TimerListHead != NULL ) { TimerListHead->IsRunning = true; TimerSetTimeout( TimerListHead ); } }
void TimerStart( TimerEvent_t *obj ) { uint32_t elapsedTime = 0; uint32_t remainingTime = 0; __disable_irq( ); if( ( obj == NULL ) || ( TimerExists( obj ) == true ) ) { __enable_irq( ); return; } obj->Timestamp = obj->ReloadValue; obj->IsRunning = false; if( TimerListHead == NULL ) { TimerInsertNewHeadTimer( obj, obj->Timestamp ); } else { if( TimerListHead->IsRunning == true ) { elapsedTime = TimerGetValue( ); if( elapsedTime > TimerListHead->Timestamp ) { elapsedTime = TimerListHead->Timestamp; // security but should never occur } remainingTime = TimerListHead->Timestamp - elapsedTime; } else { remainingTime = TimerListHead->Timestamp; } if( obj->Timestamp < remainingTime ) { TimerInsertNewHeadTimer( obj, remainingTime ); } else { TimerInsertTimer( obj, remainingTime ); } } __enable_irq( ); }
void TimerStop( TimerEvent_t *obj ) { __disable_irq( ); uint32_t elapsedTime = 0; uint32_t remainingTime = 0; TimerEvent_t* prev = TimerListHead; TimerEvent_t* cur = TimerListHead; // List is empty or the Obj to stop does not exist if( ( TimerListHead == NULL ) || ( obj == NULL ) ) { return; } if( TimerListHead == obj ) // Stop the Head { if( TimerListHead->IsRunning == true ) // The head is already running { elapsedTime = TimerGetValue( ); if( elapsedTime > obj->Timestamp ) { elapsedTime = obj->Timestamp; } remainingTime = obj->Timestamp - elapsedTime; if( TimerListHead->Next != NULL ) { TimerListHead->IsRunning = false; TimerListHead = TimerListHead->Next; TimerListHead->Timestamp += remainingTime; TimerListHead->IsRunning = true; TimerSetTimeout( TimerListHead ); } else { TimerListHead = NULL; } } else // Stop the head before it is started { if( TimerListHead->Next != NULL ) { remainingTime = obj->Timestamp; TimerListHead = TimerListHead->Next; TimerListHead->Timestamp += remainingTime; } else { TimerListHead = NULL; } } } else // Stop an object within the list { remainingTime = obj->Timestamp; while( cur != NULL ) { if( cur == obj ) { if( cur->Next != NULL ) { cur = cur->Next; prev->Next = cur; cur->Timestamp += remainingTime; } else { cur = NULL; prev->Next = cur; } break; } else { prev = cur; cur = cur->Next; } } } __enable_irq( ); }