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


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

/************************************************************************
 * function   : ANALOG_IRQHandler
 * description: ANALOG_IRQHandler 
 * input      : none
 * return     : none
 ************************************************************************/
void ANALOG_IRQHandler(void)
{
	//cmp0中断处理
	if((REG_SCU_ANALOGSTATUS & 0x10) == 0x10)
	{
		if(cmp_callback_func[0]!= NULL)
		{
			(*cmp_callback_func[0])();
		}
		REG_SCU_ANALOGSTATUS |=(1<<4) ;  
	}
	//cmp1中断处理
	else if((REG_SCU_ANALOGSTATUS & 0x100) == 0x100)
	{
		if(cmp_callback_func[1]!= NULL)
		{
			(*cmp_callback_func[1])();
		}
		REG_SCU_ANALOGSTATUS |=(1<<8) ;  
	}
	//cmp2中断处理
	else if((REG_SCU_ANALOGSTATUS & 0x1000) == 0x1000)
	{
		if(cmp_callback_func[2]!= NULL)
		{
			(*cmp_callback_func[2])();
		}		
		REG_SCU_ANALOGSTATUS |=(1<<12) ;  
	}
	else
	{
	    REG_SCU_ANALOGSTATUS = 0xffffff ; 
	}
}	
/************************************************************************
 * function   : cmp_init
 * description: cmp_init
 * input 	  : uint8_t cmpx :选择所要使用cmp
 * return     : none
 ************************************************************************/
void cmp_init(uint8_t cmpx)
{
	switch(cmpx)
	{
		case USED_CMP0:
			REG_SCU_IOCTRLPROTECT = 0xA5A55A5A;                           //清除IO写保护
			REG_SCU_PADADS = (REG_SCU_PADADS&(~(0x3<<24)))|(0X3<<24);	  //PD0-PD1 配置为模拟接口
			REG_SCU_PASEL = (REG_SCU_PASEL&(~(0x4<<16)))|(4<<16);		  //PA4 配置为cmp0_out
			REG_SCU_IOCTRLPROTECT = 0xffffffff;                           //开启IO写保护
			
//			REG_EFC_COMP0TRIM = 0x0;             						  //cmp0精度调整 根据实际测试填写一般不需要校准
			REG_SCU_CMPCFG |=(1<<6);   		     						  //cmp0极性选择 p端电压高时输出1
			REG_SCU_CMPCFG |=(2<<3);  			 						  //cmp0负端信号选择cmp0inn	 
			REG_SCU_CMPCFG |=(1<<5); 			 						  //cmp0正端信号选择cmp0_inp	
			REG_SCU_CMPCFG |=(1<<1);   			 						  //cmp0使能		
			break;
		case USED_CMP1:
			REG_SCU_IOCTRLPROTECT = 0xA5A55A5A; 						  //清除IO写保护
			REG_SCU_PADADS = (REG_SCU_PADADS&(~(0x3<<28)))|(0X3<<26);	  //PD2-PD3 配置为模拟接口
			REG_SCU_PASEL = (REG_SCU_PASEL&(~(0x6<<24)))|(6<<24);		  //PA6	配置为cmp1_out
			REG_SCU_IOCTRLPROTECT = 0xffffffff;                           //开启IO写保护	
		
//			REG_EFC_COMP1TRIM = 0xc;    								  //cmp1精度调整 根据实际测试填写一般不需要校准
			REG_SCU_CMPCFG |=(3<<13);   								  //cmp1负端信号选择cmp1inn	 
			REG_SCU_CMPCFG |=(1<<15);   								  //cmp1正端信号选择cmp1_inp	
			REG_SCU_CMPCFG |=(1<<16);   								  //cmp1极性选择 p端电压高时输出1	
			REG_SCU_CMPCFG |=(1<<11);   								  //cmp1使能		
			break;
		case USED_CMP2:
			REG_SCU_IOCTRLPROTECT = 0xA5A55A5A;                           //清除IO写保护
			REG_SCU_PADADS = (REG_SCU_PADADS&(~(0x3F<<24)))|(0X3F<<24);	  //PD4-PD5 配置为模拟接口
			REG_SCU_PBSEL = (REG_SCU_PBSEL&(~(0x6<<28)))|(6<<28);		  //PB6  配置为cmp2_out
			REG_SCU_IOCTRLPROTECT = 0xffffffff;                           //开启IO写保护
		
//			REG_EFC_COMP2TRIM = 0xc;									  //cmp2精度调整	根据实际测试填写一般不需要校准
			REG_SCU_CMPCFG |=(3<<23);   								  //cmp2负端信号选择cmp2inn	 
			REG_SCU_CMPCFG |=(1<<25);   								  //cmp2正端信号选择cmp2_inp	
			REG_SCU_CMPCFG |=(1<<26);   								  //cmp2极性选择 p端电压高时输出1		
			REG_SCU_CMPCFG |=(1<<21);   								  //cmp2使能		
			break;
		default:
			break;
		
	
	}

}
/************************************************************************
 * function   : cmp_irq_init
 * description: cmp_irq_init cmp中断配置函数
 * input 	  : uint8_t cmpx 				：cmpx中断选择
			    uint8_t irq_enable			：中断使能与否
			    void (*cmp_callback_fun)()	：中断回调函数
 * return	  : none
 ************************************************************************/
void cmp_irq_init(uint8_t cmpx,uint8_t irq_enable,void (*cmp_callback_fun)())
{	
	if(irq_enable == CMP_IRENABLE)            							//中断使能
	{			
		switch(cmpx)
		{
			
			case USED_CMP0:
				REG_SCU_COMPINEN  |=(1<<0);   							//cmp0中断使能
				cmp_callback_func[0]=cmp_callback_fun;
				break;
			case USED_CMP1:
				REG_SCU_COMPINEN  |=(1<<1);   							//cmp1中断使能
				cmp_callback_func[1]=cmp_callback_fun;
				break;
			case USED_CMP2:
				REG_SCU_COMPINEN  |=(1<<2);  						    //cmp2中断使能
				cmp_callback_func[2]=cmp_callback_fun;
				break;
			default:
				break;
		}
		NVIC_EnableIRQ(ANALOG_IRQn);
		NVIC_ClearPendingIRQ(ANALOG_IRQn);
		clean_cmp_enentstatus();	        						    //清除中断标志
				
	}
	else
	{
		REG_SCU_COMPINEN  &=~(7<<0);         						    //cmp0-2：中断失能
		NVIC_DisableIRQ(ANALOG_IRQn);
		NVIC_ClearPendingIRQ(ANALOG_IRQn);
		
		cmp_callback_func[0]=NULL;
		cmp_callback_func[1]=NULL;
		cmp_callback_func[2]=NULL;
	
	}
}
/************************************************************************
 * function   : clean_cmp_enentstatus
 * description: 清除CMP0、1、2中断状态
 * input      : none
 * return     : none
 ************************************************************************/
void clean_cmp_enentstatus(void)
{
	uint32_t temp;
	
	temp =0x1110;
	
	REG_SCU_ANALOGSTATUS = temp;	
}
/************************************************************************
 * function   : get_acmp_enentstatus
 * description: 返回模拟状态寄存器值
 * input      : none
 * return     : none
 ************************************************************************/
uint32_t get_acmp_enentstatus(void)
{
	uint32_t status;
	
	status = REG_SCU_ANALOGSTATUS ;
	
	return status;
}

