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

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

/************************************************************************
 * function   : LPTIMER23_IRQHandler
 * description: LPTIMER23_IRQHandler 
 * input      : none  
 * return     : none
 ************************************************************************/
void LPTIMER23_IRQHandler(void)
{
	if(REG_LPTIM23_SR & 0xFF)
	{
		//////////////////////////////////////LPTIMER2//////////////////////////////////////////////
		if(REG_LPTIM23_SR & VAL_LPTIM2_SR_UIF)		          //更新中断
		{                                           
			if(lptimer2func[0]!= NULL)              
			{                                       
				((void(*)())(lptimer2func[0]))();	          //lptimer2更新中断处理回调函数
			}	                                    
			REG_LPTIM23_SR = VAL_LPTIM2_SR_UIF;       
		}                                           
		                                            
		if(REG_LPTIM23_SR & VAL_LPTIM2_SR_CC1IF)		      //比较1/捕获1触发中断
		{                                           
			if(lptimer2func[1]!= NULL)              
			{                                       
				((void(*)())(lptimer2func[1]))();  	          //lptimer2比较1/捕获1触发处理回调函数
			}	                                    
			REG_LPTIM23_SR = VAL_LPTIM2_SR_CC1IF;     
		}                                           
	                                                
		if(REG_LPTIM23_SR & VAL_LPTIM2_SR_CC2IF)		      //比较2/捕获2触发中断
		{                                             
			if(lptimer2func[2]!= NULL)              
			{                                       
				((void(*)())(lptimer2func[2]))();	          //lptimer2比较2/捕获2触发处理回调函数
			}	                                    
			REG_LPTIM23_SR = VAL_LPTIM2_SR_CC2IF;     
		}                                           
		                                            
		if(REG_LPTIM23_SR & VAL_LPTIM2_SR_TIF)		          //外部触发中断
		{                                           
			if(lptimer2func[3]!= NULL)              
			{                                       
				((void(*)())(lptimer2func[3]))();	          //lptimer2外部触发中断处理回调函数
			}	
			REG_LPTIM23_SR = VAL_LPTIM2_SR_TIF;
		}
		//////////////////////////////////////LPTIMER3//////////////////////////////////////////////
		if(REG_LPTIM23_SR & VAL_LPTIM3_SR_UIF)		         //更新中断
		{
			if(lptimer3func[0]!= NULL)
			{
				((void(*)())(lptimer3func[0]))();	         //lptimer3更新中断处理回调函数
			}	 
			REG_LPTIM23_SR = VAL_LPTIM3_SR_UIF;
		}
		
		if(REG_LPTIM23_SR & VAL_LPTIM3_SR_CC1IF)		     //比较1/捕获1触发中断
		{
			if(lptimer3func[1]!= NULL)
			{
				((void(*)())(lptimer3func[1]))(); 	         //lptimer3比较1/捕获1触发处理回调函数
			}	
			REG_LPTIM23_SR = VAL_LPTIM3_SR_CC1IF;
		}
	
		if(REG_LPTIM23_SR & VAL_LPTIM3_SR_CC2IF)		     //比较2/捕获2触发中断
		{
			if(lptimer3func[2]!= NULL)
			{
				((void(*)())(lptimer3func[2]))();	         //lptimer3比较2/捕获2触发处理回调函数
			}	
			REG_LPTIM23_SR = VAL_LPTIM3_SR_CC2IF;
		}
		
		if(REG_LPTIM23_SR & VAL_LPTIM3_SR_TIF)		         //外部触发中断
		{
			if(lptimer3func[3]!= NULL)
			{
				((void(*)())(lptimer3func[3]))();	         //lptimer3外部触发中断处理回调函数
			}	
			REG_LPTIM23_SR = VAL_LPTIM3_SR_TIF;
		}
	
	}
	else 
	{
		REG_LPTIM23_SR = 0xFF;						         //清除全部中断状态 												
	}
}
/*******************************************************************
* function		: lptimer23_model_init
* description	: lptimer23_model_init  	LPTimer23定时初始化
* input			: none       	  
* return		: none
********************************************************************/
void lptimer23_model_init(void)
{
	REG_SCU_PERIRESET |= ((uint32_t)0x01<<5);											   // lpTimer23正常工作 
	REG_SCU_PERICLKEN |= ((uint32_t)0x01<<5);											   // 开启lpTimer23时钟使能 
}				                                                                           
/*******************************************************************
* function		: lptimer2_count_init
* description	: lptimer2_count_init  	LPTimer2定时初始化
* input			: uint32_t clock_source	时钟源选择
*				  uint32_t clock_div	时钟源分频
*             	  uint32_t time			定时时间        	  
* return		: none
********************************************************************/
void lptimer2_count_init(uint32_t clock_source, uint32_t clock_div, uint32_t time)
{
	lptimer23_model_init();
			
	REG_LPTIM2_CR2 &= ~(0x00001FFF);														// 恢复默认值 
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TMODE_TIME;												// 设置工作模式 
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_MODE_COUNT;												// 计数模式 
	REG_LPTIM2_CR2 |= clock_div;															// 设置分频值2分频
	REG_LPTIM2_CR2 |= clock_source;															// 选择时钟源 	
	REG_LPTIM2_ARR1 = time;																	// 设置高低位目标寄存器的值
}

/*******************************************************************
* function		: lptimer2_pwm_init
* description	: lptimer2_pwm_init    duty cyle（占空比） = (cmp / target) * 100% 
* input			: uint32_t cmp:             计数比较值			
*				  uint32_t target:          计数目标值
*            	  uint32_t clock_div  ：    计数分频值
*            	  uint32_t clock_source  ： 计数时钟来源
* return		: none
********************************************************************/
void lptimer2_pwm_init(uint32_t cmp, uint32_t target, uint32_t clock_source, uint32_t clock_div)
{
	lptimer23_model_init();
									
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 													// 清除IO写保护 																							   
																							// PWM0                                                                     
	REG_SCU_PASEL = (REG_SCU_PASEL&(~(0xF<<4)))|(0x6<<4); 									// PA1选择LPTIM2_OUT   																	   
																							// PWM1	                                                                   
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(~(0xF<<4)))|(0xE<<4); 									// PF1选择LPTIM2_OUT 																	   
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 													// IO写保护 
									
	REG_LPTIM2_CR2 &= ~(0x00001FFF);														// 恢复默认值 
	REG_LPTIM2_CR2 |= clock_source;			         										// 选择时钟源 
	REG_LPTIM2_CR2 |= clock_div;                      										// 分频系数
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_MODE_COUNT;												// 计数模式: 连续计数模式
										
	REG_LPTIM2_CCR1 = cmp;																	// 设置高低位比较寄存器的值 
	REG_LPTIM2_CCR2 = cmp;																	// 设置高低位比较寄存器的值
	REG_LPTIM2_ARR1 = target;																// 设置高低位目标寄存器的值 
			 
	REG_LPTIM2_CCMCFG1 &= ~(0x00003F);
	REG_LPTIM2_CCMCFG2 &= ~(0x00003F);
	REG_LPTIM2_CCMCFG1 = VAL_LPTIM_CCE_ENABLE | VAL_LPTIM_CCS_PWM | VAL_LPTIM_CCP_POLAR2 ;	// 通道1PWM输出配置
	REG_LPTIM2_CCMCFG2 = VAL_LPTIM_CCE_ENABLE | VAL_LPTIM_CCS_PWM | VAL_LPTIM_CCP_POLAR2 ;	// 通道2PWM输出配置
}

/*******************************************************************
* function		: lptimer2_trigger_init
* description	: lptimer2_trigger_init Trigger触发计数初始化
* input			: uint32_t target:          计数目标值 
*            	  uint32_t clock_div  ：    计数分频值
*				  uint32_t clock_source  ： 计数时钟来源
* return		: none
********************************************************************/
void lptimer2_trigger_init(uint32_t clock_source, uint32_t clock_div, uint32_t target)
{
	lptimer23_model_init();
	
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 													// 清除IO写保护 
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(~(0xF<<12)))|(0xD<<12);   								// PF3选择LPTIM2_EXT 
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 													// IO写保护 
								
	REG_LPTIM2_CR2 &= ~(0x00001FFF);														// 恢复默认值 
	REG_LPTIM2_CR2 |= clock_source;				     										// 选择时钟源 
	REG_LPTIM2_CR2 |= clock_div;                      										// 设置时钟分频
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_MODE_COUNT;												// 计数模式  
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TMODE_TRIGGER;											// Trigger脉冲触发计数模式 
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TRIGDGE_FALL;											// 外部输入信号下降沿trigger 
	REG_LPTIM2_ARR1 = target;																// 设置高低位目标寄存器的值 
}

/*******************************************************************
* function		: lptimer2_extcount_init
* description	: lptimer2_extcount_init 外部异步脉冲计数初始化
* input			: uint32_t target:          计数目标值 
*				  uint32_t clock_div  ：    计数分频值
*				  uint32_t clock_source  ： 计数时钟来源
* return		: none
********************************************************************/
void lptimer2_extcount_init(uint32_t clock_source, uint32_t clock_div, uint32_t target)
{
	lptimer23_model_init();
	
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 														// 清除IO写保护  
	REG_SCU_PGSEL = (REG_SCU_PGSEL&(~(0xF<<4)))|(0xD<<4);   									// PG1选择LPTIM2_IN 
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 														// IO写保护
										
	REG_LPTIM2_CR2 &= ~(0x00001FFF);															// 恢复默认值 
	REG_LPTIM2_CR2 |= clock_source;				      											// 选择时钟源 
	REG_LPTIM2_CR2 |= clock_div;                      											// 分频系数
	REG_LPTIM2_ARR1 = target;																	// 设置高低位目标寄存器的值 
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TMODE_EXT;													// 选择外部异步脉冲模式
												
	REG_LPTIM2_CR2 |=  VAL_LPTIM_CR2_EDGESEL_FALL;   											// LPTIN 的上升沿计数
 
}
/*******************************************************************
* function		: lptimer2_capture_init
* description	: lptimer2_capture_init   lptimer 输入捕获初始化
* input			: uint32_t target:          计数目标值 
*				  uint32_t clock_div  ：    计数分频值
*				  uint32_t clock_source  ： 计数时钟来源
* return		: none
********************************************************************/
void lptimer2_capture_init(uint32_t target, uint32_t clock_source, uint32_t clock_div)
{
	lptimer23_model_init();
		
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 														// 清除IO写保护 	
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(~(0xF<<8)))|(0xD<<8); 										// PF2选择LPTIM2_CAP0
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 														// IO写保护 
										
	REG_LPTIM2_CR2 &= ~(0x00001FFF);															// 恢复默认值 
	REG_LPTIM2_CR2 |= clock_source;			         											// 选择时钟源 
	REG_LPTIM2_CR2 |= clock_div;                      											// 分频系数
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_MODE_COUNT;													// 计数模式: 连续计数模式
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TRIGDGE_FALL;
			 
	REG_LPTIM2_CCMCFG1 = VAL_LPTIM_CCE_ENABLE | VAL_LPTIM_CCS_CAP | VAL_LPTIM_CAPEDGE_UP_DOWN ;	// 通道1输入捕获配置
	REG_LPTIM2_ARR1 = target;								                                    // 设置高低位目标寄存器的值 

}

/*******************************************************************
* function		: lptimer2_time_out_init
* description	: lptimer2_time_out_init lptimer2 超时退出初始化
* input			: uint32_t target:          计数目标值   
*				  uint32_t clock_div  ：    计数分频值 
*				  uint32_t clock_source  ： 计数时钟来源
* return		: none
********************************************************************/
void lptimer2_time_out_init(uint32_t clock_source, uint32_t clock_div, uint32_t target)
{
	lptimer23_model_init();
	
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 						    							// 清除IO写保护
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(~(0xF<<12)))|(0xD<<12);  									// PF3选择LPTIM0_EXT
							
	if(clock_source == VAL_LPTIM_CR2_CLKSEL_LPTIN)							
	{							
		REG_SCU_PGSEL = (REG_SCU_PGSEL&(~(0xF<<4)))|(0xD<<4);       							// PG1选择LPTIM2_IN 
	}											
								
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 														// IO写保护 
									
	REG_LPTIM2_CR2 &= ~(0x00001FFF);															// 恢复默认值 
	REG_LPTIM2_CR2 |= clock_source;				         										// 时钟源选择 
	REG_LPTIM2_CR2 |= clock_div;                    											// 设置时钟分频
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_MODE_COUNT;													// 计数模式 
	REG_LPTIM2_ARR1 = target;																	// 设置高低位目标寄存器的值 
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TMODE_TIMEOUT;												// 模式选择 	
	REG_LPTIM2_CR2 |= VAL_LPTIM_CR2_TRIGDGE_FALL;												// 外部触发边沿选择			
}

/*******************************************************************
* function		: lptimer2_irq_init
* description	: lptimer2_irq_init 中断初始化
* input			: uint8_t irq_enable :中断开关
*				  uint32_t irq_type : 中断类型
*				  void (*pfunc)() : 中断回调函数
* return		: none
********************************************************************/
void lptimer2_irq_init(uint8_t irq_enable, uint32_t irq_type, void (*pfunc)()) 
{
	if(irq_enable == VAL_LPTIM_IRQ_ENABLE)				    									//中断使能
	{                                                   									
		NVIC_ClearPendingIRQ(LPTIMER23_IRQn);            									
		NVIC_EnableIRQ(LPTIMER23_IRQn);                  									
																							
		if(irq_type == VAL_LPTIM2_IER_UIE)         												
		{                                               									
			REG_LPTIM23_IER |= VAL_LPTIM2_IER_UIE;		    									//计数器溢出中断使能
			lptimer2func[0] = pfunc;                        									    
		}                                                   									    
		if(irq_type == VAL_LPTIM2_IER_CC1IE)  													
		{                                                   									    
			REG_LPTIM23_IER |= VAL_LPTIM2_IER_CC1IE;											//比较/捕获通道1中断使能
			lptimer2func[1] = pfunc;                        									    
		}                                                   									    
		if(irq_type == VAL_LPTIM2_IER_CC2IE)  													
		{                                                   									    
			REG_LPTIM23_IER |= VAL_LPTIM2_IER_CC2IE;											//比较/捕获通道2中断使能
			lptimer2func[2] = pfunc;                    									
		}                                               									
		if(irq_type == VAL_LPTIM2_IER_TIE)  													
		{                                                   									    
			REG_LPTIM23_IER |= VAL_LPTIM2_IER_TIE;												//外部触发到来中断使能
			lptimer2func[3] = pfunc;                    									
		}                                               									
	}                                                   									
	else                                                									
	{		                                            									
		if(irq_type == VAL_LPTIM2_IER_UIE) 				 									
		{                                                   									 
			REG_LPTIM23_IER &= ~(VAL_LPTIM2_IER_UIE); 											//计数器溢出中断不使能
			lptimer2func[0] = NULL;                     										        
		}                                               										        
		if(irq_type == VAL_LPTIM2_IER_CC1IE)            										 	
		{                                               										        
			REG_LPTIM23_IER &= ~(VAL_LPTIM2_IER_CC1IE);											//比较/捕获通道1中断不使能
			lptimer2func[1] = NULL;                     										        
		}                                               										        
		if(irq_type == VAL_LPTIM2_IER_CC2IE)            										 	
		{                                               										        
			REG_LPTIM23_IER &= ~(VAL_LPTIM2_IER_CC2IE);											//比较/捕获通道2中断不使能
			lptimer2func[2] = NULL;                     										
		}                                               										
		if(irq_type == VAL_LPTIM2_IER_TIE)  														
		{                                               										        
			REG_LPTIM23_IER |= VAL_LPTIM2_IER_TIE;												//外部触发到来中断不使能
			lptimer2func[3] = NULL;									
		}
		
		NVIC_ClearPendingIRQ(LPTIMER23_IRQn);                                                   //清除中断      
		NVIC_DisableIRQ(LPTIMER23_IRQn);                                                        //中断禁止
	}
}

/*******************************************************************
* function		: lptimer2_start
* description	: enable lptimer2 count
* input			: none
* return		: none
********************************************************************/
void lptimer2_start(void)
{
	REG_LPTIM2_CR1 |= VAL_LPTIM_CR1_ENABLE;														// 打开LPTEN使能位，启动计数器
}

/*******************************************************************
* function		: lptimer2_stop
* description	: disable lptimer count
* input			: none
* return		: none
********************************************************************/
void lptimer2_stop(void)
{
	REG_LPTIM2_CR1 &= ~VAL_LPTIM_CR1_ENABLE;													// 关闭LPTEN使能位，关闭计数器
}

//////////////////////////////////////////////////////////////////////////LPTIMER3///////////////////////////////////////////////////////////////////////

/*******************************************************************
* function		: lptimer3_count_init
* description	: lptimer3_count_init  	LPTimer3定时初始化
* input			: uint32_t clock_source	时钟源选择
*				  uint32_t clock_div	时钟源分频
*             	  uint32_t time			定时时间        	  
* return		: none
********************************************************************/
void lptimer3_count_init(uint32_t clock_source, uint32_t clock_div, uint32_t time)
{
	lptimer23_model_init();                             										//lptimer3 模块时钟初始化
														
	REG_LPTIM3_CR4 &= ~(0x00001FFF);															// 恢复默认值 
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TMODE_TIME;													// 设置工作模式 
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_MODE_COUNT;													// 计数模式 
	REG_LPTIM3_CR4 |= clock_div;																// 设置分频值2分频
	REG_LPTIM3_CR4 |= clock_source;																// 选择时钟源 		 
	REG_LPTIM3_ARR2 = time;																		// 设置高低位目标寄存器的值
}

/*******************************************************************
* function		: lptimer3_pwm_init
* description	: lptimer3_pwm_init  duty cyle（占空比） = (cmp / target) * 100% 
* input			: uint32_t cmp: 			计数器比较值 			
*				  uint32_t target:			计数器目标值 
*            	  uint32_t clock_div:		计数器时钟分频值
*            	  uint32_t clock_source:	计数器时钟来源
* return		: none
********************************************************************/
void lptimer3_pwm_init(uint32_t cmp, uint32_t target, uint32_t clock_source, uint32_t clock_div)
{
	lptimer23_model_init();                                     									//lptimer3 模块时钟初始化
											
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 															// 清除IO写保护 															
	REG_SCU_PGSEL = (REG_SCU_PGSEL&(~(0xF<<12)))|(0xF<<12); 										// PG3选择LPTIM3_OUT PWM0										
	REG_SCU_PASEL = (REG_SCU_PASEL&(~(0xF<<24)))|(0xF<<24); 										// PA6选择LPTIM3_OUT PWM1
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 															// IO写保护 
												
	REG_LPTIM3_CR4 &= ~(0x00001FFF);																// 恢复默认值 
	REG_LPTIM3_CR4 |= clock_source;			         												// 选择时钟源 
	REG_LPTIM3_CR4 |= clock_div;                      												// 分频系数
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_MODE_COUNT;														// 计数模式: 连续计数模式
													
	REG_LPTIM3_CCR3 = cmp;																			// 设置高低位比较寄存器的值
	REG_LPTIM3_CCR4 = cmp;																			// 设置高低位比较寄存器的值	
	REG_LPTIM3_ARR2 = target;																		// 设置高低位目标寄存器的值 
					
	REG_LPTIM3_CCMCFG3 &= ~(0x00003F);		
	REG_LPTIM3_CCMCFG4 &= ~(0x00003F);		
	REG_LPTIM3_CCMCFG3 = VAL_LPTIM_CCE_ENABLE | VAL_LPTIM_CCS_PWM | VAL_LPTIM_CCP_POLAR2 ;			// 通道1PWM输出配置
	REG_LPTIM3_CCMCFG4 = VAL_LPTIM_CCE_ENABLE | VAL_LPTIM_CCS_PWM | VAL_LPTIM_CCP_POLAR2 ;			// 通道2PWM输出配置
}

/*******************************************************************
* function		: lptimer3_trigger_init
* description	: lptimer3_trigger_init Trigger触发计数初始化
* input			: uint32_t target:			计数器目标值 
*            	  uint32_t clock_div:		计数器时钟分频值
*				  uint32_t clock_source:	计数器时钟来源
* return		: none
********************************************************************/
void lptimer3_trigger_init(uint32_t clock_source, uint32_t clock_div, uint32_t target)
{
	lptimer23_model_init();                                                         				//lptimer3 模块时钟初始化 
					
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 						                    				// 清除IO写保护 
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(uint32_t)(~(0xF<<28)))|(uint32_t)(0xD<<28);   					// PF7选择LPTIM3_EXT			
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 						                    				// IO写保护 
					
	REG_LPTIM3_CR4 &= ~(0x00001FFF);																// 恢复默认值 
	REG_LPTIM3_CR4 |= clock_source;				     												// 选择时钟源 
	REG_LPTIM3_CR4 |= clock_div;                      												// 设置时钟分频
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_MODE_COUNT;														// 计数模式  
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TMODE_TRIGGER;													// Trigger脉冲触发计数模式 
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TRIGDGE_FALL;													// 外部输入信号下降沿trigger 
	REG_LPTIM3_ARR2= target;																		// 设置高低位目标寄存器的值 
}

/*******************************************************************
* function		: lptimer3_extcount_init
* description	: lptimer3_extcount_init 外部异步脉冲计数初始化
* input			: uint32_t target:			计数器目标值 
*				  uint32_t clock_div:		计数器时钟分频值
*				  uint32_t clock_source:	计数器时钟来源
* return		: none
********************************************************************/
void lptimer3_extcount_init(uint32_t clock_source, uint32_t clock_div, uint32_t target)
{
	lptimer23_model_init();                                 										//lptimer3 模块时钟初始化
											
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 															// 清除IO写保护  
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(~(0xF<<12)))|(0xF<<12); 										// PF3选择LPTIM3_IN 	 
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 															// IO写保护
											
	REG_LPTIM3_CR4 &= ~(0x00001FFF);																// 恢复默认值 
	REG_LPTIM3_CR4 |= clock_source;				      												// 选择时钟源 
	REG_LPTIM3_CR4 |= clock_div;                      												// 分频系数
	REG_LPTIM3_ARR2 = target;																		// 设置高低位目标寄存器的值 
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TMODE_EXT;		    											// 选择外部异步脉冲模式
														
	REG_LPTIM3_CR4 |=  VAL_LPTIM_CR2_EDGESEL_FALL;   												// LPTIN 的上升沿计数
 
}
/*******************************************************************
* function		: lptimer3_capture_init
* description	: lptimer3_capture_init 
* input			: uint32_t target:			计数器目标值 
*				  uint32_t clock_div:		计数器时钟分频值
*				  uint32_t clock_source:	计数器时钟来源
* return		: none
********************************************************************/
void lptimer3_capture_init(uint32_t target, uint32_t clock_source, uint32_t clock_div)
{
	lptimer23_model_init();                                     									//lptimer3 模块时钟初始化
											
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 															// 清除IO写保护 										
	REG_SCU_PGSEL = (REG_SCU_PGSEL&(~(0xF<<0)))|(0xF<<0); 											// PG0选择LPTIM3_CAP1
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 															// IO写保护 
											
	REG_LPTIM3_CR4 &= ~(0x00001FFF);																// 恢复默认值 
	REG_LPTIM3_CR4 |= clock_source;			         												// 选择时钟源 
	REG_LPTIM3_CR4 |= clock_div;                      												// 分频系数
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_MODE_COUNT;														// 计数模式: 连续计数模式
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TRIGDGE_FALL;
			 
	REG_LPTIM3_CCMCFG4 = VAL_LPTIM_CCE_ENABLE | VAL_LPTIM_CCS_CAP | VAL_LPTIM_CAPEDGE_DOWN ;		// 通道2输入捕获配置
	REG_LPTIM3_ARR2 = target;								    									// 设置高低位目标寄存器的值 

}

/*******************************************************************
* function		: lptimer3_time_out_init
* description	: lptimer3_time_out_init lptimer3超时退出初始化
* input			: uint32_t target:			计数器目标值 
*				  uint32_t clock_div:		计数器时钟分频值
*				  uint32_t clock_source:	计数器时钟来源
* return		: none
********************************************************************/
void lptimer3_time_out_init(uint32_t clock_source, uint32_t clock_div, uint32_t target)
{
	lptimer23_model_init();                                                         				//lptimer3 模块时钟初始化
					
	REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 						                    				// 清除IO写保护
	REG_SCU_PFSEL = (REG_SCU_PFSEL&(uint32_t)(~(0xF<<28)))|(uint32_t)(0xD<<28);   					// PF7选择LPTIM3_EXT
					
	if(clock_source == VAL_LPTIM_CR2_CLKSEL_LPTIN)				
	{				
		REG_SCU_PFSEL = (REG_SCU_PFSEL&(~(0xF<<12)))|(0xF<<12);                     				// PF3选择LPTIM3_IN 					  				
	}								
					
	REG_SCU_IOCTRLPROTECT = 0xFFFFFFFF; 															// IO写保护 
											
	REG_LPTIM3_CR4 &= ~(0x00001FFF);																// 恢复默认值 
	REG_LPTIM3_CR4 |= clock_source;				         											// 时钟源选择 
	REG_LPTIM3_CR4 |= clock_div;                    												// 设置时钟分频
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_MODE_COUNT;														// 计数模式 
	REG_LPTIM3_ARR2 = target;																		// 设置高低位目标寄存器的值 
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TMODE_TIMEOUT;													// 模式选择 	
	REG_LPTIM3_CR4 |= VAL_LPTIM_CR2_TRIGDGE_FALL;													// 外部触发边沿选择			
}

/*******************************************************************
* function		: lptimer3_irq_init
* description	: lptimer3_irq_init 中断初始化
* input			: uint8_t irq_enable:中断开关
*				  uint32_t irq_type:中断类型
*				  void (*pfunc)():中断回调函数
* return		: none
********************************************************************/
void lptimer3_irq_init(uint8_t irq_enable, uint32_t irq_type, void (*pfunc)()) 
{
	if(irq_enable == VAL_LPTIM_IRQ_ENABLE)															//中断使能
	{										
		NVIC_ClearPendingIRQ(LPTIMER23_IRQn);										
		NVIC_EnableIRQ(LPTIMER23_IRQn);										
												
		if(irq_type == VAL_LPTIM3_IER_UIE)         													
		{										
			REG_LPTIM23_IER |= VAL_LPTIM3_IER_UIE;													//计数器溢出中断使能
			lptimer3func[0] = pfunc;                        										    
		}                                                   										    
		if(irq_type == VAL_LPTIM3_IER_CC1IE)  														
		{                                                   										    
			REG_LPTIM23_IER |= VAL_LPTIM3_IER_CC1IE;												//比较/捕获通道1中断使能
			lptimer3func[1] = pfunc;                        										    
		}                                                   										    
		if(irq_type == VAL_LPTIM3_IER_CC2IE)  														
		{                                                   										    
			REG_LPTIM23_IER |= VAL_LPTIM3_IER_CC2IE;												//比较/捕获通道2中断使能
			lptimer3func[2] = pfunc;										
		}										
		if(irq_type == VAL_LPTIM3_IER_TIE)  														
		{                                                   										    
			REG_LPTIM23_IER |= VAL_LPTIM3_IER_TIE;													//外部触发到来中断使能
			lptimer3func[3] = pfunc;										
		}
	}
	else
	{		
		if(irq_type == VAL_LPTIM3_IER_UIE) 				 
		{                                                    
			REG_LPTIM23_IER &= ~(VAL_LPTIM3_IER_UIE); 												//计数器溢出中断不使能
			lptimer3func[0] = NULL;                    												       
		}                                              												       
		if(irq_type == VAL_LPTIM3_IER_CC1IE)           												 
		{                                              												       
			REG_LPTIM23_IER &= ~(VAL_LPTIM3_IER_CC1IE);												//比较/捕获通道1中断不使能
			lptimer3func[1] = NULL;                    												       
		}                                              												       
		if(irq_type == VAL_LPTIM3_IER_CC2IE)           												 
		{                                              												       
			REG_LPTIM23_IER &= ~(VAL_LPTIM3_IER_CC2IE);												//比较/捕获通道2中断不使能
			lptimer3func[2] = NULL;                    												
		}                                              												
		if(irq_type == VAL_LPTIM3_IER_TIE)  															
		{                                              												       
			REG_LPTIM23_IER |= VAL_LPTIM3_IER_TIE;													//外部触发到来中断不使能
			lptimer3func[3] = NULL;														
		}
		
		NVIC_ClearPendingIRQ(LPTIMER23_IRQn);                                                       //中断清除
		NVIC_DisableIRQ(LPTIMER23_IRQn);                                                            //中断禁止
	}
}

/*******************************************************************
* function		: lptimer3_start
* description	: enable lptimer3 count
* input			: none
* return		: none
********************************************************************/
void lptimer3_start(void)
{
	REG_LPTIM3_CR3 |= VAL_LPTIM_CR1_ENABLE;															// 打开LPTEN使能位，启动计数器
}

/*******************************************************************
* function		: lptimer3_stop
* description	: disable lptimer3 count
* input			: none
* return		: none
********************************************************************/
void lptimer3_stop(void)
{
	REG_LPTIM3_CR3 &= ~VAL_LPTIM_CR1_ENABLE;														// 关闭LPTEN使能位，关闭计数器
}

