/**
 *******************************************************************************
 * @file    dpm32m0xx_acmp.c.
 *
 * @brief   Source file for ACMP firmware driver.
 *          This file provides firmware functions to manage the following
 *          functionalities of the Analog Comparator (ACMP) peripheral:
 *           + Initialization and Configuration
 *           + Filter Configuration
 *           + Interrupts and flags management
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 * @verbatim
 ===============================================================================
                       ##### How to use this driver #####
 ===============================================================================
    [..]
      (#) Enable The ACMP interface clock using
          RCC_APBPeriphClockCmd(RCC_APB_PERIPH_ACMP, ENABLE).

      (#) Configure the positive and negative input pins of the analog
          comparator:
        (+) Enable the clock for the ACMP GPIO using the following function:
              RCC_AHBPeriphClockCmd(RCC_AHB_PERIPH_GPIO, ENABLE).
        (+) Configure these ACMP pins in analog mode using GPIO_Init() function.
        (+) Set these ACMP pins analog alternate functionin using
            GPIO_AnaAFConfig() function.

      (#) Configure the ACMP polarity, positive and negative input, filter
          and HYS using the ACMP_Init() function.

      (#) Activate the ACMP peripheral using ACMP_Cmd() function.

      (#) Get ACMP ready status using ACMP_GetReadyStatus() function.

      (#) Get ACMP compare result using ACMP_GetCompareResult() function.

      (#) ACMP interrupt configuration:
        (+) To activate the ACMP interrupt, use ACMP_IntCmd() functions.
        (+) Check on ACMP interrupt enable flags using the function
            ACMP_GetIntCmdStatus().
        (+) Check on ACMP interrupt occur flags using the function
            ACMP_GetIntFlagStatus().
        (+) Clear ACMP interrupt flags using the function ACMP_ClearIntFlag().

 * @endverbatim
 *******************************************************************************/

#include "dpm32m0xx_acmp.h"



/**
 *******************************************************************************
 * @brief   Deinitializes ACMP common registers to their default reset values.
 * @retval  None.
 ********************************************************************************/
void ACMP_COMDeInit(void)
{
  /* Set ACMP control register to reset value */
  ACMP->CR = 0x00000000UL;
#if defined(DPM32M08x) || defined(DPM32M05x) || defined(DPM32M03x) || \
    defined(DPM32M036) || defined(DPM32M030) || defined(DPM32M026) || \
    defined (DPM32T55x)
  /* Set ACMP0 cotrol register to reset value */
  ACMP->ACMP0_CFG = 0x00000000UL;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M026 || DPM32T55x */
  /* Set ACMP1 control register to reset value */
  ACMP->ACMP1_CFG = 0x00000000UL;
#if defined(DPM32M08x) || defined(DPM32M05x) || defined(DPM32M03x) 
  /* Set ACMP2 control register to reset value */
  ACMP->ACMP2_CFG = 0x00000000UL;
  /* Set ACMP3 control register to reset value */
  ACMP->ACMP3_CFG = 0x00000000UL;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */
}


/**
 *******************************************************************************
 * @brief   ACMP resistance select.
 * @param   [in]  ACMP_Res: Specifies the ACMP resistance.
 *                This parameter can be a value of @ref ACMP_ResSelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_RES_SELx: Select (2~17)/20 of the reference voltage as
 *                                      the negative input of the comparator (x=2~17).
 *                DPM32M036|DPM32M030|DPM32M015:
 *                  @arg ACMP_RES_SELx: Select x/100 of the VDD voltage as the
 *                                      negative input of the comparator (x=1~15, 20~100).
 *                DPM32M026|DPM32T55x:
 *                  @arg ACMP_RES_SELx: When selecting VREF = VDD, the voltage selection is divided into two stages:
 *                When ACMP_Res = 00000~110010, the step is 0.000016V times the reference voltage,
 *                with a linear distribution, that is, the reference voltage is (ACMP_Res) * 0.01587V.
 *                When ACMP_Res =110011~111111, the voltage reference is selected as a non-linear variation,
 *                as shown in the table below.
 *                ----------------------------------------------
 *                  RES_SEL       |         VREF = VDD
 *                ----------------------------------------------
 *                  0x00~0x32     |  0.01587 * RES_SEL * VDD
 *                ----------------------------------------------
 *                  0x33          |         0.805 * VDD
 *                ----------------------------------------------
 *                  0x34          |         0.821 * VDD
 *                ----------------------------------------------
 *                  0x35          |         0.836 * VDD
 *                ----------------------------------------------
 *                  0x36          |         0.851 * VDD
 *                ----------------------------------------------
 *                  0x37          |         0.866 * VDD
 *                ----------------------------------------------
 *                  0x38          |         0.878 * VDD
 *                ----------------------------------------------
 *                  0x39          |         0.889 * VDD
 *                ----------------------------------------------
 *                  0x3A          |         0.896 * VDD
 *                ----------------------------------------------
 *                  0x3B          |         0.903 * VDD
 *                ----------------------------------------------
 *                  0x3C          |         0.908 * VDD
 *                ----------------------------------------------
 *                  0x3D          |         0.912 * VDD
 *                ----------------------------------------------
 *                  0x3E          |         0.915 * VDD
 *                ----------------------------------------------
 *                  0x3F          |         0.919 * VDD
 *                ----------------------------------------------
 *                When selecting VREF=internal 1.2V reference voltage, the voltage changes linearly.
 *                The voltage step is 0.19V, which means the reference voltage is (ACMP_Res) * 0.19V.
 *                ----------------------------------------
 *                  RES_SEL       |         VREF = BADGAP
 *                ----------------------------------------------
 *                  0x00~0x3F     |         0.019 * RES_SEL
 *                ----------------------------------------------
 * @retval  None.
 ********************************************************************************/
#if defined(DPM32M026) || defined (DPM32T55x)
void ACMP_ResSelect(uint8_t ACMP_Res)
#else
void ACMP_ResSelect(ACMP_ResSelEnum ACMP_Res)
#endif /* DPM32M026 || DPM32T55x */
{
  uint32_t tmpReg = 0UL;

  /* Read the ACMP control register. */
  tmpReg = ACMP->CR;

  /* Clear CR_RES_SEL bit. */
  tmpReg &= ~ACMP_CR_RES_SEL_Msk;

  /* Set ACMP CR_RES_SEL bit according to ACMP_CfgInitType. */
  tmpReg |= ACMP_Res;

  /* Set the value of the ACMP control register. */
  ACMP->CR = tmpReg;
}


/**
 *******************************************************************************
 * @brief   Reference voltage select.
 * @param   [in]  ACMP_Vref: Specifies the source of reference voltage.
 *                This parameter can be a value of @ref ACMP_VrefSelEnum.
 *                  @arg ACMP_VREF_VDD: Selecting VDD as the source of reference voltage.
 *                  @arg ACMP_VREF_BANDGAP: Selecting Band gap as the source of
 *                                          reference voltage.
 * @retval  None.
 ********************************************************************************/
void ACMP_VrefSelect(ACMP_VrefSelEnum ACMP_Vref)
{
  uint32_t tmpReg = 0UL;

  /* Read the ACMP control register. */
  tmpReg = ACMP->CR;

  /* Clear CR_VREF_SEL bit. */
  tmpReg &= ~ACMP_CR_VREF_SEL_Msk;

  /* Set ACMP CR_VREF_SEL bit according to ACMP_Vref. */
  tmpReg |= ACMP_Vref;

  /* Set the value of the ACMP control register. */
  ACMP->CR = tmpReg;
}


#if defined (DPM32M026) || defined (DPM32T55x)
/**
 *******************************************************************************
 * @brief   Enable or disable ACMP comparison results trigger system reset.
 * @param   [in]  NewState: New state of the BEMFR.
 *                This parameter can be a value of @ref FunctionalState.
 *                  @arg ENABLE: Enable trigger system reset.
 *                  @arg DISABLE: Disable trigger system reset.
 * @retval  None.
 ********************************************************************************/
void ACMP_ResetCmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable ACMP comparison results trigger PVD system reset. */
    ACMP->CR |= ACMP_CR_PVD_RSTN_EN_Msk;
  }
  else
  {
    /* Disable ACMP comparison results trigger PVD system reset. */
    ACMP->CR &= ~ACMP_CR_PVD_RSTN_EN_Msk;
  }
}


/**
 *******************************************************************************
 * @brief   ACMP comparison results trigger system reset polarity selection.
 * @param   [in]  ACMP_ResetPolarity: Select system reset polarity.
 *                This parameter can be a value of @ref ACMP_ResetPolarityEnum.
 *                  @arg ACMP_RES_POL_LOW: When VDD/5 is lower than ACMP_VREF, a reset is triggered.
 *                  @arg ACMP_RES_POL_HIGH: When VDD/5 is higher than ACMP_VREF, a reset is triggered.
 * @retval  None.
 ********************************************************************************/
void ACMP_ResetPolSelect(ACMP_ResetPolarityEnum ACMP_ResetPolarity)
{
  uint32_t tmpReg = 0UL;

  /* Read the ACMP control register. */
  tmpReg = ACMP->CR;

  /* Clear PVD_RSTN_POL bit. */
  tmpReg &= ~ACMP_CR_PVD_RSTN_POL_Msk;

  /* Set ACMP PVD_RSTN_POL bit according to ACMP_ResetPolarity. */
  tmpReg |= ACMP_ResetPolarity;

  /* Set the value of the ACMP control register. */
  ACMP->CR = tmpReg;
}
#endif /* DPM32M026 || DPM32T55x */


#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x) || \
    defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M026) || \
    defined (DPM32T55x)
/**
 *******************************************************************************
 * @brief   Enable or disable back electromotive force resistance.
 * @param   [in]  NewState: New state of the BEMFR.
 *                This parameter can be a value of @ref FunctionalState.
 *                  @arg ENABLE: Enable BEMFR.
 *                  @arg DISABLE: Disable BEMFR.
 * @retval  None.
 ********************************************************************************/
void ACMP_BEMFRCmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable back electromotive force resistance. */
    ACMP->CR |= ACMP_CR_BEMFR_EN_Msk;
  }
  else
  {
    /* Disable back electromotive force resistance. */
    ACMP->CR &= ~ACMP_CR_BEMFR_EN_Msk;
  }
}
#endif /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M026 || DPM32T55x */


#if defined (DPM32M036) || defined (DPM32M030)
/**
 *******************************************************************************
 * @brief   BEMFR resistance circuit input selection.
 * @param   [in]  ACMP_BEMFRInput0: Select BEMFR resistance circuit input 0.
 *                This parameter can be a value of @ref ACMP_BEMFRInput0Enum.
 *                  @arg ACMP_BEMFR_INPUT0_ACMP_INx: Select ACMP_INx as the input 0 of the back BEMFR resistance circuit (x=0~3).
 * @param   [in]  ACMP_BEMFRInput1: Select BEMFR resistance circuit input 1.
 *                This parameter can be a value of @ref ACMP_BEMFRInput1Enum.
 *                  @arg ACMP_BEMFR_INPUT1_ACMP_INx: Select ACMP_INx as the input 1 of the back BEMFR resistance circuit (x=1~4).
 * @param   [in]  ACMP_BEMFRInput2: Select BEMFR resistance circuit input 2.
 *                This parameter can be a value of @ref ACMP_BEMFRInput2Enum.
 *                  @arg ACMP_BEMFR_INPUT2_ACMP_INx: Select ACMP_INx as the input 2 of the back BEMFR resistance circuit (x=2~5).
 * @retval  None.
 ********************************************************************************/
void ACMP_BEMFInputSelect(ACMP_BEMFRInput0Enum ACMP_BEMFRInput0,
                          ACMP_BEMFRInput1Enum ACMP_BEMFRInput1, 
                          ACMP_BEMFRInput2Enum ACMP_BEMFRInput2)
                          {
  uint32_t tmpReg = 0UL;

  /* Read the ACMP control register. */
  tmpReg = ACMP->CR;

  /* Clear CR_BEMFR_SEL bit. */
  tmpReg &= ~(ACMP_CR_BEMFR_SEL0_Msk | ACMP_CR_BEMFR_SEL1_Msk | ACMP_CR_BEMFR_SEL2_Msk);

  /* Set ACMP CR_BEMFR_SEL bit according to ACMP_BEMFRInput. */
  tmpReg |= (ACMP_BEMFRInput0 | ACMP_BEMFRInput1 | ACMP_BEMFRInput2);

  /* Set the value of the ACMP control register. */
  ACMP->CR = tmpReg;
}
#endif /* DPM32M036 || DPM32M030 */


#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) 
/**
 *******************************************************************************
 * @brief   Overcurrent protection input selection.
 * @param   [in]  ACMP_OCPInput: Select overcurrent protection input.
 *                This parameter can be a value of @ref ACMP_OCPInputEnum.
 *                  @arg ACMP_OCP_INPUT_PGA0_OUT: Select PGA0_OUT as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA1_OUT: Select PGA1_OUT as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA0_IN_P: Select PGA0_IN_P as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA0_IN_N: Select PGA0_IN_N as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA1_IN_P: Select PGA1_IN_P as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA1_IN_N: Select PGA1_IN_N as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA2_IN_P: Select PGA2_IN_P as overcurrent protection input.
 *                  @arg ACMP_OCP_INPUT_PGA2_IN_N: Select PGA2_IN_N as overcurrent protection input.
 * @retval  None.
 ********************************************************************************/
void ACMP_OCPInputSelect(ACMP_OCPInputEnum ACMP_OCPInput)
{
  uint32_t tmpReg = 0UL;

  /* Read the ACMP control register. */
  tmpReg = ACMP->CR;

  /* Clear OCP_SEL bit. */
  tmpReg &= ~ACMP_CR_OCP_SEL_Msk;

  /* Set ACMP OCP_SEL bit according to ACMP_OCPInput. */
  tmpReg |= ACMP_OCPInput;

  /* Set the value of the ACMP control register. */
  ACMP->CR = tmpReg;
}
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */


/**
 *******************************************************************************
 * @brief   Deinitializes specifies ACMP channel to their default reset values.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @retval  None.
 ********************************************************************************/
void ACMP_DeInit(ACMP_ChannelEnum ACMP_Channel)
{
  /* Set ACMP configuration register to reset value */
  ACMP_CHCFG(ACMP_Channel) = 0UL;

  /* Clear the value of the ACMP interrup Flag. */
  ACMP->SR = (1UL << ACMP_Channel);
}


/**
 *******************************************************************************
 * @brief   Initializes the specifies ACMP channel according to the specified
 *          parameters in the ACMP_InitType.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @param   [in]  ACMP_InitType: Structure pointer of ACMP configuration.
 * @retval  None.
 ********************************************************************************/
void ACMP_Init(ACMP_ChannelEnum ACMP_Channel, ACMP_InitTypeStruct *ACMP_InitType)
{
  uint32_t tmpReg = 0UL;

  /* Parameters check. */
  PARAM_ASSERT(IS_ACMP_CHANNEL(ACMP_Channel));
#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x) || \
    defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)
  PARAM_ASSERT(IS_ACMP_POLARITY(ACMP_InitType->ACMP_Polarity));
#endif /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M015 */
  PARAM_ASSERT(IS_ACMP_P_INPUT(ACMP_InitType->ACMP_PInput));
  PARAM_ASSERT(IS_ACMP_N_INPUT(ACMP_InitType->ACMP_NInput));
  PARAM_ASSERT(IS_ACMP_FILTER_LEN(ACMP_InitType->ACMP_Filter.FilterLen));
  PARAM_ASSERT(IS_ACMP_FILTER_SAMPLE(ACMP_InitType->ACMP_Filter.FilterSample));
  PARAM_ASSERT(IS_FUNCTION_STATE(ACMP_InitType->ACMP_Filter.FilterCmd));
  PARAM_ASSERT(IS_FUNCTION_STATE(ACMP_InitType->ACMP_HYSCmd));
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) || \
    defined (DPM32M026) || defined (DPM32T55x)
  PARAM_ASSERT(IS_FUNCTION_STATE(ACMP_InitType->ACMP_HoldCmd));
#endif /* DPM32M036 || DPM32M030 || DPM32M015 || DPM32M026 || DPM32T55x */

  /* Read the ACMP configuration register. */
  tmpReg = ACMP_CHCFG(ACMP_Channel);

  /* Clear CFG_POL,CFG_IN_P_SEL,CFG_IN_N_SEL,CFG_FLT_SAMPLE,
      CFG_FLT_LEN,CFG_FLT_EN,HYS_EN bits. */
#if defined (DPM32M036) || defined (DPM32M030)
  tmpReg &= ~(ACMP_ACMP0_CFG_POL_Msk | ACMP_ACMP0_CFG_IN_P_SEL_Msk | \
              ACMP_ACMP0_CFG_IN_N_SEL_Msk | ACMP_ACMP0_CFG_FLT_SAMPLE_Msk | \
              ACMP_ACMP0_CFG_FLT_LEN_Msk | ACMP_ACMP0_CFG_FLT_EN_Msk | \
              ACMP_ACMP0_CFG_HYS_EN_Msk | ACMP_ACMP0_CFG_RES_HOLD_Msk);
#elif defined (DPM32M015)
  tmpReg &= ~(ACMP_ACMP1_CFG_POL_Msk | ACMP_ACMP1_CFG_IN_P_SEL_Msk | \
              ACMP_ACMP1_CFG_IN_N_SEL_Msk | ACMP_ACMP1_CFG_FLT_SAMPLE_Msk | \
              ACMP_ACMP1_CFG_FLT_LEN_Msk | ACMP_ACMP1_CFG_FLT_EN_Msk | \
              ACMP_ACMP1_CFG_HYS_EN_Msk | ACMP_ACMP1_CFG_RES_HOLD_Msk);
#elif defined (DPM32M026) || defined (DPM32T55x)
  tmpReg &= ~(ACMP_ACMP1_CFG_IN_P_SEL_Msk | ACMP_ACMP1_CFG_IN_N_SEL_Msk | \
              ACMP_ACMP1_CFG_FLT_SAMPLE_Msk | ACMP_ACMP1_CFG_FLT_LEN_Msk  |\
              ACMP_ACMP1_CFG_FLT_EN_Msk | ACMP_ACMP1_CFG_HYS_EN_Msk | \
              ACMP_ACMP1_CFG_RES_HOLD_Msk);
#else /* DPM32M08x || DPM32M05x || DPM32M03x */
  tmpReg &= ~(ACMP_ACMP0_CFG_POL_Msk | ACMP_ACMP0_CFG_IN_P_SEL_Msk | \
              ACMP_ACMP0_CFG_IN_N_SEL_Msk | ACMP_ACMP0_CFG_FLT_SAMPLE_Msk | \
              ACMP_ACMP0_CFG_FLT_LEN_Msk | ACMP_ACMP0_CFG_FLT_EN_Msk | \
              ACMP_ACMP0_CFG_HYS_EN_Msk);
#endif /* DPM32M036 || DPM32M030 */

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x) || \
    defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)
  /* Set ACMP ACMP_CFG_POL bit according to ACMP_InitType. */
  tmpReg |= (uint32_t)(ACMP_InitType->ACMP_Polarity);
#endif /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M015 */

  /* Set ACMP IN_P_SEL bit according to ACMP_InitType. */
  tmpReg |= (uint32_t)(ACMP_InitType->ACMP_PInput);

  /* Set ACMP IN_N_SEL bit according to ACMP_InitType. */
  tmpReg |= (uint32_t)(ACMP_InitType->ACMP_NInput);

  /* Set ACMP FLT_SAMPLE bit according to ACMP_InitType. */
  tmpReg |= (uint32_t)(ACMP_InitType->ACMP_Filter.FilterSample);

  /* Set ACMP FLT_LEN bit according to ACMP_InitType. */
  tmpReg |= (uint32_t)(ACMP_InitType->ACMP_Filter.FilterLen);

  if(DISABLE != ACMP_InitType->ACMP_Filter.FilterCmd)
  {
    /* Set ACMP FLT_EN bit according to ACMP_InitType. */
#if defined (DPM32M015) 
    tmpReg |= ACMP_ACMP1_CFG_FLT_EN_Msk;
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M026 || DPM32T55x */
    tmpReg |= ACMP_ACMP0_CFG_FLT_EN_Msk;
#endif /* DPM32M015 */
  }

  if(DISABLE != ACMP_InitType->ACMP_HYSCmd)
  {
    /* Set ACMP HYS_EN bit according to ACMP_InitType. */
    tmpReg |= ACMP_ACMP1_CFG_HYS_EN_Msk;
  }

#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) || \
    defined (DPM32M026) || defined (DPM32T55x)
  if(DISABLE != ACMP_InitType->ACMP_HoldCmd)
  {
    /* Set ACMP RES_HOLD bit according to ACMP_InitType. */
    tmpReg |= ACMP_ACMP1_CFG_RES_HOLD_Msk;
  }
#endif /* DPM32M036 || DPM32M030 || DPM32M015 || DPM32M026 || DPM32T55x */

  /* Set the value of the ACMP configuration register. */
  ACMP_CHCFG(ACMP_Channel) = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Initialize the ACMP_InitType with default parameters.
 * @param   [in]  ACMP_InitType: Pointer to a ACMP_InitTypeStruct structure
 *                which will be initialized.
 * @retval  None.
 ******************************************************************************/
void ACMP_StructInit(ACMP_InitTypeStruct *ACMP_InitType)
{
#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x) || \
    defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)
  ACMP_InitType->ACMP_Polarity = ACMP_POL_NORMAL;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M015 */
  ACMP_InitType->ACMP_PInput = ACMP_IN_P_SEL_ACMP_IN0;
  ACMP_InitType->ACMP_NInput = ACMP_IN_N_SEL_ACMP_IN0;
  ACMP_InitType->ACMP_Filter.FilterSample = ACMP_FILTER_SAMPLE_DIV1;
  ACMP_InitType->ACMP_Filter.FilterLen = ACMP_FILTER_LEN1;
  ACMP_InitType->ACMP_Filter.FilterCmd = DISABLE;
  ACMP_InitType->ACMP_HYSCmd = DISABLE;
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) || \
    defined (DPM32M026) || defined (DPM32T55x)
  ACMP_InitType->ACMP_HoldCmd = DISABLE;
#endif /* DPM32M036 || DPM32M030 || DPM32M015 || DPM32M026 || DPM32T55x */
}

/**
 *******************************************************************************
 * @brief   Enables or disables the specified ACMP channel.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @param   [in]  NewState: New state of the ACMP channel.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void ACMP_Cmd(ACMP_ChannelEnum ACMP_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {    
    /* Enable specified ACMP channel. */
    ACMP_CHCFG(ACMP_Channel) |= (uint32_t)ACMP_ACMP1_CFG_EN_Msk;
  }
  else
  {
    /* Disable specified ACMP channel. */
    ACMP_CHCFG(ACMP_Channel) &= ~(uint32_t)ACMP_ACMP1_CFG_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Configure ACMP filter according to the specified parameters in the ACMP_FilterInitType.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @param   [in]  ACMP_FilterInitType: Structure pointer of ACMP filter configuration.
 * @retval  None.
 ********************************************************************************/
void ACMP_FilterInit(ACMP_ChannelEnum ACMP_Channel, ACMP_FilterInitTypeStruct *ACMP_FilterInitType)
{
  uint32_t tmpReg = 0UL;

  /* Parameters check. */
  PARAM_ASSERT(IS_ACMP_FILTER_LEN(ACMP_FilterInitType->FilterLen));
  PARAM_ASSERT(IS_ACMP_FILTER_SAMPLE(ACMP_FilterInitType->FilterSample));
  PARAM_ASSERT(IS_FUNCTION_STATE(ACMP_FilterInitType->FilterCmd));

  /* Read the ACMP configuration register. */
  tmpReg = ACMP_CHCFG(ACMP_Channel);

  /* Clear FLT_SAMPLE,FLT_LEN,FLT_EN bits. */
  tmpReg &= ~(ACMP_ACMP1_CFG_FLT_SAMPLE_Msk | ACMP_ACMP1_CFG_FLT_LEN_Msk | \
              ACMP_ACMP1_CFG_FLT_EN_Msk);

  /* Set ACMP FLT_SAMPLE bit according ACMP_FilterInitType. */
  tmpReg |= (uint32_t)(ACMP_FilterInitType->FilterSample);

  /* Set ACMP FLT_LEN bit according ACMP_FilterInitType. */
  tmpReg |= (uint32_t)(ACMP_FilterInitType->FilterLen);

  if(DISABLE != ACMP_FilterInitType->FilterCmd)
  {
    /* Set ACMP FLT_LEN bit according ACMP_FilterInitType. */
    tmpReg |= ACMP_ACMP1_CFG_FLT_EN_Msk;
  }

  /* Set the value of the ACMP configuration register. */
  ACMP_CHCFG(ACMP_Channel) = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Initialize the ACMP_FilterInitType with default parameters.
 * @param   [in]  ACMP_FilterInitType: Pointer to a ACMP_FilterInitTypeStruct structure
 *                which will be initialized.
 * @retval  None.
 ******************************************************************************/
void ACMP_FilterStructInit(ACMP_FilterInitTypeStruct *ACMP_FilterInitType)
{
  ACMP_FilterInitType->FilterSample = ACMP_FILTER_SAMPLE_DIV1;
  ACMP_FilterInitType->FilterLen = ACMP_FILTER_LEN1;
  ACMP_FilterInitType->FilterCmd = DISABLE;
}

/**
 *******************************************************************************
 * @brief   Enables or disables the specifies ACMP channel filter.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @param   [in]  NewState: New state of the ACMP filter.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void ACMP_FilterCmd(ACMP_ChannelEnum ACMP_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable ACMP filter. */
    ACMP_CHCFG(ACMP_Channel) |= ACMP_ACMP1_CFG_FLT_EN_Msk;
  }
  else
  {
    /* Disable ACMP filter. */
    ACMP_CHCFG(ACMP_Channel) &= ~ACMP_ACMP1_CFG_FLT_EN_Msk;
  }
}


#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015) || \
    defined (DPM32M026) || defined (DPM32T55x)
/**
 *******************************************************************************
 * @brief   Enables or disables the specifies ACMP channel filter.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @param   [in]  NewState: New state of the ACMP filter.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void ACMP_OutHoldCmd(ACMP_ChannelEnum ACMP_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable ACMP filter. */
    ACMP_CHCFG(ACMP_Channel) |= ACMP_ACMP1_CFG_RES_HOLD_Msk;
  }
  else
  {
    /* Disable ACMP filter. */
    ACMP_CHCFG(ACMP_Channel) &= ~ACMP_ACMP1_CFG_RES_HOLD_Msk;
  }
}
#endif /* DPM32M036 || DPM32M030 || DPM32M015 || DPM32M026 || DPM32T55x */


/**
 *******************************************************************************
 * @brief   Get ACMP channel compare results.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @retval  FlagState: ACMP comparison result (SET or RESET).
 ******************************************************************************/
FlagState ACMP_GetCompareResult(ACMP_ChannelEnum ACMP_Channel)
{
  /* Return the value of the ACMP comparison results. */
#if defined (DPM32M015) 
  return (FlagState)((ACMP->SR & ((uint32_t)ACMP_SR_ACMP1_RES_Msk))
                     ? SET : RESET);
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 */
  return (FlagState)((ACMP->SR & ((uint32_t)(ACMP_SR_ACMP0_RES_Msk << ACMP_Channel)))
                     ? SET : RESET);
#endif /* DPM32M015 */
}

/**
 *******************************************************************************
 * @brief   Get ACMP channel ready status.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @retval  FlagState: ACMP ready status (SET or RESET).
 ******************************************************************************/
FlagState ACMP_GetReadyStatus(ACMP_ChannelEnum ACMP_Channel)
{
#if defined (DPM32M015) 
  return (FlagState)((ACMP->SR & ((uint32_t)ACMP_SR_ACMP1_RDY_Msk)) \
                     ? SET : RESET);
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 */
  return (FlagState)((ACMP->SR & ((uint32_t)(ACMP_SR_ACMP0_RDY_Msk << ACMP_Channel))) \
                     ? SET : RESET);
#endif /* DPM32M015 */
}

/**
 *******************************************************************************
 * @brief   Enables or disables the specifies ACMP channel interrupt.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @param   [in]  ACMP_IntType: Specifies the ACMP trigger interrupt type.
 *                This parameter can be a value of @ref ACMP_IntTypeEnum.
 *                   @arg ACMP_INT_TYPE_RISING: Rising edge trigger interrupt.
 *                   @arg ACMP_INT_TYPE_FALLING: Falling edge trigger interrupt.
 *                   @arg ACMP_INT_TYPE_RISING_FALLING: Rising and falling edge trigger interrupt.
 * @param   [in]  NewState: New state of the specifies ACMP interrupts.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void ACMP_IntCmd(ACMP_ChannelEnum ACMP_Channel, ACMP_IntTypeEnum ACMP_IntType, FunctionalState NewState)
{
  uint32_t tmpReg = 0UL;

  /* Read the ACMP configuration register. */
  tmpReg = ACMP_CHCFG(ACMP_Channel);

  /* Clear INT_TYPE bit. */
  tmpReg &= ~(ACMP_ACMP1_CFG_INT_TYPE_Msk | ACMP_ACMP1_CFG_IE_Msk);

  /* Set INT_TYPE bit according to ACMP_IntType. */
  tmpReg |= (uint32_t)(ACMP_IntType);

  if(DISABLE != NewState)
  {
    tmpReg |= (uint32_t)ACMP_ACMP1_CFG_IE_Msk;
  }

  /* Set the value of the ACMP configuration register. */
  ACMP_CHCFG(ACMP_Channel) = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Get specifies ACMP channel interrupt enable status.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @retval  FunctionalState: The ACMP interrupt state(ENABLE or DISABLE).
 ******************************************************************************/
FunctionalState ACMP_GetIntCmdStatus(ACMP_ChannelEnum ACMP_Channel)
{
#if defined (DPM32M015) 
  /* Return the status of the interrupt enable bit. */
  return (FunctionalState)((ACMP_CHCFG(ACMP_Channel) & (ACMP_ACMP1_CFG_IE_Msk))
                           ? ENABLE : DISABLE);
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M026 || DPM32T55x */
  /* Return the status of the interrupt enable bit. */
  return (FunctionalState)((ACMP_CHCFG(ACMP_Channel) & (ACMP_ACMP0_CFG_IE_Msk))
                           ? ENABLE : DISABLE);
#endif /* DPM32M015 */
}

/**
 *******************************************************************************
 * @brief   Get specifies ACMP channel interrupt Flag.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @retval  FlagState: The state of ACMP interrupt (SET or RESET).
 ******************************************************************************/
FlagState ACMP_GetIntFlagStatus(ACMP_ChannelEnum ACMP_Channel)
{
  /* Return the value of the ACMP interrup Flag. */
#if defined (DPM32M015) 
  return (FlagState)((ACMP->SR & ((uint32_t)ACMP_SR_ACMP1_IF_Msk))
                     ? SET : RESET);
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M026 || DPM32T55x */
  return (FlagState)((ACMP->SR & ((uint32_t)(ACMP_SR_ACMP0_IF_Msk << ACMP_Channel)))
                     ? SET : RESET);
#endif /* DPM32M015 */
}

/**
 *******************************************************************************
 * @brief   Clear specifies ACMP channel interrupt Flag.
 * @param   [in]  ACMP_Channel: Specifies the ACMP channel.
 *                This parameter can be a value of @ref ACMP_ChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                  @arg ACMP_CH2: ACMP channel 2.
 *                  @arg ACMP_CH3: ACMP channel 3.
 *                DPM32M036|DPM32M030|DPM32M026|DPM32T55x:
 *                  @arg ACMP_CH0: ACMP channel 0.
 *                  @arg ACMP_CH1: ACMP channel 1.
 *                DPM32M015:
 *                  @arg ACMP_CH1: ACMP channel 1.
 * @retval  None.
 ******************************************************************************/
void ACMP_ClearIntFlag(ACMP_ChannelEnum ACMP_Channel)
{
#if defined (DPM32M015) 
  ACMP->SR = (uint32_t)ACMP_SR_ACMP1_IF_Msk;
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 || DPM32M026 || DPM32T55x */
  ACMP->SR = (uint32_t)(ACMP_SR_ACMP0_IF_Msk << ACMP_Channel);
#endif /* DPM32M015 */
}
