/**
 * @file hv_vos_Timer.c
 * @brief vos timer source code
 * @details 
 * @author HiView SoC Software Team
 * @version 0.0.1
 * @date 20230301
 * @copyright Copyright(c),2023-3, Hiview Software. All rights reserved.
 * @par History: 
 * <table>
 * <tr><th>author                     <th>date           <th>description
 * <tr><td>HiView SoC Software Team   <td>20230301       <td>Create and first Version.
 * </table>
**/

#include "hv_vos_Comm.h"
#include "FreeRTOS.h"
#include "timers.h"
#include "hv_vos_Timer.h"

struct _HV_TIMER_S{
    TimerHandle_t handler;
};

static void TimerCallback(TimerHandle_t hTimer)
{
    TimerCallback_t *callb;
    callb = (TimerCallback_t *)pvTimerGetTimerID(hTimer);
    if (callb != NULL)
    {
        callb->func(callb->arg, callb->usTimerEvent);
    }
    return;
}

HV_TIMER_S* Hv_Vos_Timer_Create(HV_TIMER_INIT_PARAMS *param)
{
    TimerCallback_t *callb;
    callb = HV_MALLOC_OBJECT(TimerCallback_t);
    if(NULL == callb)
    {
        return NULL;
    }
    else
    {
      callb->func = param->callbackFn;
      callb->arg  = param->callbackArg;
      callb->usTimerEvent = param->usTimerEvent;
    }
    TimerHandle_t handler = xTimerCreate( param->name,
                      pdMS_TO_TICKS(param->periodMs),
                      param->reload ? pdHV_TRUE : pdHV_FALSE,
                      callb,
                      TimerCallback);
    if(NULL == handler)
    {
        return NULL;
    }
    HV_TIMER_S *pstTimer = HV_MALLOC_OBJECT(HV_TIMER_S);
    if(NULL == pstTimer)
    {
        return NULL;
    }
    pstTimer->handler = handler;
    return pstTimer;
}

void Hv_Vos_Timer_Delete(HV_TIMER_S *pstTimer)
{
    /*释放timer create申请的callb内存*/
    TimerCallback_t *callb = (TimerCallback_t *)pvTimerGetTimerID(pstTimer->handler);
    HV_FREE_OBJECT(callb);

    xTimerDelete(pstTimer->handler, 0);
    HV_FREE_OBJECT(pstTimer);

    return;
}

BOOL Hv_Vos_Timer_Start(HV_TIMER_S *pstTimer)
{
    BaseType_t ret = xTimerStart(pstTimer->handler, 0);
    return ret == pdPASS;
}

BOOL Hv_Vos_Timer_Stop(HV_TIMER_S *pstTimer)
{
    BaseType_t ret;
    ret = xTimerStop(pstTimer->handler, 0);
    return ret == pdPASS;
}

BOOL Hv_Vos_Timer_IsTimerActive(HV_TIMER_S *pstTimer)
{
    BaseType_t ret;
    ret = xTimerIsTimerActive(pstTimer->handler);
    return ret != pdHV_FALSE;
}

BOOL Hv_Vos_Timer_ChangePeriod(HV_TIMER_S *pstTimer, UINT32 periodMs)
{
    BaseType_t ret;
    ret = xTimerChangePeriod(pstTimer->handler, pdMS_TO_TICKS(periodMs), portMAX_DELAY);
    return ret == pdPASS;
}

BOOL Hv_Vos_Timer_Rstart(HV_TIMER_S *pstTimer, UINT32 uiPeriodMs)
{    
    if (NULL == pstTimer) 
    {
        HV_LOG_INFO(DEFAULT,"rstart timer check null!!");
        return HV_FALSE;
    } 
    if (Hv_Vos_Timer_IsTimerActive(pstTimer))
    {
        Hv_Vos_Timer_Stop(pstTimer);
    }
    if(0 != uiPeriodMs)
    {
        Hv_Vos_Timer_ChangePeriod(pstTimer, uiPeriodMs);
    }
    Hv_Vos_Timer_Start(pstTimer);
    return HV_TRUE;
}

BOOL Hv_Vos_Timer_Rstop(HV_TIMER_S *pstTimer)
{    
    if (NULL == pstTimer) 
    {
        HV_LOG_INFO(DEFAULT,"rstop timer check null!!");
        return HV_FALSE;
    }
    if (Hv_Vos_Timer_IsTimerActive(pstTimer))
    {
        Hv_Vos_Timer_Stop(pstTimer);
    }
    return HV_TRUE;
}

