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 TimerIrqHandler( void ) { TimerEvent_t* cur; TimerEvent_t* next; uint32_t old = HW_RTC_GetTimerContext( ); uint32_t now = HW_RTC_SetTimerContext( ); uint32_t DeltaContext = now - old; //intentionnal wrap around /* update timeStamp based upon new Time Reference*/ /* beacuse delta context should never exceed 2^32*/ if ( TimerListHead != NULL ) { for (cur=TimerListHead; cur->Next != NULL; cur= cur->Next) { next =cur->Next; if (next->Timestamp > DeltaContext) { next->Timestamp -= DeltaContext; } else { next->Timestamp = 0 ; } } } /* execute imediately the alarm callback */ if ( TimerListHead != NULL ) { cur = TimerListHead; TimerListHead = TimerListHead->Next; exec_cb( cur->Callback ); } // remove all the expired object from the list while( ( TimerListHead != NULL ) && ( TimerListHead->Timestamp < HW_RTC_GetTimerElapsedTime( ) )) { cur = TimerListHead; TimerListHead = TimerListHead->Next; exec_cb( cur->Callback ); } /* start the next TimerListHead if it exists AND NOT running */ if(( TimerListHead != NULL ) && (TimerListHead->IsRunning == false)) { TimerSetTimeout( TimerListHead ); } }
static void TimerInsertNewHeadTimer( TimerEvent_t *obj ) { TimerEvent_t* cur = TimerListHead; if( cur != NULL ) { cur->IsRunning = false; } obj->Next = cur; TimerListHead = obj; TimerSetTimeout( TimerListHead ); }
void TimerInsertNewHeadTimer( TimerEvent_t *obj, uint32_t remainingTime ) { TimerEvent_t* cur = TimerListHead; if( cur != NULL ) { cur->Timestamp = remainingTime - obj->Timestamp; cur->IsRunning = false; } obj->Next = cur; obj->IsRunning = true; TimerListHead = obj; TimerSetTimeout( TimerListHead ); }
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( ); }
void TimerStop( TimerEvent_t *obj ) { BACKUP_PRIMASK(); DISABLE_IRQ( ); TimerEvent_t* prev = TimerListHead; TimerEvent_t* cur = TimerListHead; // List is empty or the Obj to stop does not exist if( ( TimerListHead == NULL ) || ( obj == NULL ) ) { RESTORE_PRIMASK( ); return; } if( TimerListHead == obj ) // Stop the Head { if( TimerListHead->IsRunning == true ) // The head is already running { if( TimerListHead->Next != NULL ) { TimerListHead->IsRunning = false; TimerListHead = TimerListHead->Next; TimerSetTimeout( TimerListHead ); } else { HW_RTC_StopAlarm( ); TimerListHead = NULL; } } else // Stop the head before it is started { if( TimerListHead->Next != NULL ) { TimerListHead = TimerListHead->Next; } else { TimerListHead = NULL; } } } else // Stop an object within the list { while( cur != NULL ) { if( cur == obj ) { if( cur->Next != NULL ) { cur = cur->Next; prev->Next = cur; } else { cur = NULL; prev->Next = cur; } break; } else { prev = cur; cur = cur->Next; } } } RESTORE_PRIMASK( ); }