/***********************************************************************
 * Copyright (c)  2017 - 2021, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : gtimer0.c
 * Description : gtimer0 driver source file
 * Author(s)   : shengyu
 * version     : V1.0
 * Modify date : 2021-12-30
 ***********************************************************************/
#include "gtimer.h"

void (*gtimer0_callback[3])(void) = { 0 };


/***********************************************************************
 * Function   	: GTIM0_IRQHandler
 * Description	: GTIM0 interrupt handling
 * Input 		: none
 * Output		: none   
 * Return		: none
 ***********************************************************************/
void GTIM0_IRQHandler(void) interrupt 21
{
	if((REG_GTIM0_SR & GTIMER0_UIF)  && (REG_GTIM0_IER & GTIMER0_UIE))		//UE中断
	{
		if(gtimer0_callback[0] != NULL)
		{
			gtimer0_callback[0]();
		}
		REG_GTIM0_SR = GTIMER0_UIF;						//清除UE中断标志
	}
	else if((REG_GTIM0_SR & GTIMER0_CCIF)  && (REG_GTIM0_IER & GTIMER0_CCIE))		//比较中断/捕捉中断
	{
		if(gtimer0_callback[1] != NULL)
		{
			gtimer0_callback[1]();
		}
		REG_GTIM0_SR = GTIMER0_CCIF;					//清除中断/捕捉中断
	}
	else if((REG_GTIM0_SR & GTIMER0_BKE_IF) && (REG_GTIM0_IER & GTIMER0_BKE_IE))			//刹车中断
	{
		if(gtimer0_callback[2] != NULL)
		{
			gtimer0_callback[2]();
		}
		REG_GTIM0_SR = GTIMER0_BKE_IF;			//清除刹车中断标志
	}
	else
	{
		REG_GTIM0_SR = 0x7;									//清除所有中断标志
	}
}  


/************************************************************************
 * Function   	: gtimer0_count_init
 * Description	: gtimer0_count_init GTIMER0 中断初始化
 * Input 		: uint8_t arr	GTIMER0重载值
							uint8_t psc GTIMER0分频值
 * Output 	: none
 * Return		: none
 ************************************************************************/	
void gtimer0_count_init(uint16_t arr,uint16_t psc)
{
	PCLK1 |= (1<<3); 									  //开Gtim0时钟使能 	
	PRESET1 |= (1<<3);									//GTim0正常工作
	
	REG_GTIM0_CR0 |= (1<<6);						//使能auto-repload 

	REG_GTIM0_PSC1 = (psc>>8)&0xFF;			//高8位 FCK_CNT=FCK_PSC/(PSC[15:0]+1);  FCK_PSC = APBCLK 
	REG_GTIM0_PSC0 = psc&0xFF;					//低8位 FCK_CNT=FCK_PSC/(PSC[15:0]+1);  FCK_PSC = APBCLK 
	
	REG_GTIM0_ARR1 = ((arr-1)>>8)&0xFF;			//高8位 自动装载值
	REG_GTIM0_ARR0 = (arr-1)&0xFF;					//低8位 自动装载值
	
	REG_GTIM0_EGR = 0x1;								//产生UE事件，将PSC的值立即载入shadow寄存器
	REG_GTIM0_SR |= (1<<0);							//清除UE产生的中断，否则会直接进入中断服务函数
	
}


/************************************************************************
 * Function   	: gtimer0_pwm_init
 * Description	: gtimer0_pwm_init GTIMER0 中断初始化
 * Input 		: uint16_t arr	GTIMER0重载值
							uint16_t psc  GTIMER0分频值
							uint16_t ccr  GTIMER0比较值
 * Output 	: none
 * Return		: none
 ************************************************************************/	
void gtimer0_pwm_init(uint16_t arr, uint16_t psc, uint16_t ccr)
{
	PCLK1 |= (1<<3); 									  //开Gtim0时钟使能 
	PRESET1 |= (1<<3);									//GTim0正常工作 
	
	REG_P13_CFG = 0x06;									//P13 CH 
	REG_P15_CFG = 0x04;									//P15 CH 
//	REG_P25_CFG = 0x04;								//P25 CH 
	
	REG_P14_CFG = 0x05;									//P14 CHN
	REG_P20_CFG = 0x06;									//P20 CHN
//	REG_P23_CFG = 0x05;								//P23 CHN 
	
	REG_GTIM0_CR0 |= (1<<6);						//使能auto-repload 
	
	REG_GTIM0_PSC1 = (psc>>8)&0xFF;			//高8位 FCK_CNT=FCK_PSC/(PSC[15:0]+1);  FCK_PSC = APBCLK 
	REG_GTIM0_PSC0 = psc&0xFF;					//低8位 FCK_CNT=FCK_PSC/(PSC[15:0]+1);  FCK_PSC = APBCLK 
	
	REG_GTIM0_ARR1 = ((arr-1)>>8)&0xFF;			//高8位 自动装载值 
	REG_GTIM0_ARR0 = (arr-1)&0xFF;					//低8位 自动装载值 
	
	REG_GTIM0_ARRN1 = ((arr-1)>>8)&0xFF;		//高8位 自动装载值 
	REG_GTIM0_ARRN0 = (arr-1)&0xFF;					//低8位 自动装载值 
				
	REG_GTIM0_CCR1 = ((ccr)>>8)&0xFF;		//高8位 比较寄存器 
	REG_GTIM0_CCR0 = (ccr)&0xFF;					//低8位 比较寄存器 
				
	REG_GTIM0_CCRN1 = ((ccr)>>8)&0xFF;	//高8位 比较寄存器
	REG_GTIM0_CCRN0 = (ccr)&0xFF;				//低8位 比较寄存器
				
	REG_GTIM0_CR1 |= (1<<0);						//互补PWM和原PWM反相位
				
	REG_GTIM0_CR1 |= (1<<1);						//避免死区功能使能
				
	REG_GTIM0_EGR = 0x1;								//产生UE事件，将PSC的值立即载入shadow寄存器
	REG_GTIM0_SR |= (1<<0);							//清除UE产生的中断，否则会直接进入中断服务函数
	
	REG_GTIM0_CR2 |= (1<<2);						//输出总使能
	
	REG_GTIM0_CCER |= (1<<0);						//使能输出
	
	
}

/***********************************************************************
 * Function   	: gtimer0_capture_init
 * Description	: gtimer0_capture_init GTIMER0输入捕获
 * Input 		: uint16_t arr          装载值
 * 					: uint8_t capture_div   捕捉源预分频位
 * 					: uint8_t capssel  			捕捉源选择位
 * Output		: none
 * Return		: none
 ***********************************************************************/
void gtimer0_capture_init(uint16_t arr,uint8_t capture_div,uint8_t capssel)
{
	PCLK1 |= (1<<3); 									  	//开Gtim0时钟使能
	PRESET1 |= (1<<3);										//GTim0正常工作
		
	REG_P13_CFG = 0x06;										//P13 GTIMER0_CH 

	REG_GTIM0_ARR1 = ((arr-1)>>8)&0xFF;				//高8位 自动装载值 
	REG_GTIM0_ARR0 = (arr-1)&0xFF;						//低8位 自动装载值 
		
	REG_GTIM0_CCMR0 &= ~(1<<7);						//外部计数源滤波使能：无滤波功能 
	REG_GTIM0_CCMR0 |= (1<<0);						//配置CCS为输入 
	
	REG_GTIM0_CCMR1 = (REG_GTIM0_CCMR1&(~(0x03<<0)))|(capssel<<0);			//捕捉源选择位 	

	REG_GTIM0_CCMR1 = (REG_GTIM0_CCMR1&(~(3<<5)))|(capture_div<<5);	//分频配置
		
	REG_GTIM0_CCMR1 &= ~(0x03<<2);				//捕获沿触发控制位：上升沿触发 
		
	REG_GTIM0_CCER |= (1<<0);							//使能捕捉功能 
	
}

void gtimer0_bke_init(void)
{
	PCLK1 |= (1<<3); 								//开Gtim0时钟使能 	
	PRESET1 |= (1<<3);							//GTim0正常工作 

	REG_P01_CFG = 0x05;							//P01 GTIMER0_BKE 
//	REG_P22_CFG = 0x05;							//P22 GTIMER0_BKE 	
//	REG_P25_CFG = 0x05;							//P25 GTIMER0_BKE 
	
	REG_GTIM0_CR1 &= ~(3<<6);				//PWM刹车触发后，PWM正向电平状态设置位:低电平 
	REG_GTIM0_CR2 &= ~(3<<0);				// PWM刹车触发后，PWM互补电平状态设置位:低电平 

	REG_GTIM0_CR1 &= ~(1<<3);				//刹车信号高电平有效
	
	REG_GTIM0_CR1 |= (1<<2);				//使能刹车功能 

	REG_GTIM0_CCER |= (1<<0);				//使能输出 
}

/************************************************************************
 * Function   	: gtimer0_irq_init
 * Description	: gtimer0_irq_init 	GTIMER0 中断初始化
 * Input 		: uint8_t irq_enable		GTIMER0中断使能开关 1：使能 0：禁止
 *						uint8_t gtimer_irq_type GTIMER0中断类型选择
 *            void (*pfunc)()					GTIMER0中断回调函数
 * Output 	: none
 * Return		: none
 ************************************************************************/	
void gtimer0_irq_init(uint8_t irq_enable,uint8_t gtimer_irq_type,void (*pfunc)())
{
	REG_GTIM0_SR = 0x7;		//清除状态标志
	
	if(irq_enable == GTIMER_IRQ_ENABLE)
	{
		switch(gtimer_irq_type)
		{
			case GTIMER0_UIE_IRQ:
					gtimer0_callback[0] = pfunc;
					REG_GTIM0_IER |= GTIMER0_UIE;				//使能UPDATE中断
					break;
			case GTIMER0_CCIE_IRQ:
					gtimer0_callback[1] = pfunc;
					REG_GTIM0_IER |= GTIMER0_CCIE;			//使能比较/捕捉中断
					break;	
			case GTIMER0_BKE_IE_IRQ:
					gtimer0_callback[2] = pfunc;
					REG_GTIM0_IER |= GTIMER0_BKE_IE;		//使能刹车中断
					break;
			default:
					break;				
		}	
		EA = 1 ;																	//开启总中断
		IEN1 |= (1<<0);														//开启gtimer0中断 
	}
	else
	{
		switch(gtimer_irq_type)
		{
			case GTIMER0_UIE_IRQ:
					gtimer0_callback[0] = pfunc;
					REG_GTIM0_IER |= ~GTIMER0_UIE;			//禁止UPDATE中断
					break;
			case GTIMER0_CCIE_IRQ:
					gtimer0_callback[1] = pfunc;
					REG_GTIM0_IER |= ~GTIMER0_CCIE;			//禁止比较/捕捉中断
					break;	
			case GTIMER0_BKE_IE_IRQ:
					gtimer0_callback[2] = pfunc;
					REG_GTIM0_IER |= ~GTIMER0_BKE_IE;		//禁止刹车中断
					break;		
			default:
					break;				
		}	
	}
	
}

/************************************************************************
 * Function   	: gtimer0_start
 * Description	: gtimer0_start 启动GTIMER0计数
 * Input 		: none
 * Output 	: none
 * Return		: none
 ************************************************************************/	
void gtimer0_start(void)
{
	REG_GTIM0_CR0 |= (1<<0);				//使能计数器 
}



/***********************************************************************
 * Function   	: gtimer0_stop
 * Description	: gtimer0_stop  停止GTIMER0计数器
 * Input 		: none
 * Output		: none
 * Return		: none
 ***********************************************************************/
void gtimer0_stop(void)
{
	REG_GTIM0_CR0 &= ~(1<<0);				//不使能计数器
}


