#include "drv_timer.h" static struct drv_timer_t *timerHead; void drv_timer_start (struct drv_timer_t *timer) { ASSERT(timer != NULL); timer->start = 1; } void drv_timer_restart (struct drv_timer_t *timer) { ASSERT(timer != NULL); timer->start = 0; timer->time_temp = 0; timer->period = timer->period_temp; timer->start = 1; } void drv_timer_pause (struct drv_timer_t *timer) { ASSERT(timer != NULL); timer->start = 0; timer->time_temp = 0; return; } void drv_timer_detach (struct drv_timer_t *timer) { struct drv_timer_t **now_target; struct drv_timer_t *entry; ASSERT(timer != NULL); for (now_target = &timerHead; *now_target; ) { entry = *now_target; if (entry == timer) { *now_target = entry->next; return; } else { now_target = &entry->next; } } return; } static void drv_timer_attach (struct drv_timer_t *timer) { struct drv_timer_t *target; for (target = timerHead; target != NULL; target = target->next) { if (target == timer) { return; } } timer->next = timerHead; timerHead = timer; } // call in tick interrupt void drv_timer_handler (uint8_t ms) { struct drv_timer_t *timer; for (timer = timerHead; timer != NULL; timer = timer->next) { if (timer->start) { timer->time_temp += ms; if (timer->time_temp >= timer->timeout) { timer->time_temp = 0; if ((timer->type & TIMER_TYPE_HARDWARE) != 0) { if (timer->timerCallback) { timer->timerCallback(timer->user_data); } if ((timer->type & TIMER_ONE_SHOT) != 0) { --timer->period; if (timer->period == 0) { drv_timer_pause(timer); } } } else { timer->timeout_flag = 1; } } } } } void drv_timer_linkUserData (struct drv_timer_t *timer, void *user_data) { ASSERT(timer != NULL); timer->user_data = user_data; } void drv_timer_init (struct drv_timer_t *timer, void (*timerCallback)(void *user_data), uint32_t timeout, uint16_t period) { ASSERT(timer != NULL); timer->period = period; timer->timeout = timeout; timer->type = TIMER_TYPE_HARDWARE; timer->timerCallback = timerCallback; timer->time_temp = 0; timer->period_temp = period; if (period == 0) { timer->type |= TIMER_PERIODIC; } else { timer->type |= TIMER_ONE_SHOT; } drv_timer_attach(timer); }