#include "base/define.h"
#include "timer_cfg.h"
#include "base/delay.h"
volatile Timerupdatefunc p_timer4update_func = NULL;


/*
@brief 发送时钟校准波形
@param pre_us 发送的周期
@param count 发送周期的个数
*/
static volatile uint16_t amend_plus_count = 0;

volatile TimerTriger p_timertriger = NULL;
void FireBus_ClkAmend(uint16_t pre_us,uint16_t trigger_us,uint16_t count,void *p_fun)
{
	
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;//定时器初始化结构
	TIM_OCInitTypeDef  TIM_OCInitStructure;//通道输出初始化结构
	NVIC_InitTypeDef NVIC_InitStructure;  
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE ); 
	p_timertriger = (TimerTriger)p_fun;
	amend_plus_count = count;
	NVIC_DisableIRQ(TIM3_IRQn);
		//TIM初始化
	TIM_TimeBaseStructure.TIM_Period = pre_us-1;        //周期0～FFFF
	TIM_TimeBaseStructure.TIM_Prescaler = 71 ;          //时钟分频
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;          //时钟分 1us
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//模式	
	TIM_TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);   //基本初始化	

	//TIM3通道初始化
	TIM_OCStructInit(& TIM_OCInitStructure);                                                //默认参数
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;                    //工作状态
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;         //设定为输出，需要PWM输出才需要这行代码
	TIM_OCInitStructure.TIM_Pulse = pre_us-trigger_us - 1;                   //占空长度
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low;                 //高电平

	TIM_OC1Init(TIM3, &TIM_OCInitStructure);  
	TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
	TIM_ClearFlag(TIM3,TIM_IT_CC1);
	TIM_ITConfig(TIM3, TIM_IT_CC1 , ENABLE);//使能CC1中断
	TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);
	TIM_ARRPreloadConfig(TIM3, ENABLE); 
	TIM_SetCompare3(TIM3,0);
	TIM_Cmd(TIM3, ENABLE); //开启定时器
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;         
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 9;     
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //TIM2全局中断使能   
  NVIC_ClearPendingIRQ(TIM3_IRQn);
  NVIC_Init(&NVIC_InitStructure);     
	
}

/*
使用轮询的方式检测校准结束
*/
void FireBus_ClkAmendCycle(void)
{
	//使用查询的方式，关闭中断
	NVIC_DisableIRQ(TIM3_IRQn);
	TIM_ITConfig(TIM3, TIM_IT_CC1 , DISABLE);//使能CC1中断
	TIM_ITConfig(TIM3,TIM_IT_Update,DISABLE);
	if(p_timertriger == NULL)
	{
		return;
	}
	__disable_irq();
	while(1)
	{
		uint8_t flag = 0;
		if( TIM_GetITStatus(TIM3,TIM_IT_Update))
		{
			if(amend_plus_count > 0)
				amend_plus_count--;
			flag = 1;
			p_timertriger(flag);
			TIM3->SR = 0;
		}else if(TIM_GetITStatus(TIM3,TIM_IT_CC1))
		{
			flag = 2;
			p_timertriger(flag);
			TIM3->SR = 0;
		}
		if(amend_plus_count == 0)
		{
			flag = 3;
			TIM_DeInit(TIM3);
			p_timertriger(flag);
			p_timertriger = NULL;
			break;
		}
	}
	__enable_irq();
}


void TIM3_IRQHandler()
{
	uint8_t flag = 0;
	rt_interrupt_enter();
	if( TIM_GetITStatus(TIM3,TIM_IT_Update))
	{
		if(amend_plus_count > 0)
			amend_plus_count--;
		flag = 1;
	}else if(TIM_GetITStatus(TIM3,TIM_IT_CC1))
	{
		flag = 2;
	}
	//timer_interrupt_flag_clear(TIMER2,TIMER_FLAG_UP|TIMER_FLAG_CH2|TIMER_FLAG_CH2O);
	TIM3->SR = 0;
	if(p_timertriger != NULL)
	{
		p_timertriger(flag);
	}
	if(amend_plus_count == 0)
	{
		flag = 3;
		NVIC_DisableIRQ(TIM3_IRQn);
		TIM_DeInit(TIM3);
		p_timertriger(flag);
		p_timertriger = NULL;
	}
	 rt_interrupt_leave();
}


/*
@brief 超时定时器,单位10ms
@param ms 最大可设置6553。
@param  pfunc 超时回调函数，注意回调函数中不能做长延时任务
*/
void RunTimeOut_Timer(uint16_t ms,Timerupdatefunc pfunc )
{
	NVIC_InitTypeDef NVIC_InitStructure;  
	//定时器初始化数据结构定义
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE );
	p_timer4update_func = pfunc;
	ms = ms*2-1;
	
	NVIC_DisableIRQ(TIM1_UP_IRQn);
		//复位计数器
	TIM_DeInit(TIM1);							
	TIM_TimeBaseStructure.TIM_Period           = ms;		//计数上限，100*100us = 10000us = 10ms
	TIM_TimeBaseStructure.TIM_Prescaler        = 36000-1;//2K;	//预分频72MHz主频，分频后时钟周期0.5ms
	TIM_TimeBaseStructure.TIM_ClockDivision    = TIM_CKD_DIV1;  //不分频
	TIM_TimeBaseStructure.TIM_CounterMode      = TIM_CounterMode_Up;  //向上计数
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	//初始化
	TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
	//清中断
  TIM_ClearFlag(TIM1, TIM_FLAG_Update);
	TIM_ITConfig(TIM1,TIM_IT_Update,ENABLE);
	
	//定时器清零
	TIM_SetCounter(TIM1,0);
	
	TIM_ARRPreloadConfig(TIM1, DISABLE);
	
	//定时器启动	
  TIM_Cmd(TIM1,ENABLE);
	
	NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQn;         
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 10;     
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;      //TIM2全局中断使能   
	NVIC_ClearPendingIRQ(TIM1_UP_IRQn);
  NVIC_Init(&NVIC_InitStructure);     
}


//停止超时定时器计数
void RunTimeoutStop(void)
{
	TIM_DeInit(TIM1);			
}
//获取超时定时器计数值
uint16_t GetRunTimeOutCount(void)
{
	return TIM1->CNT;
}

void TIM1_UP_IRQHandler()
{
//	uint8_t flag = 0;
	rt_interrupt_enter();
	if(TIM_GetITStatus(TIM1,TIM_IT_Update))
	{
		if(p_timer4update_func != NULL)
		{
			TIM_Cmd(TIM1,DISABLE);	
			p_timer4update_func();
			
		}
	}
	TIM1->SR = 0x00;
	rt_interrupt_leave();

}
/*
延时定时器初始化，单次向上计数
*/
void DelayTimer_Init(void)
{
	//定时器初始化数据结构定义
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
	TIM_DeInit(TIM2);
	
	TIM_TimeBaseStructure.TIM_Period           = 0xFFFF;		//计数上限，100*100us = 10000us = 10ms
	TIM_TimeBaseStructure.TIM_Prescaler        = 7200-1;	//预分频48,48MHz主频，分频后时钟周期1us
	TIM_TimeBaseStructure.TIM_ClockDivision    = TIM_CKD_DIV1;  //不分频
	TIM_TimeBaseStructure.TIM_CounterMode      = TIM_CounterMode_Up;  //向上计数
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	
	TIM_ARRPreloadConfig(TIM2, DISABLE);
	//初始化
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
	StartDelayTime();
}
/*
延时定时器初始化，单次向上计数
*/
void TimerCount_Init(void)
{
		//定时器初始化数据结构定义
	TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
	TIM_DeInit(TIM2);
	
	TIM_TimeBaseStructure.TIM_Period           = 0xFFFF;		//计数上限，100*100us = 10000us = 10ms
	TIM_TimeBaseStructure.TIM_Prescaler        = 7200-1;	//预分频48,48MHz主频，分频后时钟周期1us
	TIM_TimeBaseStructure.TIM_ClockDivision    = TIM_CKD_DIV1;  //不分频
	TIM_TimeBaseStructure.TIM_CounterMode      = TIM_CounterMode_Up;  //向上计数
	TIM_TimeBaseStructure.TIM_RepetitionCounter=0;
	
	TIM_ARRPreloadConfig(TIM2, DISABLE);
	//初始化
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
}
/*
@brief 重启延时定时器
*/
void StartDelayTime()
{
	TIM_Cmd(TIM2,DISABLE);
	TIM2->CNT = 0;
	TIM2->PSC = (uint32_t)7200-1;//10K 0.1ms
	TIM2->EGR |= TIM_EventSource_Update;
	TIM2->SR = 0;
	TIM_Cmd(TIM2,ENABLE);
	
}
/*
@brief 定时器是否运行到大于当前值
@param  当前比较值
*/
uint8_t isDelayEnd(uint16_t wait_time)
{
	if((TIM2->CNT > wait_time) && (TIM2->SR > 0) )
		return 0;
	return 1;
}
/* 
@breif 等待定时器计数值大于设定值
@param 等待定时器的结束值，单位0.1ms
*/
void WaitDelayEnd(uint16_t wait_time)
{
	while((TIM2->CNT  < wait_time) && (TIM2->SR < 1))
	{
		
	}
}
/*
@brief 获取当前定时器计数值，单位1us。并重启计数
@rtv   返回上次的计数值
*/
uint16_t Get1usCount(void)
{
	uint16_t us_value ;
	if(TIM2->SR > 0)
	{
		us_value = 65535;
	}else{
		us_value = TIM2->CNT;
	}
	
	TIM_Cmd(TIM2,DISABLE);
	TIM2->CNT = 0;
	TIM2->PSC = (uint32_t)71;//1M 1us
	TIM2->EGR |= TIM_EventSource_Update;
	TIM2->SR = 0;
	TIM_Cmd(TIM2,ENABLE);
	return us_value;
}

/*
@brief 获取当前定时器计数值，单位10us。并重启计数
@rtv   返回上次的计数值
*/
uint16_t Get10usCount(void)
{
	
	uint16_t us_value ;
	if(TIM2->SR > 0)
	{
		us_value = 65535;
	}else{
		us_value = TIM2->CNT;
	}
	
	TIM_Cmd(TIM2,DISABLE);
	TIM2->CNT = 0;
	TIM2->PSC = (uint32_t)720-1;//100K 10us
	TIM2->EGR |= TIM_EventSource_Update;
	TIM2->SR = 0;
	TIM_Cmd(TIM2,ENABLE);
	return us_value;
	
	

	
}

/*
@brief 获取当前定时器计数值，单位0.1ms。并重启计数
@rtv   返回上次的计数值
*/
uint16_t Get100usCount(void)
{
	
	uint16_t us_value ;
	if(TIM2->SR > 0)
	{
		us_value = 65535;
	}else{
		us_value = TIM2->CNT;
	}
	
	TIM_Cmd(TIM2,DISABLE);
	TIM2->CNT = 0;
	TIM2->PSC = (uint32_t)7200-1;//10K 100us
	TIM2->EGR |= TIM_EventSource_Update;
	TIM2->SR = 0;
	TIM_Cmd(TIM2,ENABLE);
	return us_value;
	
	
}

/*
@brief 直接获取定时器的值
*/
uint16_t GetCountTimerCnt()
{
	return TIM2->CNT;
}



void TimerCount_Off(void)
{
	TIM_Cmd(TIM2,DISABLE);
	TIM2->CNT = 0;
	TIM2->PSC = (uint32_t)7200-1;//10K 0.1ms
	TIM2->EGR |= TIM_EventSource_Update;
	TIM2->SR = 0;
}


