1
0
Fork 0
InfiniSim/sim/timers.cpp
Reinhold Gschweicher 3cc6e74ea1 sim/timers: implement xTimerGetExpiryTime, xTimerIsActive, more accurate
Implement the missing functions `xTimerGetExpiryTime()` and `xTimerIsActive()`
for the move of `TimerController` to use FreeRTOS timers.

In the process also fix a slight inaccuracy in the ms to ticks
conversion (no conversion was done as 1000 was close enough to 1024 for
a first working implementation).

Fixes: https://github.com/InfiniTimeOrg/InfiniSim/issues/17
2022-03-29 22:41:09 +02:00

79 lines
2.4 KiB
C++

#include "timers.h"
#include <stdexcept>
uint32_t timer_callback_wrapper(uint32_t interval, void *param) {
TimerHandle_t *xTimer = static_cast<TimerHandle_t*>(param);
if (!xTimer->running) {
return 0;
}
xTimer->pxCallbackFunction(*xTimer);
if (xTimer->auto_reload) {
return xTimer->timer_period_in_ms;
}
xTimer->running = false;
return 0; // cancel timer
}
void *pvTimerGetTimerID(const TimerHandle_t &xTimer) { // return pvTimerID from xTimerCreate
return xTimer.pvTimerID;
}
void vTimerSetTimerID(TimerHandle_t &xTimer, void *pvNewID) {
xTimer.pvTimerID = pvNewID;
}
TimerHandle_t xTimerCreate(const char * const pcTimerName, /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
const TickType_t xTimerPeriodInTicks,
const UBaseType_t uxAutoReload, // false=one-shot, true=recurring
void * const pvTimerID, // pointer passed to callback
TimerCallbackFunction_t pxCallbackFunction)
{
TimerHandle_t xTimer;
xTimer.timer_period_in_ms = pdTICKS_TO_MS(xTimerPeriodInTicks);
xTimer.auto_reload = uxAutoReload == pdTRUE;
xTimer.timer_name = pcTimerName;
xTimer.pvTimerID = pvTimerID;
xTimer.pxCallbackFunction = pxCallbackFunction;
return xTimer;
}
bool xTimerStart(TimerHandle_t &xTimer, TickType_t xTicksToWait) {
xTimer.running = true;
xTimer.expiry_time = xTaskGetTickCount() + pdMS_TO_TICKS(xTimer.timer_period_in_ms);
xTimer.timer_id = SDL_AddTimer(xTimer.timer_period_in_ms, timer_callback_wrapper, &xTimer);
if (xTimer.pxCallbackFunction == nullptr) {
throw std::runtime_error("xTimerStart called before xTimerCreate");
}
return xTimer.timer_id != 0;
}
bool xTimerChangePeriod(TimerHandle_t &xTimer, TickType_t xNewPeriod, TickType_t xTicksToWait) {
if (xTimer.running) {
xTimerStop(xTimer, xTicksToWait);
xTimer.timer_period_in_ms = pdTICKS_TO_MS(xNewPeriod);
xTimerStart(xTimer, xTicksToWait);
} else {
xTimer.timer_period_in_ms = pdTICKS_TO_MS(xNewPeriod);
}
return true;
}
bool xTimerReset(TimerHandle_t &xTimer, TickType_t xTicksToWait) {
if (xTimer.running) {
xTimerStop(xTimer, xTicksToWait);
}
return xTimerStart(xTimer, xTicksToWait);
}
bool xTimerStop(TimerHandle_t &xTimer, TickType_t xTicksToWait) {
xTimer.running = false;
return SDL_RemoveTimer(xTimer.timer_id);
}
TickType_t xTimerGetExpiryTime( TimerHandle_t xTimer )
{
return xTimer.expiry_time;
}
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer ) {
return xTimer.running;
}