#include "timer.h"
#include "tim.h"

extern TIM_HandleTypeDef htim3;
static int g_timer_working = 0;

static timeout_func g_timeout_func = NULL;
static u_int32_t g_timeout_param = 0;


/**
  * @brief  设置定时器
  * @param  timeout_ms 设置超时时间
  * @param  func 
  */
void set_timeout(u_int32_t timeout_ms, timeout_func func, u_int32_t param)
{   
    stop_timout();

    if(timeout_ms){
      g_timeout_func = func;
      g_timeout_param = param;
      
      // 重装周期
    __HAL_TIM_SET_AUTORELOAD(&htim3, timeout_ms);
    
    start_timout();
    }
}

/**
  * @brief  延时指定的毫秒数
  * @param  param 
  */
void flag_timeout_callback(u_int32_t param)
{
  *((u_int32_t *)param) = 1;
}

/**
  * @brief 本函数使用定时器,在定时器超时时,将flag_addr中的内容置为1,用于简单的超时标志
  * @param  timeout_ms 
  * @param  flag_addr
  */
void set_flag_timeout(u_int32_t timeout_ms, u_int32_t *flag_addr)
{
  set_timeout(timeout_ms, flag_timeout_callback, (u_int32_t)flag_addr);
}

/**
  * @brief 停止定时器,等效于set_timeout(0,NULL,0)
  */
void stop_timout()
{ 
  if(g_timer_working){
    HAL_TIM_Base_Stop_IT(&htim3);  //停止定时器
    g_timer_working = 0;
  }
}

/**
  * @brief 启动定时器
  */
void start_timout()
{ 
  if(!g_timer_working){
    HAL_TIM_Base_Start_IT(&htim3);  //停止定时器
    g_timer_working = 1;
  }
}


/**
  * @brief  延时指定的毫秒数
  * @param  time_ms
  */
void delay_ms(u_int32_t time_ms)
{
    u_int32_t timeout_flag = 0;
    
    set_flag_timeout(time_ms, &timeout_flag);
    while(!timeout_flag);
}

/**
  * @brief  定制器中断回调函数
  * @brief  htim
  */
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  if(htim->Instance == TIM3){
     if(g_timeout_func){
       (*g_timeout_func)(g_timeout_param);
      }
  }
}