#include "MultiTimer.h" #include #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); } } }