/***********************************************************************
 * Copyright (c)  2017 - 2022, Unicmicro Co.,Ltd .
 * All rights reserved.
 * Filename    : btimer01.c
 * Description : btimer01 driver source file
 * Author(s)   : Sissi
 * version     : V1.0
 * Modify date : 2022-08-08
 ***********************************************************************/
#include "btimer01.h"
#include "uart1.h"

void (*btimer0_callback[4])(void) = { 0 };

/************************************************************************
 * Function   	: BTIMER01_IRQHandler
 * Description	: btimer01中断处理函数
 * Input 	    : none
 * Output 		: none
 * Return		: none
 ************************************************************************/
void BTIMER01_IRQHandler(void)
{	
	if((REG_BTIM01_SR & VAL_BTIMER0_UIE))						//UE0中断
	{
		if(btimer0_callback[0] != NULL)
		{
			btimer0_callback[0]();	
			REG_BTIM01_SR = VAL_BTIMER0_UIE;					//清除UE0中断标志
		}		
	}		
	else if((REG_BTIM01_SR & VAL_BTIMER0_CNIE))					//比较0中断
	{
		if(btimer0_callback[1] != NULL)
		{
			btimer0_callback[1]();	
			REG_BTIM01_SR = VAL_BTIMER0_CNIE;					//清除比较0中断标志
		}		
	}			
	else if((REG_BTIM01_SR & VAL_BTIMER1_UIE))					//UE1中断
	{		
		if(btimer0_callback[2] != NULL)
		{
			btimer0_callback[2]();	
			REG_BTIM01_SR = VAL_BTIMER1_UIE;					//清除UE1中断标志
		}		
	}	
	else if((REG_BTIM01_SR & VAL_BTIMER1_CNIE))					//比较1中断
	{		
		if(btimer0_callback[3] != NULL)
		{
			btimer0_callback[3]();	
			REG_BTIM01_SR = VAL_BTIMER1_CNIE;					//清除比较1中断标志
		}		
	}
	
	REG_BTIM01_SR = BTIMER01_IRQ_CLEAR;							//清除所有中断标志
}

/************************************************************************
 * Function   	: btimer01_irq_init
 * Description	: btimer01 中断初始化
 * Input 		: uint8_t irq_enable				btimer01 中断使能开关 1：使能 0：禁止
				  uint8_t btimer_irq_type 			btimer01 中断类型选择
 *            	  void (*pfunc)()					btimer01 中断回调函数
 * Output 		: none
 * Return		: none
 ************************************************************************/	
void btimer01_irq_init(uint8_t irq_enable,uint8_t btimer_irq_type,void (*pfunc)())
{
	REG_BTIM01_SR = BTIMER01_IRQ_CLEAR;							//清除所有中断标志

	if(irq_enable == BTIMER01_IRQ_ENABLE)
	{
		switch(btimer_irq_type)
		{
			case BTIMER0_UE_IRQ:
					btimer0_callback[0] = pfunc;
					REG_BTIM01_DIER |= VAL_BTIMER0_UIE;			//允许CNT0 Update事件中断
					break;
			case BTIMER0_CNT_IRQ:
					btimer0_callback[1] = pfunc;
					REG_BTIM01_DIER |= VAL_BTIMER0_CNIE;		//允许比较0中断
					break;
			case BTIMER1_UE_IRQ:
					btimer0_callback[2] = pfunc;
					REG_BTIM01_DIER |= VAL_BTIMER1_UIE;			//允许CNT1 Update事件中断
					break;
			case BTIMER1_CNT_IRQ:
					btimer0_callback[3] = pfunc;
					REG_BTIM01_DIER |= VAL_BTIMER1_CNIE;		//允许比较1中断
					break;	
		}
		NVIC_ClearPendingIRQ(BTIMER01_IRQn);
		NVIC_EnableIRQ(BTIMER01_IRQn);
	}
	else
	{
		switch(btimer_irq_type)
		{
			case BTIMER0_UE_IRQ:
					btimer0_callback[0] = pfunc;
					REG_BTIM01_DIER &= ~VAL_BTIMER0_UIE;		//禁止CNT0 Update事件中断
					break;
			case BTIMER0_CNT_IRQ:
					btimer0_callback[1] = pfunc;
					REG_BTIM01_DIER &= ~VAL_BTIMER0_CNIE;		//禁止比较0中断
					break;
			case BTIMER1_UE_IRQ:
					btimer0_callback[2] = pfunc;
					REG_BTIM01_DIER &= ~VAL_BTIMER1_UIE;		//禁止CNT1 Update事件中断
					break;
			case BTIMER1_CNT_IRQ:
					btimer0_callback[3] = pfunc;
					REG_BTIM01_DIER &= ~VAL_BTIMER1_CNIE;		//禁止比较1中断
					break;	
		}
	}
}

/************************************************************************
 * Function   	: btimer0_count_init
 * Description	: btimer0 count 初始化
 * Input 		: uint16_t arr 		重载值设置
 *			  	  uint16_t psc 		预分频值设置
 * Output 		: none
 * Return		: none
 ************************************************************************/
void btimer0_count_init(uint16_t arr, uint16_t psc)
{
	REG_SCU_PERIRESET |= BTIMER01_CLKEN;						//BTIMER01模块时钟使能
	REG_SCU_PERICLKEN |= BTIMER01_RESET;						//BTIMER01模块复位使能
	
	REG_BTIM0_ARR = arr;
	REG_BTIM0_PSC = psc;
	
	REG_BTIM0_EGR = 0x1;									//使能update事件
	REG_BTIM0_CR &= ~(1<<1);								//UE事件发生时计数不停止
	REG_BTIM0_CR |= (1<<6);							  		//ARR寄存器使能preload
	
	REG_BTIM01_SR = BTIMER01_IRQ_CLEAR;						//清除所有中断标志
	REG_BTIM01_DIER |= VAL_BTIMER0_UIE;						//允许CNT Update事件中断
		
	REG_BTIM0_CR |= BTIMER01_CEN_ENABLE;		  			//BTIMER0计数器使能
}

/************************************************************************
 * Function   	: btimer1_count_init
 * Description	: btimer1 count 初始化
 * Input 		: uint16_t arr 		 重载值设置
 *			  	  uint16_t psc 		 预分频值设置
 * Output 		: none
 * Return		: none
 ************************************************************************/
void btimer1_count_init(uint16_t arr, uint16_t psc)
{
	REG_SCU_PERIRESET |= BTIMER01_CLKEN;						//BTIMER01模块时钟使能
	REG_SCU_PERICLKEN |= BTIMER01_RESET;						//BTIMER01模块复位使能
	
	REG_BTIM1_ARR = arr;
	REG_BTIM1_PSC = psc;
	
	REG_BTIM1_EGR = 0x1;									//使能update事件
	REG_BTIM1_CR &= ~(1<<1);								//UE事件发生时计不停止
	REG_BTIM1_CR |= (1<<6);							    	//ARR寄存器使能preload
	
	REG_BTIM01_SR = BTIMER01_IRQ_CLEAR;					    //清除所有中断标志
	REG_BTIM01_DIER |= VAL_BTIMER1_UIE;				        //允许CNT Update事件中断
	
	REG_BTIM1_CR |= BTIMER01_CEN_ENABLE;			        //BTIMER1计数器使能
}

/************************************************************************
 * Function   	: btimer0_pwm_cn_init
 * Description	: btimer0 count pwm 输出初始化
 * Input 		: uint16_t arr 		重载值设置
 *				  uint16_t ccr 		比较值设置
 *			  	  uint16_t psc 		预分频值设置
 * Output 		: none
 * Return		: none
 ************************************************************************/
void btimer0_pwm_cn_init(uint16_t arr,uint16_t ccr,uint16_t psc)
{
	REG_SCU_PERIRESET |= BTIMER01_CLKEN;						//BTIMER01模块时钟使能
	REG_SCU_PERICLKEN |= BTIMER01_RESET;						//BTIMER01模块复位使能
	
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 					//清除IO写保护

	REG_SCU_PGSEL = (REG_SCU_PGSEL&(~(0xF<<24)))|(0x9<<24);	//PG6复用为BTIMER0-OUT
	
	REG_SCU_IOCTRLPROTECT = 0xffffffff; 					//开启IO写保护
	
	REG_BTIM0_CR &= ~(1<<2);								//正向输出极性
	REG_BTIM0_CR |= (1<<7);								//输出PWM频率
	REG_BTIM0_CR &= ~(1<<1);								//UE事件发生时计数不停止
	
	REG_BTIM0_ARR = arr;									//重载值
	REG_BTIM0_CCR = ccr;									//比较值
	REG_BTIM0_PSC = psc;									//f(CNT) = f(CLK) / (psc + 1);
	
	REG_BTIM0_EGR = 0x1;									//使能update事件
	REG_BTIM01_SR = BTIMER01_IRQ_CLEAR;					    //清除所有中断标志
	
	REG_BTIM0_CR |= BTIMER01_CEN_ENABLE;			      	//BTIMER0计数器使能
}

/************************************************************************
 * Function   	: btimer1_pwm_cn_init
 * Description	: btimer1 count pwm 输出初始化
 * Input 		: uint16_t arr 		重载值设置
 *      		  uint16_t ccr 		比较值设置
 *			  	  uint16_t psc 		预分频值设置
 * Output 		: none
 * Return		: none
 ************************************************************************/
void btimer1_pwm_cn_init(uint16_t arr,uint16_t ccr,uint16_t psc)
{
	REG_SCU_PERIRESET |= BTIMER01_CLKEN;						//BTIMER01模块时钟使能
	REG_SCU_PERICLKEN |= BTIMER01_RESET;						//BTIMER01模块复位使能
	
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 					//清除IO写保护

	REG_SCU_PGSEL = (REG_SCU_PGSEL&(~(0xF<<12)))|(0x8<<12);	//PG3复用为BTIMER1-OUT

	REG_SCU_IOCTRLPROTECT = 0xffffffff; 					//开启IO写保护
	
	REG_BTIM1_CR &= ~(1<<2);								//正向输出极性
	REG_BTIM1_CR |= (1<<7);								//输出PWM频率
	REG_BTIM1_CR &= ~(1<<1);								//UE事件发生时计数不停止
	
	REG_BTIM1_ARR = arr;									//重载值
	REG_BTIM1_CCR = ccr;									//比较值
	REG_BTIM1_PSC = psc;									//f(CNT) = f(CLK) / (psc + 1);
	
	REG_BTIM1_EGR = 0x1;									//使能update事件
	
	REG_BTIM01_SR = BTIMER01_IRQ_CLEAR;					    //清除所有中断标志
	
	REG_BTIM1_CR |= BTIMER01_CEN_ENABLE;			        //BTIMER1计数器使能
}

/************************************************************************
 * function   : btimer0_caen
 * Description: 使能btimer0 count受cen_all控制
 * input      : none
 * return     : none
 ************************************************************************/
void btimer0_caen(void)
{
	REG_BTIM0_CR |= (1<<3);
}

/************************************************************************
 * function   : btimer1_caen
 * Description: 使能btimer1 count受cen_all控制
 * input      : none
 * return     : none
 ************************************************************************/
void btimer1_caen(void)
{
	REG_BTIM1_CR |= (1<<3);
}

/************************************************************************
 * function   : btimer0_cen_all
 * Description: 使能Atimer,Btimer01 cnt1,Btimer23,Gtimer,LPtimer cen = 1
 * input      : none
 * return     : none
 ************************************************************************/
void btimer0_cen_all(void)
{
	REG_BTIM0_CR |= (1<<4);
}

/************************************************************************
 * function   : btimer1_cen_all
 * Description: 使能Atimer,Btimer01 cnt0,Btimer23,Gtimer,LPtimer cen = 1
 * input      : none
 * return     : none
 ************************************************************************/
void btimer1_cen1_all(void)
{
	REG_BTIM1_CR |= (1<<4);
}
