#include "soft_timer.h" static soft_timer_t timers[MAX_TIMERS]; void stimer_init(void) { for (int i = 0; i < MAX_TIMERS; ++i) { timers[i].active = false; timers[i].inUse = false; } } void stimer_end(int timer_id) { if (timer_id >= 0 && timer_id < MAX_TIMERS) { timers[timer_id].active = false; timers[timer_id].inUse = false; } } int stimer_start(uint32_t timeout_ticks, timer_mode_t mode, timer_callback_t cb, void* ctx) { for (int i = 0; i < MAX_TIMERS; ++i) { if (!timers[i].inUse) { timers[i].timeout_ticks = timeout_ticks; timers[i].remaining_ticks = timeout_ticks; timers[i].mode = mode; timers[i].callback = cb; timers[i].callback_context = ctx; timers[i].inUse = true; timers[i].active = true; timers[i].fired = false; return i; } } return -1; // No free timer slot } void stimer_stop(int timer_id) { if (timer_id >= 0 && timer_id < MAX_TIMERS) { timers[timer_id].active = false; } } bool stimer_is_active(int timer_id) { return timer_id >= 0 && timer_id < MAX_TIMERS && timers[timer_id].active; } bool stimer_fired(int timer_id) { if (timer_id >= 0 && timer_id < MAX_TIMERS) { return timers[timer_id].fired; } return false; } bool stimer_clearFired(int timer_id) { if (timer_id >= 0 && timer_id < MAX_TIMERS) { timers[timer_id].fired = false; } } void stimer_update(void) { for (int i = 0; i < MAX_TIMERS; ++i) { if (timers[i].active && timers[i].remaining_ticks > 0) { timers[i].remaining_ticks--; if (timers[i].remaining_ticks == 0) { timers[i].fired = true; if (timers[i].callback) { timers[i].callback(timers[i].callback_context); } if (timers[i].mode == TIMER_MODE_PERIODIC) { timers[i].remaining_ticks = timers[i].timeout_ticks; } else { timers[i].active = false; timers[i].inUse = false; } } } } } // blocking delay void stimer_delay(uint32_t ticks) { int handle = stimer_start(ticks, TIMER_MODE_ONE_SHOT, 0, 0); while (!stimer_fired(handle)); }