/***********************************************************************************************************
 * Copyright (c)  2021 - 2022, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : gtimer0.c
 * Description : gtimer0 driver source file
 * Author(s)   : yanhaihua
 * Version     : V1.0
 * Modify date : 2021-09-23
 ***********************************************************************************************************/

#include "gtimer.h"

#if defined(UM2080F32_USING_GTIMER0) || defined(UM2080F32_USING_GTIMER1) || defined(UM2080F32_USING_GTIMER2)
/****************************************** GTIMER时钟使能 *************************************************/
#define VAL_GTIMER0_CLKEN	        		(1<<9)		    												/* GTIMER0时钟使能 */
#define VAL_GTIMER1_CLKEN		        	(1<<2)		    												/* GTIMER1时钟使能 */
#define VAL_GTIMER2_CLKEN	        		(1<<3)		    												/* GTIMER2时钟使能 */

/****************************************** GTIMER复位 *****************************************************/
#define VAL_GTIMER0_RESET	        		(1<<9)		    												/* GTIMER0复位 */
#define VAL_GTIMER1_RESET		        	(1<<2)		    												/* GTIMER1复位 */
#define VAL_GTIMER2_RESET	        		(1<<3)		    												/* GTIMER2复位 */

/****************************************** GTIM_IER寄存器 *************************************************/
#define VAL_GTIM_UIE	        			(1<<0)		    												/* UPTADE事件中断 */
#define VAL_GTIM_CCIE		        		(1<<1)		    												/* 捕捉/比较事件中断 */
#define VAL_GTIM_BKE_IE	        			(1<<2)		    												/* 刹车事件中断 */

/****************************************** GTIM_SR寄存器 **************************************************/
#define VAL_GTIM_SRCLEAR	        		(0x7)		    												/* 清除所有中断标志 */
#define VAL_GTIM_UIF	        			(1<<0)		    												/* UPTADE事件中断标志 */
#define VAL_GTIM_CCIF		        		(1<<1)		    												/* 捕捉/比较事件中断标志 */
#define VAL_GTIM_BKEF	        			(1<<2)		    												/* 刹车事件中断标志 */

/****************************************** 事件 ***********************************************************/
#define VAL_GTIM_EGR	        			(0x1)		    												/* 产生Update事件 */
#define VAL_GTIM_OPM_ENABLE					(1<<1)															/* Update Event发生时计数器停止（自动清零CEN）*/
#define VAL_GTIM_CEN						(1<<0)															/* 计数器使能 */

#define VAL_GTIM_MOE_ENABLE					(1<<18)															/* 输出总使能 */

/****************************************** PWM ************************************************************/
#define VAL_GTIM_PWM_DEAD_ENABLE			(1<<9)															/* 避免死区功能使能 */
#define VAL_GTIM_PWM_INV_ENABLE				(1<<8)															/* 互补PWM和原PWM反相位 */
		
#define VAL_GTIM_PWMN_B_S	        		(1<<16)		    												/* PWM刹车触发后，PWM互补电平状态设置位 为高电平 */
#define VAL_GTIM_PWMS_B_S           		(1<<14)		    												/* PWM刹车触发后，PWM正向电平状态设置位 为高电平 */
		
#define VAL_GTIM_PWMN_IDLE	        		(1<<20)		    												/* PWM输出负向电平IDLE状态 为高电平 */
#define VAL_GTIM_PWMP_IDLE          		(1<<19)		    												/* PWM输出正向电平IDLE状态 为高电平 */

/****************************************** ARR ************************************************************/
#define VAL_GTIM_UE_TRGO					(1<<7)															/* UE信号被用作TRGO */
#define VAL_GTIM_OC1REF_TRGO				(0<<7)															/* OC1REF用作TRGO */
		
#define VAL_GTIM_PRELOAD_ENABLE				(1<<6)															/* ARR寄存器使能preload */
#define VAL_GTIM_PRELOAD_DISABLE			(0<<6)															/* ARR寄存器不使能preload */

/****************************************** 对齐模式 *******************************************************/
#define VAL_GTIM_EDGE_ALIGN					(0<<4)															/* 边沿对齐模式 */
#define VAL_GTIM_CENTRAL_ALIGN1				(1<<4)															/* 中央对齐模式1，输出比较中断标志仅在计数器向下计数的过程中置位 */
#define VAL_GTIM_CENTRAL_ALIGN2				(2<<4)															/* 中央对齐模式2，输出比较中断标志仅在计数器向上计数的过程中置位 */
#define VAL_GTIM_CENTRAL_ALIGN3				(3<<4)															/* 中央对齐模式3，输出比较中断标志在计数器向上向下计数的过程中都会置位 */

/****************************************** 计数模式 *******************************************************/
#define VAL_GTIM_EDGE_DIR_UP				(0<<2)															/* 边沿模式向上计数 */
#define VAL_GTIM_EDGE_DIR_DOWN				(1<<2)															/* 边沿模式向下计数 */

#define VAL_GTIM_SOFT_BK					(1<<13)															/* 软件触发刹车功能 */

#define VAL_GTIM_CEN_ALL					(1<<12)															/* 同时使能Gtimer0/1/2和LPTIM0/1/2，写此位后Gtimer0/1/2和LPTIM0/1/2的CEN位同时为1 */
#define VAL_GTIM_CEN_ALL_EN		    		(1<<3)															/* 当前Gtimer可以被CEN_ALL控制 */
		
/****************************************** CCS ************************************************************/
#define VAL_GTIM_CCS_OUTPUT					(0<<0)															/* CC通道配置为输出 */
#define VAL_GTIM_CCS_INPUT					(1<<0)															/* CC通道配置为输入 */

#define VAL_GTIM_CCS	        			(1<<0)		    												/* CC通道方向选择 */

/****************************************** GTIM_CCER寄存器 ************************************************/
#define VAL_GTIM_CCP_HIGH					(0<<1)															/* CNT<CCR时输出高电平 */
#define VAL_GTIM_CCP_LOW					(1<<1)															/* CNT>CCR时输出高电平 */
#define VAL_GTIM_CCE_ENABLE					(1<<0)															/* 捕捉/比较输出使能 */

#define VAL_GTIM_CAPEDGE_UP					(0<<10)															/* 捕捉源上升沿触发 */
#define VAL_GTIM_CAPEDGE_DOWN				(1<<10)															/* 捕捉源下降沿触发 */
#define VAL_GTIM_CAPEDGE_UP_DOWN			(2<<10)															/* 捕捉源上升或下降沿触发 */


#endif

#ifdef UM2080F32_USING_GTIMER0

void (*gtimer0_callback[3])(void) = { 0 };
/***********************************************************************************************************
 * Function   	: gtimer0_count_init
 * Description	: GTIMER0定时器初始化
 * Input 		: uint8_t clk_src 	 GTIMER0计数时钟源选择
 *            	: uint16_t arr 		 GTIMER0重载值设置
 *			  	: uint16_t psc 		 GTIMER0预分频值设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_count_init(uint8_t clk_src,uint16_t arr,uint16_t psc)
{
	REG_SCU_PERIRESET |= VAL_GTIMER0_RESET;																	/* GTIMER0正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER0_CLKEN;																	/* 开GTIMER0时钟使能 */	
	
	REG_GTIM0_CCMR = (REG_GTIM0_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	
	REG_GTIM0_ARR = arr;																					/* 重载值 */
	REG_GTIM0_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM0_EGR = VAL_GTIM_EGR;																			/* 产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM0_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */
	
	REG_GTIM0_CR |= VAL_GTIM_EDGE_ALIGN;																	/* 边沿对齐模式	*/
	REG_GTIM0_CR |= VAL_GTIM_EDGE_DIR_UP; 																	/* 向上计数 */
}

/***********************************************************************************************************
 * Function   	: gtimer0_pwm_init
 * Description	: GTIMER0 PWM输出初始化
 * Input 		: uint8_t clk_src 	GTIMER0计数时钟源选择
 *            	: uint16_t arr 		GTIMER0重载值设置
 *				: uint16_t arr 		GTIMER0比较值设置
 *			  	: uint16_t psc 		GTIMER0预分频值设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_pwm_init(uint8_t clk_src,uint16_t arr,uint16_t ccr,uint16_t psc)
{
	REG_SCU_PERIRESET |= VAL_GTIMER0_RESET;																	/* GTIMER0正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER0_CLKEN;																	/* 开GTIMER0时钟使能 */	
	
	REG_GTIM0_CCMR = (REG_GTIM0_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	
	REG_GTIM0_ARR = arr|((arr)<<16);																		/* 重载值 */
	REG_GTIM0_CCR = ccr|((ccr)<<16);																		/* 比较值 */
	REG_GTIM0_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM0_EGR = VAL_GTIM_EGR;																			/* 产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM0_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */
	
	REG_GTIM0_CR |= VAL_GTIM_PWM_DEAD_ENABLE;																/* 避免死区功能使能,使能此位才能输出互补的PWM波 */
	REG_GTIM0_CR |= VAL_GTIM_PWM_INV_ENABLE;		     													/* 互补PWM和原PWM反相位 */
	REG_GTIM0_CR |= VAL_GTIM_EDGE_ALIGN;																	/* 边沿对齐模式	*/
	REG_GTIM0_CR |= VAL_GTIM_EDGE_DIR_UP; 																	/* 向上计数 */

	REG_GTIM0_CCMR |= VAL_GTIM_CCS_OUTPUT;																	/* CC通道配置为输出 */
	
	REG_GTIM0_CCER |= VAL_GTIM_CCP_HIGH;																	/* CNT<CCR时输出高电平 */
	REG_GTIM0_CCER |= VAL_GTIM_CCE_ENABLE;																	/* 比较输出使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer0_capture_init
 * Description	: GTIMER0 输入捕获初始化
 * Input 		: uint8_t clk_src 	GTIMER0计数时钟源选择
 *            	: uint16_t arr 		GTIMER0重载值设置
 *			  	: uint16_t psc 		GTIMER0预分频值设置
 *              : uint8_t cap_div   GTIMER0捕捉源分频设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_capture_init(uint8_t clk_src,uint16_t arr,uint16_t psc,uint8_t cap_div) 
{
	REG_SCU_PERIRESET |= VAL_GTIMER0_RESET;																	/* GTIMER0正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER0_CLKEN;																	/* 开GTIMER0时钟使能 */	
	
	REG_GTIM0_CCMR |= VAL_GTIM_CAPSSEL_GTIMER_CH;															/* 选择捕捉源 */
	REG_GTIM0_CCMR = (REG_GTIM0_CCMR & ~(3<<13)) | cap_div;													/* 捕捉源预分频 */
	REG_GTIM0_CCMR |= VAL_GTIM_CAPEDGE_UP;																	/* 捕捉源上升沿触发 */
		
	REG_GTIM0_CCMR = (REG_GTIM0_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	REG_GTIM0_ARR = arr;																					/* 重载值 */
	REG_GTIM0_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM0_EGR = VAL_GTIM_EGR;																			/* /产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM0_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */

	REG_GTIM0_CCMR |= VAL_GTIM_CCS_INPUT;																	/* CC通道配置为输入 */
	REG_GTIM0_CCER |= VAL_GTIM_CCE_ENABLE;																	/* 捕捉使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer0_bke_init
 * Description	: GTIMER0 硬件刹车初始化
 * Input 		: uint32_t bke_src	GTIMER0刹车源设置
 *            	: uint32_t bke_pol	GTIMER0刹车信号触发极性
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_bke_init(uint32_t bke_src,uint32_t bke_pol)
{
	REG_SCU_PERIRESET |= VAL_GTIMER0_RESET;																	/* GTIMER0正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER0_CLKEN;																	/* 开GTIMER0时钟使能 */	
	
	REG_GTIM0_CR = (REG_GTIM0_CR & ~(0xFF<<21)) | bke_src;													/* 刹车源选择 */
	REG_GTIM0_CR = (REG_GTIM0_CR & ~(1<<11)) | bke_pol;     												/* 刹车信号触发极性 */

	REG_GTIM0_CR &= ~VAL_GTIM_PWMN_IDLE; 																	/* PWM输出负向电平IDLE状态为低电平 */
	REG_GTIM0_CR &= ~VAL_GTIM_PWMP_IDLE; 																	/* PWM输出正向电平IDLE状态为低电平 */
	
	REG_GTIM0_CR &= ~VAL_GTIM_PWMN_B_S;    																	/* PWM刹车触发后，PWM互补电平状态设置位为低电平 */
	REG_GTIM0_CR &= ~VAL_GTIM_PWMS_B_S;     																/* PWM刹车触发后，PWM正向电平状态设置位为低电平 */
	
	REG_GTIM0_CR |= VAL_GTIM_BKE;           																/* 刹车功能使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer0_moe_set
 * Description	: GTIMER0通道输出使能开关
 * Input 		: uint8_t moe_enable	1:使能输出 0：关闭输出
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_moe_set(em_enable_t moe_enable)
{
	if(moe_enable == ENABLE)
	{
		REG_GTIM0_CR |= VAL_GTIM_MOE_ENABLE;																/* 使能输出 */
	}
	else
	{	
		REG_GTIM0_CR &= ~VAL_GTIM_MOE_ENABLE;																/* 关闭输出 */
	}
}

/***********************************************************************************************************
 * Function   	: gtimer0_soft_bke_set
 * Description	: GTIMER0软件触发刹车使能开关
 * Input 		: uint8_t soft_bk_enable	1:使能软件触发刹车 0：关闭软件触发刹车
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_soft_bke_set(em_enable_t soft_bk_enable)
{
	if(soft_bk_enable == ENABLE)
	{
		REG_GTIM0_CR |= VAL_GTIM_SOFT_BK;       															/* 软件触发刹车功能 */
	}
	else
	{	
		REG_GTIM0_CR &= ~VAL_GTIM_SOFT_BK;       															/* 关闭软件触发刹车功能 */
		REG_GTIM0_SR = VAL_GTIM_BKEF;																		/* 清除刹车中断标志 */
	}
}

/***********************************************************************************************************
 * Function   	: gtimer0_irq_init
 * Description	: GTIMER0 中断初始化
 * Input 		: em_enable_t irq_enable	GTIMER0中断使能开关
 *   			: em_gtimer_irq_t irq_type  GTIMER0中断类型选择
 *            	: void (*pfunc)()	        GTIMER0中断回调函数
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/	
void gtimer0_irq_init(em_enable_t irq_enable,em_gtimer_irq_t irq_type,void (*pfunc)())
{
	REG_GTIM0_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断状态 */
	if(irq_enable == ENABLE)
	{
		NVIC_ClearPendingIRQ(GTIMER0_IRQn);
		NVIC_EnableIRQ(GTIMER0_IRQn);
		
		REG_GTIM0_IER |= (1<<irq_type);
		gtimer0_callback[irq_type] = pfunc;
	}
	else
	{
		REG_GTIM0_IER &= ~(1<<irq_type);
		gtimer0_callback[irq_type] = pfunc;
	}
}

/***********************************************************************************************************
 * Function   	: gtimer0_start
 * Description	: 启动GTIMER0计数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/	
void gtimer0_start(void)
{
	REG_GTIM0_CR |= VAL_GTIM_CEN;																			/* 启动计数器 */
}

/***********************************************************************************************************
 * Function   	: gtimer0_stop
 * Description	: 关闭GTIMER0计数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer0_stop(void)
{
	REG_GTIM0_CR &= ~VAL_GTIM_CEN;																			/* 关闭计数器 */
}

/***********************************************************************************************************
 * Function   	: GTIMER0_IRQHandler
 * Description	: GTIMER0中断处理函数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void GTIMER0_IRQHandler(void)
{
	if((REG_GTIM0_SR & VAL_GTIM_UIF) && (REG_GTIM0_IER & VAL_GTIM_UIE))										/* UE中断 */
	{
		if(gtimer0_callback[0] != NULL)
		{
			gtimer0_callback[0]();	
			REG_GTIM0_SR = VAL_GTIM_UIF;																	/* 清除UE中断标志 */
		}		
	}	
	else if((REG_GTIM0_SR & VAL_GTIM_CCIF) && (REG_GTIM0_IER & VAL_GTIM_CCIE))								/* 比较中断 */
	{
		if(gtimer0_callback[1] != NULL)
		{
			gtimer0_callback[1]();	
			REG_GTIM0_SR = VAL_GTIM_CCIF;																	/* 清除比较中断标志 */
		}	
	}	
	else if((REG_GTIM0_SR & VAL_GTIM_BKEF) && (REG_GTIM0_IER & VAL_GTIM_BKE_IE))							/* 刹车中断 */
	{
		if(gtimer0_callback[2] != NULL)
		{
			gtimer0_callback[2]();	
			REG_GTIM0_SR = VAL_GTIM_BKEF;																	/* 清除刹车中断标志 */
		}	
	}
	else
	{
		REG_GTIM0_SR = VAL_GTIM_SRCLEAR;																	/* 清除所有中断状态 */
	}
}

#endif


#ifdef UM2080F32_USING_GTIMER1

void (*gtimer1_callback[3])(void) = { 0 };
/***********************************************************************************************************
 * Function   	: gtimer1_count_init
 * Description	: GTIMER1定时器初始化
 * Input 		: uint8_t clk_src 	 GTIMER1计数时钟源选择
 *            	: uint16_t arr 		 GTIMER1重载值设置
 *			  	: uint16_t psc 		 GTIMER1预分频值设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_count_init(uint8_t clk_src,uint16_t arr,uint16_t psc)
{
	REG_SCU_PERIRESET |= VAL_GTIMER1_RESET;																	/* GTIMER1正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER1_CLKEN;																	/* 开GTIMER1时钟使能 */	
	
	REG_GTIM1_CCMR = (REG_GTIM1_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	
	REG_GTIM1_ARR = arr;																					/* 重载值 */
	REG_GTIM1_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM1_EGR = VAL_GTIM_EGR;																			/* 产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM1_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */
	
	REG_GTIM1_CR |= VAL_GTIM_EDGE_ALIGN;																	/* 边沿对齐模式	*/
	REG_GTIM1_CR |= VAL_GTIM_EDGE_DIR_UP; 																	/* 向上计数 */
}

/***********************************************************************************************************
 * Function   	: gtimer1_pwm_init
 * Description	: GTIMER1 PWM输出初始化
 * Input 		: uint8_t clk_src 	GTIMER1计数时钟源选择
 *            	: uint16_t arr 		GTIMER1重载值设置
 *				: uint16_t arr 		GTIMER1比较值设置
 *			  	: uint16_t psc 		GTIMER1预分频值设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_pwm_init(uint8_t clk_src,uint16_t arr,uint16_t ccr,uint16_t psc)
{
	REG_SCU_PERIRESET |= VAL_GTIMER1_RESET;																	/* GTIMER1正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER1_CLKEN;																	/* 开GTIMER1时钟使能 */	
	
	REG_GTIM1_CCMR = (REG_GTIM1_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	
	REG_GTIM1_ARR = arr|((arr)<<16);																		/* 重载值 */
	REG_GTIM1_CCR = ccr|((ccr)<<16);																		/* 比较值 */
	REG_GTIM1_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM1_EGR = VAL_GTIM_EGR;																			/* 产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM1_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */
	
	REG_GTIM1_CR |= VAL_GTIM_PWM_DEAD_ENABLE;																/* 避免死区功能使能,使能此位才能输出互补的PWM波 */
	REG_GTIM1_CR |= VAL_GTIM_PWM_INV_ENABLE;		     													/* 互补PWM和原PWM反相位 */
	REG_GTIM1_CR |= VAL_GTIM_EDGE_ALIGN;																	/* 边沿对齐模式	*/
	REG_GTIM1_CR |= VAL_GTIM_EDGE_DIR_UP; 																	/* 向上计数 */

	REG_GTIM1_CCMR |= VAL_GTIM_CCS_OUTPUT;																	/* CC通道配置为输出 */
	
	REG_GTIM1_CCER |= VAL_GTIM_CCP_HIGH;																	/* CNT<CCR时输出高电平 */
	REG_GTIM1_CCER |= VAL_GTIM_CCE_ENABLE;																	/* 比较输出使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer1_capture_init
 * Description	: GTIMER1 输入捕获初始化
 * Input 		: uint8_t clk_src 	GTIMER1计数时钟源选择
 *            	: uint16_t arr 		GTIMER1重载值设置
 *			  	: uint16_t psc 		GTIMER1预分频值设置
 *              : uint8_t cap_div   GTIMER1捕捉源分频设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_capture_init(uint8_t clk_src,uint16_t arr,uint16_t psc,uint8_t cap_div) 
{
	REG_SCU_PERIRESET |= VAL_GTIMER1_RESET;																	/* GTIMER1正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER1_CLKEN;																	/* 开GTIMER1时钟使能 */	
	
	REG_GTIM1_CCMR |= VAL_GTIM_CAPSSEL_GTIMER_CH;															/* 选择捕捉源 */
	REG_GTIM1_CCMR = (REG_GTIM1_CCMR & ~(3<<13)) | cap_div;													/* 捕捉源预分频 */
	REG_GTIM1_CCMR |= VAL_GTIM_CAPEDGE_UP;																	/* 捕捉源上升沿触发 */
		
	REG_GTIM1_CCMR = (REG_GTIM1_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	REG_GTIM1_ARR = arr;																					/* 重载值 */
	REG_GTIM1_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM1_EGR = VAL_GTIM_EGR;																			/* /产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM1_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */

	REG_GTIM1_CCMR |= VAL_GTIM_CCS_INPUT;																	/* CC通道配置为输入 */
	REG_GTIM1_CCER |= VAL_GTIM_CCE_ENABLE;																	/* 捕捉使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer1_bke_init
 * Description	: GTIMER1 硬件刹车初始化
 * Input 		: uint32_t bke_src	GTIMER1刹车源设置
 *            	: uint32_t bke_pol	GTIMER1刹车信号触发极性
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_bke_init(uint32_t bke_src,uint32_t bke_pol)
{
	REG_SCU_PERIRESET |= VAL_GTIMER1_RESET;																	/* GTIMER1正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER1_CLKEN;																	/* 开GTIMER1时钟使能 */	
	
	REG_GTIM1_CR = (REG_GTIM1_CR & ~(0xFF<<21)) | bke_src;													/* 刹车源选择 */
	REG_GTIM1_CR = (REG_GTIM1_CR & ~(1<<11)) | bke_pol;     												/* 刹车信号触发极性 */

	REG_GTIM1_CR &= ~VAL_GTIM_PWMN_IDLE; 																	/* PWM输出负向电平IDLE状态为低电平 */
	REG_GTIM1_CR &= ~VAL_GTIM_PWMP_IDLE; 																	/* PWM输出正向电平IDLE状态为低电平 */
	
	REG_GTIM1_CR &= ~VAL_GTIM_PWMN_B_S;    																	/* PWM刹车触发后，PWM互补电平状态设置位为低电平 */
	REG_GTIM1_CR &= ~VAL_GTIM_PWMS_B_S;     																/* PWM刹车触发后，PWM正向电平状态设置位为低电平 */
	
	REG_GTIM1_CR |= VAL_GTIM_BKE;           																/* 刹车功能使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer1_moe_set
 * Description	: GTIMER1通道输出使能开关
 * Input 		: uint8_t moe_enable	1:使能输出 0：关闭输出
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_moe_set(em_enable_t moe_enable)
{
	if(moe_enable == ENABLE)
	{
		REG_GTIM1_CR |= VAL_GTIM_MOE_ENABLE;																/* 使能输出 */
	}
	else
	{	
		REG_GTIM1_CR &= ~VAL_GTIM_MOE_ENABLE;																/* 关闭输出 */
	}
}

/***********************************************************************************************************
 * Function   	: gtimer1_soft_bke_set
 * Description	: GTIMER1软件触发刹车使能开关
 * Input 		: uint8_t soft_bk_enable	1:使能软件触发刹车 0：关闭软件触发刹车
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_soft_bke_set(em_enable_t soft_bk_enable)
{
	if(soft_bk_enable == ENABLE)
	{
		REG_GTIM1_CR |= VAL_GTIM_SOFT_BK;       															/* 软件触发刹车功能 */
	}
	else
	{	
		REG_GTIM1_CR &= ~VAL_GTIM_SOFT_BK;       															/* 关闭软件触发刹车功能 */
		REG_GTIM1_SR = VAL_GTIM_BKEF;																		/* 清除刹车中断标志 */
	}
}

/***********************************************************************************************************
 * Function   	: gtimer1_irq_init
 * Description	: GTIMER1 中断初始化
 * Input 		: em_enable_t irq_enable	GTIMER1中断使能开关
 *   			: em_gtimer_irq_t irq_type  GTIMER1中断类型选择
 *            	: void (*pfunc)()	        GTIMER1中断回调函数
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/	
void gtimer1_irq_init(em_enable_t irq_enable,em_gtimer_irq_t irq_type,void (*pfunc)())
{
	REG_GTIM1_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断状态 */
	if(irq_enable == ENABLE)
	{
		NVIC_ClearPendingIRQ(GTIMER1_IRQn);
		NVIC_EnableIRQ(GTIMER1_IRQn);
		
		REG_GTIM1_IER |= (1<<irq_type);
		gtimer1_callback[irq_type] = pfunc;
	}
	else
	{
		REG_GTIM1_IER &= ~(1<<irq_type);
		gtimer1_callback[irq_type] = pfunc;
	}
}

/***********************************************************************************************************
 * Function   	: gtimer1_start
 * Description	: 启动GTIMER1计数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/	
void gtimer1_start(void)
{
	REG_GTIM1_CR |= VAL_GTIM_CEN;																			/* 启动计数器 */
}

/***********************************************************************************************************
 * Function   	: gtimer1_stop
 * Description	: 关闭GTIMER1计数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer1_stop(void)
{
	REG_GTIM1_CR &= ~VAL_GTIM_CEN;																			/* 关闭计数器 */
}

/***********************************************************************************************************
 * Function   	: GTIMER1_IRQHandler
 * Description	: GTIMER1中断处理函数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void GTIMER1_IRQHandler(void)
{
	if((REG_GTIM1_SR & VAL_GTIM_UIF) && (REG_GTIM1_IER & VAL_GTIM_UIE))										/* UE中断 */
	{
		if(gtimer1_callback[0] != NULL)
		{
			gtimer1_callback[0]();	
			REG_GTIM1_SR = VAL_GTIM_UIF;																	/* 清除UE中断标志 */
		}		
	}	
	else if((REG_GTIM1_SR & VAL_GTIM_CCIF) && (REG_GTIM1_IER & VAL_GTIM_CCIE))								/* 比较中断 */
	{
		if(gtimer1_callback[1] != NULL)
		{
			gtimer1_callback[1]();	
			REG_GTIM1_SR = VAL_GTIM_CCIF;																	/* 清除比较中断标志 */
		}	
	}	
	else if((REG_GTIM1_SR & VAL_GTIM_BKEF) && (REG_GTIM1_IER & VAL_GTIM_BKE_IE))							/* 刹车中断 */
	{
		if(gtimer1_callback[2] != NULL)
		{
			gtimer1_callback[2]();	
			REG_GTIM1_SR = VAL_GTIM_BKEF;																	/* 清除刹车中断标志 */
		}	
	}
	else
	{
		REG_GTIM1_SR = VAL_GTIM_SRCLEAR;																	/* 清除所有中断状态 */
	}
}

#endif


#ifdef UM2080F32_USING_GTIMER2

void (*gtimer2_callback[3])(void) = { 0 };
/***********************************************************************************************************
 * Function   	: gtimer2_count_init
 * Description	: GTIMER2定时器初始化
 * Input 		: uint8_t clk_src 	 GTIMER2计数时钟源选择
 *            	: uint16_t arr 		 GTIMER2重载值设置
 *			  	: uint16_t psc 		 GTIMER2预分频值设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_count_init(uint8_t clk_src,uint16_t arr,uint16_t psc)
{
	REG_SCU_PERIRESET |= VAL_GTIMER2_RESET;																	/* GTIMER2正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER2_CLKEN;																	/* 开GTIMER2时钟使能 */	
	
	REG_GTIM2_CCMR = (REG_GTIM2_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	
	REG_GTIM2_ARR = arr;																					/* 重载值 */
	REG_GTIM2_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM2_EGR = VAL_GTIM_EGR;																			/* 产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM2_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */
	
	REG_GTIM2_CR |= VAL_GTIM_EDGE_ALIGN;																	/* 边沿对齐模式	*/
	REG_GTIM2_CR |= VAL_GTIM_EDGE_DIR_UP; 																	/* 向上计数 */
}

/***********************************************************************************************************
 * Function   	: gtimer2_pwm_init
 * Description	: GTIMER2 PWM输出初始化
 * Input 		: uint8_t clk_src 	GTIMER2计数时钟源选择
 *            	: uint16_t arr 		GTIMER2重载值设置
 *				: uint16_t arr 		GTIMER2比较值设置
 *			  	: uint16_t psc 		GTIMER2预分频值设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_pwm_init(uint8_t clk_src,uint16_t arr,uint16_t ccr,uint16_t psc)
{
	REG_SCU_PERIRESET |= VAL_GTIMER2_RESET;																	/* GTIMER2正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER2_CLKEN;																	/* 开GTIMER2时钟使能 */	
	
	REG_GTIM2_CCMR = (REG_GTIM2_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	
	REG_GTIM2_ARR = arr|((arr)<<16);																		/* 重载值 */
	REG_GTIM2_CCR = ccr|((ccr)<<16);																		/* 比较值 */
	REG_GTIM2_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM2_EGR = VAL_GTIM_EGR;																			/* 产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM2_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */
	
	REG_GTIM2_CR |= VAL_GTIM_PWM_DEAD_ENABLE;																/* 避免死区功能使能,使能此位才能输出互补的PWM波 */
	REG_GTIM2_CR |= VAL_GTIM_PWM_INV_ENABLE;		     													/* 互补PWM和原PWM反相位 */
	REG_GTIM2_CR |= VAL_GTIM_EDGE_ALIGN;																	/* 边沿对齐模式	*/
	REG_GTIM2_CR |= VAL_GTIM_EDGE_DIR_UP; 																	/* 向上计数 */

	REG_GTIM2_CCMR |= VAL_GTIM_CCS_OUTPUT;																	/* CC通道配置为输出 */
	
	REG_GTIM2_CCER |= VAL_GTIM_CCP_HIGH;																	/* CNT<CCR时输出高电平 */
	REG_GTIM2_CCER |= VAL_GTIM_CCE_ENABLE;																	/* 比较输出使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer2_capture_init
 * Description	: GTIMER2 输入捕获初始化
 * Input 		: uint8_t clk_src 	GTIMER2计数时钟源选择
 *            	: uint16_t arr 		GTIMER2重载值设置
 *			  	: uint16_t psc 		GTIMER2预分频值设置
 *              : uint8_t cap_div   GTIMER2捕捉源分频设置
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_capture_init(uint8_t clk_src,uint16_t arr,uint16_t psc,uint8_t cap_div) 
{
	REG_SCU_PERIRESET |= VAL_GTIMER2_RESET;																	/* GTIMER2正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER2_CLKEN;																	/* 开GTIMER2时钟使能 */	
	
	REG_GTIM2_CCMR |= VAL_GTIM_CAPSSEL_GTIMER_CH;															/* 选择捕捉源 */
	REG_GTIM2_CCMR = (REG_GTIM2_CCMR & ~(3<<13)) | cap_div;													/* 捕捉源预分频 */
	REG_GTIM2_CCMR |= VAL_GTIM_CAPEDGE_UP;																	/* 捕捉源上升沿触发 */
		
	REG_GTIM2_CCMR = (REG_GTIM2_CCMR & ~(3<<4)) | clk_src;													/* 选择计数时钟源 */
	REG_GTIM2_ARR = arr;																					/* 重载值 */
	REG_GTIM2_PSC = psc;																					/* f(CNT) = f(CLK) / (psc + 1); */
	REG_GTIM2_EGR = VAL_GTIM_EGR;																			/* /产生UE事件，将PSC的值立即载入shadow寄存器 */
	REG_GTIM2_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断 */

	REG_GTIM2_CCMR |= VAL_GTIM_CCS_INPUT;																	/* CC通道配置为输入 */
	REG_GTIM2_CCER |= VAL_GTIM_CCE_ENABLE;																	/* 捕捉使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer2_bke_init
 * Description	: GTIMER2 硬件刹车初始化
 * Input 		: uint32_t bke_src	GTIMER2刹车源设置
 *            	: uint32_t bke_pol	GTIMER2刹车信号触发极性
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_bke_init(uint32_t bke_src,uint32_t bke_pol)
{
	REG_SCU_PERIRESET |= VAL_GTIMER2_RESET;																	/* GTIMER2正常工作 */
	REG_SCU_PERICLKEN |= VAL_GTIMER2_CLKEN;																	/* 开GTIMER2时钟使能 */	
	
	REG_GTIM2_CR = (REG_GTIM2_CR & ~(0xFF<<21)) | bke_src;													/* 刹车源选择 */
	REG_GTIM2_CR = (REG_GTIM2_CR & ~(1<<11)) | bke_pol;     												/* 刹车信号触发极性 */

	REG_GTIM2_CR &= ~VAL_GTIM_PWMN_IDLE; 																	/* PWM输出负向电平IDLE状态为低电平 */
	REG_GTIM2_CR &= ~VAL_GTIM_PWMP_IDLE; 																	/* PWM输出正向电平IDLE状态为低电平 */
	
	REG_GTIM2_CR &= ~VAL_GTIM_PWMN_B_S;    																	/* PWM刹车触发后，PWM互补电平状态设置位为低电平 */
	REG_GTIM2_CR &= ~VAL_GTIM_PWMS_B_S;     																/* PWM刹车触发后，PWM正向电平状态设置位为低电平 */
	
	REG_GTIM2_CR |= VAL_GTIM_BKE;           																/* 刹车功能使能 */
}

/***********************************************************************************************************
 * Function   	: gtimer2_moe_set
 * Description	: GTIMER2通道输出使能开关
 * Input 		: uint8_t moe_enable	1:使能输出 0：关闭输出
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_moe_set(em_enable_t moe_enable)
{
	if(moe_enable == ENABLE)
	{
		REG_GTIM2_CR |= VAL_GTIM_MOE_ENABLE;																/* 使能输出 */
	}
	else
	{	
		REG_GTIM2_CR &= ~VAL_GTIM_MOE_ENABLE;																/* 关闭输出 */
	}
}

/***********************************************************************************************************
 * Function   	: gtimer2_soft_bke_set
 * Description	: GTIMER2软件触发刹车使能开关
 * Input 		: uint8_t soft_bk_enable	1:使能软件触发刹车 0：关闭软件触发刹车
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_soft_bke_set(em_enable_t soft_bk_enable)
{
	if(soft_bk_enable == ENABLE)
	{
		REG_GTIM2_CR |= VAL_GTIM_SOFT_BK;       															/* 软件触发刹车功能 */
	}
	else
	{	
		REG_GTIM2_CR &= ~VAL_GTIM_SOFT_BK;       															/* 关闭软件触发刹车功能 */
		REG_GTIM2_SR = VAL_GTIM_BKEF;																		/* 清除刹车中断标志 */
	}
}

/***********************************************************************************************************
 * Function   	: gtimer2_irq_init
 * Description	: GTIMER2 中断初始化
 * Input 		: em_enable_t irq_enable	GTIMER2中断使能开关
 *   			: em_gtimer_irq_t irq_type  GTIMER2中断类型选择
 *            	: void (*pfunc)()	        GTIMER2中断回调函数
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/	
void gtimer2_irq_init(em_enable_t irq_enable,em_gtimer_irq_t irq_type,void (*pfunc)())
{
	REG_GTIM2_SR = VAL_GTIM_SRCLEAR;																		/* 清除所有中断状态 */
	if(irq_enable == ENABLE)
	{
		NVIC_ClearPendingIRQ(GTIMER2_IRQn);
		NVIC_EnableIRQ(GTIMER2_IRQn);
		
		REG_GTIM2_IER |= (1<<irq_type);
		gtimer2_callback[irq_type] = pfunc;
	}
	else
	{
		REG_GTIM2_IER &= ~(1<<irq_type);
		gtimer2_callback[irq_type] = pfunc;
	}
}

/***********************************************************************************************************
 * Function   	: gtimer2_start
 * Description	: 启动GTIMER2计数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/	
void gtimer2_start(void)
{
	REG_GTIM2_CR |= VAL_GTIM_CEN;																			/* 启动计数器 */
}

/***********************************************************************************************************
 * Function   	: gtimer2_stop
 * Description	: 关闭GTIMER2计数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void gtimer2_stop(void)
{
	REG_GTIM2_CR &= ~VAL_GTIM_CEN;																			/* 关闭计数器 */
}

/***********************************************************************************************************
 * Function   	: GTIMER2_IRQHandler
 * Description	: GTIMER2中断处理函数
 * Input 		: none
 * Output 		: none
 * Return		: none
 ***********************************************************************************************************/
void GTIMER2_IRQHandler(void)
{
	if((REG_GTIM2_SR & VAL_GTIM_UIF) && (REG_GTIM2_IER & VAL_GTIM_UIE))										/* UE中断 */
	{
		if(gtimer2_callback[0] != NULL)
		{
			gtimer2_callback[0]();	
			REG_GTIM2_SR = VAL_GTIM_UIF;																	/* 清除UE中断标志 */
		}		
	}	
	else if((REG_GTIM2_SR & VAL_GTIM_CCIF) && (REG_GTIM2_IER & VAL_GTIM_CCIE))								/* 比较中断 */
	{
		if(gtimer2_callback[1] != NULL)
		{
			gtimer2_callback[1]();	
			REG_GTIM2_SR = VAL_GTIM_CCIF;																	/* 清除比较中断标志 */
		}	
	}	
	else if((REG_GTIM2_SR & VAL_GTIM_BKEF) && (REG_GTIM2_IER & VAL_GTIM_BKE_IE))							/* 刹车中断 */
	{
		if(gtimer2_callback[2] != NULL)
		{
			gtimer2_callback[2]();	
			REG_GTIM2_SR = VAL_GTIM_BKEF;																	/* 清除刹车中断标志 */
		}	
	}
	else
	{
		REG_GTIM2_SR = VAL_GTIM_SRCLEAR;																	/* 清除所有中断状态 */
	}
}

#endif



