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

void (*opa_recv_callback)(void) = NULL;

/************************************************************************
 * function   	: OPA_IRQHandler
 * Description	: OPA_IRQHandler
 * input		: none
 * output		: none   
 * return		: none
 ************************************************************************/
void ANALOG_IRQHandler(void)
{
	if(REG_SCU_ANALOGSTATUS & 0x10000)       	//cmp 中断 
	{
		if(opa_recv_callback!= NULL)
		{
			(*opa_recv_callback)();
		}	
		REG_SCU_ANALOGSTATUS |= (0x10000);	//清除cmp中断标志
	}
	REG_SCU_ANALOGSTATUS |= 0x10000; 		//  清除中断状态
}

/************************************************************************
 * function		: opa_init
 * Description	: opa_init
 * input  		: mode    1  单倍输出   0多倍输出
 * output		: none   
 * return		: none
 ************************************************************************/
void opa_init(uint8_t mode)
{
	REG_SCU_IOCTRLPROTECT = 0xa5a55a5a;				

	REG_SCU_PADADS = (REG_SCU_PADADS&(~(0x3<<3)))|(3<<3); 					  //将PA3（OPA_P0）、PA4(OPA_N0)配置成模拟接口
	
	REG_SCU_IOCTRLPROTECT = 0xffffffff;
	REG_SCU_OPACFG &= ~(0x00000FFF);
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<1)))|(1<<1); 					  //OPA功能使能
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<4)))|(1<<4);	            	  //opa输出使能PB2
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x3<<5)))|(1<<5); 					  //OPA正端选择OPA_P0

	if(mode == MULT_MODE)
	{
	   REG_SCU_OPACFG &= ~(3<<2); 								              //OPA负端选择OPA_N0
	}
	
	else if(mode == ADC_MODE)
	{
		REG_SCU_OPACFG &= ~(3<<5);											  //OPA正端内部接ADC输入
		REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x3<<2)))|(3<<2); 				  //OPA负端通过内部连接输出
		REG_ADC_TCRL |= (1<<0);												  //ADC输入通道使能OPA缓冲
	}
	else  			//SINGLE_MODE
	{
		REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x3<<2)))|(3<<2); 				  //OPA负端通过内部连接输出
	}
}

/************************************************************************
 * function   	: opa_cmp_init
 * Description	: opa_cmp_init
 * input  		: none
 * output		: none   
 * return		: none
 ************************************************************************/
void opa_cmp_init(void)
{
	REG_SCU_IOCTRLPROTECT = 0xa5a55a5a;				
	REG_SCU_PADADS = (REG_SCU_PADADS&(~(0x3<<3)))|(3<<3); 						//将PA3（OPA_P0）、PA4(OPA_N0)配置成模拟接口
	
	REG_SCU_OPACFG &= ~(0x00000FFF);
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<1)))|(1<<1); 						//OPA功能使能
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<4)))|(0<<4);	            		//opa输出使能
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<5)))|(1<<5); 						//OPA正端选择OPA_P0
	REG_SCU_OPACFG &= ~(3<<2); 								                    //OPA负端选择OPA_N0
	
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<0)))|(1<<0); 						//opa作为cmp功能使能
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<8)))|(1<<8); 						//cmp极性选择
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x3<<9)))|(0<<9); 						//opa作为cmp比较器滤波时间设置
	REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<11)))|(1<<11);      				//opa作为比较器滤波使能
	
	REG_SCU_IOCTRLPROTECT = 0xffffffff;
}

/************************************************************************
 * function   	: opa_irq_init
 * Description	: opa_irq_init
 * input  		: void (*pfunc)() opa中断回调函数
 * output		: none   
 * return		: none
 ************************************************************************/
void opa_irq_init(uint8_t irq_enable, void (*pfunc)())
{
	if(irq_enable == OPA_IRQ_ENABLE)
	{
		NVIC_ClearPendingIRQ(ANALOG_IRQn);
		NVIC_EnableIRQ(ANALOG_IRQn);
		
		REG_SCU_OPACFG = (REG_SCU_OPACFG&(~(0x1<<7)))|(1<<7); 		//cmp中断使能
		opa_recv_callback = pfunc;
	}
	else
	{
		REG_SCU_OPACFG &= ~(1<<7); 									//cmp中断失能
		opa_recv_callback = NULL;
	}
}
