
#include "timer.h"



//客户需要适配此TIMER_GET_TICK()  API，要求返回以1ms为周期的uint32_t型systick当前值，可以参考STM32的HAL_GetTick();
//客户需要持续调用TimerService()才能保证软定时器回调功能（DelayMs()函数不受此影响）。

#define TIMER_GET_TICK() HAL_GetTick()  


static uint32_t systick_local;

static TimerEvent_t timer_head_ptr;

void TimerInit( TimerEvent_t *obj, void ( *callback )( void *context ) )
{
    TimerEvent_t *p_mov;
    p_mov = &timer_head_ptr;
    if (obj == NULL)
        return;
    if (callback == NULL)
        return;
		obj->ReloadValue = 0;
    obj->IsStarted = false;
    obj->IsNext2Expire = false;
    obj->Callback = callback;
    obj->Context = NULL;
    obj->Next = NULL;
    while (p_mov->Next != NULL)
    {
        p_mov = p_mov->Next;
    }
    p_mov->Next = obj;
}

void TimerSetValue( TimerEvent_t *obj, uint32_t value )
{
    if (obj != NULL)
    {
				obj->IsStarted = false;
        obj->ReloadValue = value;
    }
}

void TimerStart( TimerEvent_t *obj )
{
    if (obj != NULL)
    {
        if (obj->IsStarted == false)
        {
            obj->Timestamp = TIMER_GET_TICK();
            obj->IsStarted = true;
        }
    }
}

void TimerStop( TimerEvent_t *obj )
{
    if (obj != NULL)
    {
        obj->IsStarted = false;
    }
}

void TimerService( void )
{
    if (systick_local == TIMER_GET_TICK())
        return;
    if (timer_head_ptr.Next == NULL)
        return;
    systick_local = TIMER_GET_TICK();

    TimerEvent_t *timer_mov_ptr = timer_head_ptr.Next;
    while (1)
    {
        if (timer_mov_ptr->IsStarted == true)
        {
            if (TIMER_GET_TICK() - timer_mov_ptr->Timestamp >= timer_mov_ptr->ReloadValue)
            {
                timer_mov_ptr->IsStarted = false;
                if (timer_mov_ptr->Callback != NULL)
                    timer_mov_ptr->Callback(timer_mov_ptr->Context);
            }
        }
        if (timer_mov_ptr->Next != NULL)
        {
            timer_mov_ptr = timer_mov_ptr->Next;
        }
        else
        {
            break;
        }
    }
}
void DelayMs( uint32_t ms )
{
    uint32_t timer_start = TIMER_GET_TICK();
    while (TIMER_GET_TICK()- timer_start < ms)
    {
			//wait
    }
}
TimerTime_t TimerGetCurrentTime( void )
{
    return TIMER_GET_TICK();
}
TimerTime_t TimerGetElapsedTime( TimerTime_t past )
{
	return TIMER_GET_TICK() - past;
}

