/* * Copyright (c) 2016 Zibin Zheng * All rights reserved */ #include "multi_timer.h" //timer handle list head. static struct Timer* head_handle = NULL; //Timer ticks //static uint32_t _timer_ticks = 0; static uint16_t _timer_ticks = 0; /** * @brief Initializes the timer struct handle. * @param handle: the timer handle strcut. * @param timeout_cb: timeout callback. * @param repeat: repeat interval time. * @retval None */ void timer_init_Head ( void ) { head_handle = NULL; } void timer_init ( struct Timer* handle, void ( *timeout_cb ) (), uint32_t timeout, uint32_t repeat ) { // memset(handle, 0, sizeof(struct Timer)); handle->timeout_cb = timeout_cb; handle->timeout = _timer_ticks + timeout; handle->repeat = repeat; } void timer_app ( struct Timer* handle, void ( *timeout_cb ) (), uint32_t timeout, uint32_t repeat ) { timer_init ( handle, timeout_cb, timeout, repeat ); timer_start ( handle ); } /** * @brief Start the timer work, add the handle into work list. * @param btn: target handle strcut. * @retval 0: succeed. -1: already exist. */ int timer_start ( struct Timer* handle ) { struct Timer* target = head_handle; while ( target ) { if ( target == handle ) return -1; //already exist. target = target->next; } handle->next = head_handle; head_handle = handle; return 0; } /** * @brief Stop the timer work, remove the handle off work list. * @param handle: target handle strcut. * @retval None */ void timer_stop ( struct Timer* handle ) { struct Timer** curr; for ( curr = &head_handle; *curr; ) { struct Timer* entry = *curr; if ( entry == handle ) { *curr = entry->next; // free(entry); } else curr = &entry->next; } } /** * @brief main loop. * @param None. * @retval None */ void timer_loop() { struct Timer* target; for ( target = head_handle; target; target = target->next ) { if ( ( ( target->timeout < TIMER_MAX ) && ( _timer_ticks >= target->timeout ) ) || \ ( ( target->timeout >= TIMER_MAX ) && ( _timer_ticks + TIMER_MAX >= target->timeout ) ) ) { if ( target->repeat == 0 ) //Ò»´ÎÐÔ { timer_stop ( target ); } else //Ñ­»· { target->timeout = _timer_ticks + target->repeat; } target->timeout_cb(); } } } /** * @brief background ticks, timer repeat invoking interval 1ms. * @param None. * @retval None. */ void timer_ticks() { _timer_ticks += TIMER_TICK; if ( _timer_ticks >= TIMER_MAX ) _timer_ticks = 0; }