You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.5 KiB
C
87 lines
2.5 KiB
C
#include "MultiTimer.h"
|
|
#include <stdio.h>
|
|
|
|
#define MULTIMER_MAX_TIMEOUT 0x7fffffff
|
|
|
|
/* Check if timer's expiry time is greater than time and care about uint32_t wraparounds */
|
|
#define CHECK_TIME_LESS_THAN(t, compare_to) ( (((uint32_t)((t)-(compare_to))) > MULTIMER_MAX_TIMEOUT) ? 1 : 0 )
|
|
|
|
/* Timer handle list head. */
|
|
static MultiTimer* timerList = NULL;
|
|
|
|
/* Timer tick */
|
|
static PlatformTicksFunction_t platformTicksFunction = NULL;
|
|
|
|
int MultiTimerInstall(PlatformTicksFunction_t ticksFunc)
|
|
{
|
|
platformTicksFunction = ticksFunc;
|
|
return 0;
|
|
}
|
|
|
|
int MultiTimerStart(MultiTimer* timer, uint32_t timing, MultiTimerCallback_t callback, void* userData)
|
|
{
|
|
if (!timer || !callback || timing > MULTIMER_MAX_TIMEOUT / 2 ) {
|
|
return -1;
|
|
}
|
|
MultiTimer** nextTimer = &timerList;
|
|
/* Remove the existing target timer. */
|
|
for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
|
|
if (timer == *nextTimer) {
|
|
*nextTimer = timer->next; /* remove from list */
|
|
break;
|
|
}
|
|
}
|
|
|
|
/* Init timer. */
|
|
timer->deadline = platformTicksFunction() + timing;
|
|
timer->callback = callback;
|
|
timer->userData = userData;
|
|
|
|
/* Insert timer. */
|
|
for (nextTimer = &timerList;; nextTimer = &(*nextTimer)->next) {
|
|
if (!*nextTimer) {
|
|
timer->next = NULL;
|
|
*nextTimer = timer;
|
|
break;
|
|
}
|
|
if (timer->deadline < (*nextTimer)->deadline) {
|
|
timer->next = *nextTimer;
|
|
*nextTimer = timer;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int MultiTimerStop(MultiTimer* timer)
|
|
{
|
|
MultiTimer** nextTimer = &timerList;
|
|
/* Find and remove timer. */
|
|
for (; *nextTimer; nextTimer = &(*nextTimer)->next) {
|
|
MultiTimer* entry = *nextTimer;
|
|
if (entry == timer) {
|
|
*nextTimer = timer->next;
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int MultiTimerYield(void)
|
|
{
|
|
MultiTimer* entry = timerList;
|
|
for (; entry; entry = entry->next) {
|
|
/* Sorted list, just process with the front part. */
|
|
if (CHECK_TIME_LESS_THAN(platformTicksFunction(), entry->deadline)) {
|
|
return (int)(entry->deadline - platformTicksFunction());
|
|
}
|
|
/* remove expired timer from list */
|
|
timerList = entry->next;
|
|
|
|
/* call callback */
|
|
if (entry->callback) {
|
|
entry->callback(entry, entry->userData);
|
|
}
|
|
}
|
|
}
|