/**
  ******************************************************************************
  * @file    kpm32xx_ddl_cmp.c
  * @author  Kiwi Software Team
  * @brief   CMP DDL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of CMP peripheral:
  *          + Initialization and Configuration functions
  *    
  * @note
  *          V1.0.0, 2025/1/6.
  *
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *
  *   3. Neither the name of the copyright holder nor the names of its contributors
  *      may be used to endorse or promote products derived from this software without
  *      specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  ******************************************************************************
  */

#include "kpm32xx_ddl.h"


#ifdef DDL_CMP_MODULE_ENABLED


/**
  * @brief  CMP init
  * @param  CMPx     pointer to a ACMP_Type structure.
			outPol  cmp out polar
			edgeSel cmp edge detection
			edgePol cmp edge polar
			hySel   cmp hysteresis select
  * @retval None
  */
void DDL_CMP_Init(ACMP_Type *CMPx, CMP_OutPol_T outPol, CMP_EdgeDet_T edgeSel , CMP_EdgePol_T edgePol,CMP_HySel_T hySel)
{
	uint32_t tmp = 0;
	tmp |= (hySel << ACMP_CMPx_CTRL_HYSEL_Pos);
	tmp |= (edgeSel << ACMP_CMPx_CTRL_EDG_DET_EN_Pos);
	tmp |= (edgePol << ACMP_CMPx_CTRL_EDG_POL_EN_Pos);
	tmp |= (outPol << ACMP_CMPx_CTRL_OUT_POL_Pos);
	CMPx->ACMP_CTRL = tmp;
}


/**
  * @brief  CMP init
  * @param  CMPx     pointer to a ACMP_Type structure.
			pSel  cmp p select pin
			pASel cmp p select pin enable
			nSel  cmp n select pin
			nASel cmp n select pin enable
  * @retval None
  */
void DDL_CMP_PNSel(ACMP_Type *CMPx, CMP_P_Select_T pSel, CMP_P_ASelect_T pASel , CMP_N_Select_T nSel,CMP_N_ASelect_T nASel)
{
	CMPx->ACMP_PN_SEL = nSel | (pSel<<16);
	CMPx->ACMP_ASEL   = nASel| (pASel<<16);
}



/**
  * @brief  CMP enable
  * @param  CMPx     pointer to a ACMP_Type structure.
  * @retval None
  */
void DDL_CMP_Enable(ACMP_Type *CMPx)
{
	  SET_BIT(CMPx->ACMP_CTRL , ACMP_CMPx_CTRL_EN);
}


/**
  * @brief  CMP disable
  * @param  CMPx     pointer to a ACMP_Type structure.
  * @retval None
  */
void DDL_CMP_Disable(ACMP_Type *CMPx)
{
	   CLEAR_BIT(CMPx->ACMP_CTRL, ACMP_CMPx_CTRL_EN);
}


/**
  * @brief  CMP interrupt enable
  * @param  CMPx     pointer to a ACMP_Type structure.
  * @retval None
  */
void DDL_CMP_IntEnable(ACMP_Type *CMPx)
{
	  SET_BIT(CMPx->ACMP_CTRL , ACMP_CMPx_CTRL_CMPx_IE);
}


/**
  * @brief  CMP interrupt disable
  * @param  CMPx     pointer to a ACMP_Type structure.
  * @retval None
  */
void DDL_CMP_IntDisable(ACMP_Type *CMPx)
{
	  CLEAR_BIT(CMPx->ACMP_CTRL , ACMP_CMPx_CTRL_CMPx_IE);
}


/**
  * @brief  CMP filter config init
  * @param  hFilter     pointer to a CMP_Filter_Handle_T structure.
  * @retval None
  */
void DDL_CMP_Filter_StructInit(CMP_Filter_Handle_T *hFilter)
{
	hFilter->cmpFilterEnable = 0;
	hFilter->cmpFilterWind   = 0;
	hFilter->cmpFilterNum    = 0;
	hFilter->cmpFilterDiv    = 0;
}


/**
  * @brief  CMP filter config
  * @param  CMPx     pointer to a ACMP_Type structure.
  * @retval None
  */
void DDL_CMP_Filter_Config(ACMP_Type *CMPx, CMP_Filter_Handle_T *hFilter)
{
	uint32_t tmp = 0, tmp1 = 0;
	
	/* filter config*/
	tmp |= (hFilter->cmpFilterDiv <<ACMP_CMPx_FLT_CTRL_DIV_Pos);
	tmp |= (hFilter->cmpFilterNum <<ACMP_CMPx_FLT_CTRL_NUM_Pos);
	tmp |= (hFilter->cmpFilterWind<<ACMP_CMPx_FLT_CTRL_WIND_Pos);
	CMPx->ACMP_FLT_CTRL = tmp;
	
	/* filter enable */
	tmp1 = CMPx->ACMP_CTRL;
	tmp1 |= hFilter->cmpFilterEnable << ACMP_CMPx_CTRL_FLT_EN_Pos;
	CMPx->ACMP_CTRL = tmp1;
}


/**
  * @brief  CMP output mode select
  * @param  CMPx   : pointer to a ACMP_Type structure.
  * @param  source: 0 EBUS
  *                 1 PIN
  *                 2 TIM
  * @param  mode:   0 async output 
  *                 1 sync output
  *                 2 filter output
  *                 3 edge output
  */
void DDL_CMP_Output_Mode_Select(ACMP_Type *CMPx, uint8_t source, uint8_t mode)
{
	uint32_t tmp = 0;
	tmp = CMPx->ACMP_CTRL;
	switch(source)
	{
		case 0: /*EBUS*/
			tmp |= mode << ACMP_CMPx_CTRL_EOUT_SEL_Pos;
			MODIFY_REG(CMPx->ACMP_CTRL, ACMP_CMPx_CTRL_EOUT_SEL, tmp);
			break;
		case 1: /*PIN*/
			tmp |= mode << ACMP_CMPx_CTRL_POUT_SEL_Pos;
			MODIFY_REG(CMPx->ACMP_CTRL, ACMP_CMPx_CTRL_POUT_SEL, tmp);
			break;
		case 2: /*TIM*/
			tmp |= mode << ACMP_CMPx_CTRL_TOUT_SEL_Pos;
			MODIFY_REG(CMPx->ACMP_CTRL, ACMP_CMPx_CTRL_TOUT_SEL, tmp);
			break;
	}
}


/**
  * @brief  CMP filter config init
  * @param  hdac     pointer to a DAC_InitTypeDef structure.
  * @retval None
  */
void DDL_DAC_Init_StructInit(DAC_InitTypeDef *hdac)
{
	hdac->ebusChannelSel = 0;
	hdac->dacRampTrigger = 0;
	hdac->dacRampMode    = 0;
	hdac->dacRampEnable  = 0;
	hdac->dacMD          = 0;
	hdac->dacEnable      = 1;
}


/**
  * @brief  use to config counter mode para
  * @param  CMPx     pointer to a ACMP_Type structure.
  * @param  hdac	 pointer to a DAC_InitTypeDef to config parameter
  * @retval NULL
  */
void DDL_DAC_Init(ACMP_Type *CMPx, DAC_InitTypeDef *hdac)
{
	uint32_t tmp = 0;
	tmp = 0;
	
	tmp |= (hdac->ebusChannelSel << DAC_CTRL_EBUS_SEL_Pos);
	tmp |= (hdac->dacRampTrigger << DAC_CTRL_RAMP_TRG_Pos);
	tmp |= (hdac->dacRampMode << DAC_CTRL_RAMP_MD_Pos);
	tmp |= (hdac->dacRampEnable << DAC_CTRL_RAMP_EN_Pos);
	tmp |= (hdac->dacMD << DAC_CTRL_DACx_MD_Pos);
	tmp |= (hdac->dacEnable << DAC_CTRL_DACx_EN_Pos);
	CMPx->DAC_CTRL = tmp;
}


/**
  * @brief  dac value write
  * @param  CMPx   : pointer to a ACMP_Type structure.
  * @retval dacValue: write data int dac value  
  */
void DDL_DAC_Value(ACMP_Type *CMPx,uint32_t dacValue)
{
	MODIFY_REG(CMPx->DAC_VAL_T,0xfff, dacValue);
}


/**
  * @brief  dac value write
  * @param  CMPx   : pointer to a ACMP_Type structure.
  * @retval dacValue: write data int dac ramp value  
  */
void DDL_DAC_Ramp_Value(ACMP_Type *CMPx,uint32_t dacValue)
{
	MODIFY_REG(CMPx->DAC_VAL_T, 0xfff << DAC_VAL_B_Pos, dacValue << DAC_VAL_B_Pos);
}


/**
  * @brief  dac ramp para config
  * @param  hCMP   : pointer to a CMP_Handle_T structure.
  * @retval dly: write data int dac ramp dly  para
			step: write data int dac ramp step para
			slope: write data int dac ramp slope para
  */
void DDL_DAC_Ramp_Config(ACMP_Type *CMPx,uint32_t dly,uint32_t step,uint32_t slope)
{
	CMPx->DAC_RAMP_DLY_R = dly << DAC_RAMP_DLY_B_Pos;
	CMPx->DAC_RAMP_STEP_R = step << DAC_RAMP_STEP_B_Pos;
	CMPx->DAC_RAMP_SLOPE_R = slope << DAC_RAMP_SLOPE_B_Pos;
}

#endif /* DDL_CMP_MODULE_ENABLED */




