/**
 *******************************************************************************
 * @file    dpm32m0xx_epwm.c
 *
 * @brief   Source file for EPWM firmware driver.
 *          This file provides firmware functions to manage the following
 *          functionalities of the EPWM peripheral:
 *            + TimeBase management
 *            + ADC compare management
 *            + Channel output management
 *            + Force output management
 *            + Shadow and death management
 *            + Energency stop management
 *            + Interrupt, DMA flags management
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 * @verbatim
 ===============================================================================
                       ##### How to use this driver #####
 ===============================================================================
    [..]
      (#) Enable the EPWM controller interface clock using
          RCC_APBPeriphClockCmd(RCC_APB_PERIPH_EPWM, ENABLE).

      (#) EPWM pins configuration:
        (+) Enable the clock for the EPWM GPIOs using the following function:
            RCC_AHBPeriphClockCmd(RCC_AHB_PERIPH_GPIO, ENABLE).
        (+) Configure these EPWM pins in alternate function mode by calling
            the function GPIO_Init().
        (+) Connect the involved pins to alternate function using the
            following function GPIO_AltFuncConfig().

      (#) Unlock register write protect using EPWM_Unlock().

      (#) Configure the EPWM reload value, clock division, counter cycle and
          counter cycle using the EPWM_TimeBaseInit() function.

      (#) Activate the EPWM peripheral using EPWM_Cmd() function.

      (#) EPWM ADC compare configuration:
        (+) Configure the ADC compare value, direction and status using
            EPWM_ADCCmpInit() function.
        (+) Optionally you can enable/configure the following parameters without
            re-initialization (i.e there is no need to call again
            EPWM_ADCCmpInit() function):
          (*) Set ADC compare values using EPWM_SetADCCompare1Value() and
              EPWM_SetADCCompare2Value() function.
          (*) Set ADC compare direction using EPWM_SetADCCompare1Dir() and
              EPWM_SetADCCompare2Dir() function.
          (*) Enable ADC compare using EPWM_ADCCompare1Cmd() and
              EPWM_ADCCompare1Cmd() function.

      (#) EPWM channel output configuration:
        (+) Configure the channel output value, action, initial status, polarity,
            direction and status using EPWM_CHInit() function.
        (+) Optionally you can enable/configure the following parameters without
            re-initialization (i.e there is no need to call again
            EPWM_CHInit() function):
          (*) Set channel output compare values using EPWM_SetCHCompare1Value()
              and EPWM_SetCHCompare2Value() function.
          (*) Set channel output action using EPWM_SetCHCompare1Action() and
              EPWM_SetCHCompare2Action() function.
          (*) Set channel output initial level using EPWM_SetCHInitOutputLevel()
              function.
          (*) Set channel output polarity using EPWM_SetCHNPolarity() and
              EPWM_SetCHPPolarity() function.
          (*) Set channel output compare direction using EPWM_SetCHCompare1Dir()
              and EPWM_SetCHCompare2Dir() function.
          (*) Set channel output compare direction using EPWM_SetCHCompare1Dir()
              and EPWM_SetCHCompare2Dir() function.
         (+) Activate the EPWM channel output using EPWM_CHCmd() function.

      (#) EPWM fource output configuration:
        (+) Configure the fource output level and status using
            EPWM_CHForceOutInit() function.
        (+) Optionally you can enable/configure the following parameters without
            re-initialization (i.e there is no need to call again
            EPWM_CHForceOutInit() function):
          (*) Set fource output level using EPWM_SetCHNForceLevel()
              and EPWM_SetCHPForceLevel() function.
          (*) Enable fource output using EPWM_CHNForceCmd()
              and EPWM_CHPForceCmd() function.

      (#) EPWM emergency stop configuration:
        (+) Configure the emergency stop filter, polarity, ACMP, debug status and
            output level using EPWM_CHForceOutInit() function.
        (+) Get emergency stop status using EPWM_GetESStopStatus() function.
        (+) Software set emergency stop using EPWM_ESSoftwareBrake() function.
        (+) Software set emergency stop continue output using
            EPWM_ESSoftwareContinue() function.

      (#) When using the DMA mode.
        (+) Configure the DMA using DMA_Init() function.
        (+) Active the needed channel Request using EPWM_DMACmd() function.

      (#) EPWM interrupt configuration:
        (+) To activate the EPWM interrupt, using EPWM_IntCmd() functions.
        (+) Check on EPWM interrupt enable flags using the function
            EPWM_GetIntCmdStatus().
        (+) Check on EPWM interrupt occur flags using the function
            EPWM_GetIntFlagStatus().
        (+) Clear EPWM interrupt flags using the function EPWM_ClearIntFlag().

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

#include "dpm32m0xx_epwm.h"



/**
 *******************************************************************************
 * @brief   Unlocks EPWM related registers.
 * @retval  None.
 ******************************************************************************/
void EPWM_Unlock(void)
{
  EPWM->LOCK = 0x900D0000;
}

/**
 *******************************************************************************
 * @brief   Locks EPWM related registers.
 * @retval  None.
 ******************************************************************************/
void EPWM_Lock(void)
{
  EPWM->LOCK = 0x900D0001;
}

/**
 *******************************************************************************
 * @brief   Deinitializes the EPWM peripheral registers to their default reset values.
 * @retval  None.
 ******************************************************************************/
void EPWM_DeInit(void)
{
  /* Reset EPWM control register. */
  EPWM->CR = (uint32_t)0x00000000;

  /* Reset EPWM auto reload register. */
  EPWM->ARR = (uint32_t)0x00000000;

  /* Claer EPWM interrupt status register. */
  EPWM->SR = (uint32_t)0x0000001F;

  /* Reset EPWM compare control register. */
  EPWM->CMP_CFG = (uint32_t)0x00000000;

  /* Reset EPWM ADC compare1 value register. */
  EPWM->ADC_CMP1 = (uint32_t)0x00000000;

  /* Reset EPWM ADC compare2 value register. */
  EPWM->ADC_CMP2 = (uint32_t)0x00000000;

  /* Reset EPWM CH0 compare1 value register. */
  EPWM->CH0_CMP1 = (uint32_t)0x00000000;

  /* Reset EPWM CH0 compare2 value register. */
  EPWM->CH0_CMP2 = (uint32_t)0x00000000;

  /* Reset EPWM CH1 compare1 value register. */
  EPWM->CH1_CMP1 = (uint32_t)0x00000000;

  /* Reset EPWM CH1 compare2 value register. */
  EPWM->CH1_CMP2 = (uint32_t)0x00000000;

  /* Reset EPWM CH2 compare1 value register. */
  EPWM->CH2_CMP1 = (uint32_t)0x00000000;

  /* Reset EPWM CH2 compare2 value register. */
  EPWM->CH2_CMP2 = (uint32_t)0x00000000;

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  /* Reset EPWM CH3 compare1 value register. */
  EPWM->CH3_CMP1 = (uint32_t)0x00000000;

  /* Reset EPWM CH3 compare2 value register. */
  EPWM->CH3_CMP2 = (uint32_t)0x00000000;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

  /* Reset EPWM update register. */
  EPWM->UPDATE = (uint32_t)0x00000000;

  /* Reset EPWM channel control register. */
  EPWM->CH_CR = (uint32_t)0x00000000;

  /* Reset EPWM force output control register. */
  EPWM->OUT_CR = (uint32_t)0x00000000;

  /* Reset EPWM death time control register. */
  EPWM->DT_CR = (uint32_t)0x00000000;

  /* Reset EPWM emergency stop control register. */
  EPWM->STOP_CR = (uint32_t)0x00000000;
}

/**
 *******************************************************************************
 * @brief   Initializes the EPWM peripheral base time function according to
 *          the specified parameters in the EPWM_TimeBaseInitType.
 * @param   [in]  EPWM_TimeBaseInitType: Structure pointer of EPWM configuration.
 * @retval  None.
 ******************************************************************************/
void EPWM_TimeBaseInit(EPWM_TimeBaseInitTypeStruct* EPWM_TimeBaseInitType)
{
  uint32_t tmpReg = 0UL;

  /* Parameters check. */
  PARAM_ASSERT(IS_EPWM_CLOCK_DIV(EPWM_TimeBaseInitType->EPWM_ClockDiv));
  PARAM_ASSERT(IS_EPWM_COUNTER_CYCLE(EPWM_TimeBaseInitType->EPWM_CounterCycle));
  PARAM_ASSERT(IS_EPWM_COUNTER_MODE(EPWM_TimeBaseInitType->EPWM_CounterMode));

  /* Read the value of the EPWM control register. */
  tmpReg = EPWM->CR;

  /* Clear EPWM CLK_DIV[2:0],MODE,SINGLE bits. */
  tmpReg &= ~(EPWM_CR_CLK_DIV_Msk | EPWM_CR_MODE_Msk | EPWM_CR_SINGLE_Msk);

  /* Set EPWM CLK_DIV[2:0] bits according to EPWM_TimeBaseInitType. */
  tmpReg |=  (uint32_t)(EPWM_TimeBaseInitType->EPWM_ClockDiv << EPWM_CR_CLK_DIV_Pos);

  /* Set EPWM MODE bit according to EPWM_TimeBaseInitType. */
  tmpReg |=  (uint32_t)(EPWM_TimeBaseInitType->EPWM_CounterMode << EPWM_CR_MODE_Pos);

  /* Set EPWM SINGLE bit according to EPWM_TimeBaseInitType. */
  tmpReg |=  (uint32_t)(EPWM_TimeBaseInitType->EPWM_CounterCycle << EPWM_CR_SINGLE_Pos);

  /* Store the new value. */
  EPWM->CR = tmpReg;

  /* Sets the EPWM auto reload register value. */
  EPWM->ARR = EPWM_TimeBaseInitType->EPWM_ReloadValue;
}

/**
 *******************************************************************************
 * @brief   Initialize the EPWM_TimeBaseInitType with default parameters.
 * @param   [in]  EPWM_TimeBaseInitType: Pointer to a EPWM_TimeBaseInitTypeStruct
 *                structure which will be initialized.
 * @retval  None.
 ******************************************************************************/
void EPWM_TimeBaseStructInit(EPWM_TimeBaseInitTypeStruct* EPWM_TimeBaseInitType)
{
  EPWM_TimeBaseInitType->EPWM_ReloadValue = 0xFFFF;
  EPWM_TimeBaseInitType->EPWM_ClockDiv = EPWM_CLK_DIV1;
  EPWM_TimeBaseInitType->EPWM_CounterCycle = EPWM_COUNTER_CYCLE_PERIOD;
  EPWM_TimeBaseInitType->EPWM_CounterMode = EPWM_COUNTER_MODE_INCREASE_DECREASE;
}

/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM peripheral counter functions.
 * @param   [in]  NewState: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_Cmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable EPWM counter functions. */
    EPWM->CR |= EPWM_CR_EN_Msk;
  }
  else
  {
    /* Disable EPWM counter functions. */
    EPWM->CR &= ~EPWM_CR_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM auto reload register new value.
 * @param   [in]  EPWM_Value: Specifies the auto reload register new value.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetAutoReload(uint16_t EPWM_Value)
{
  /* Set the auto reload register value. */
  EPWM->ARR = EPWM_Value;
}

/**
 *******************************************************************************
 * @brief   Gets the EPWM auto reload register value.
 * @retval  uint16_t: Auto reload register value.
 ******************************************************************************/
uint16_t EPWM_GetAutoReload(void)
{
  /* Return the auto reload register value. */
  return (uint16_t)EPWM->ARR;
}

/**
 *******************************************************************************
 * @brief   Get the counter register value.
 * @retval  uint16_t: Counter register value.
 ******************************************************************************/
uint16_t EPWM_GetCounter(void)
{
  /* Get the counter register value. */
  return (uint16_t)EPWM->CNT;
}

/**
 *******************************************************************************
 * @brief   Initializes the EPWM peripheral ADC compare1 function according to
 *          the specified parameters in the EPWM_ADCCmpInitTypeStruct.
 * @param   [in]  EPWM_ADCCmpInitType: Structure pointer of EPWM ADC compare configuration.
 * @retval  None.
 ******************************************************************************/
void EPWM_ADCCmpInit(EPWM_ADCCmpInitTypeStruct* EPWM_ADCCmpInitType)
{
  uint32_t tmpReg = 0UL;

  /* Parameters check. */
  PARAM_ASSERT(IS_EPWM_CMP_DIRECTION(EPWM_ADCCmpInitType->EPWM_ADCCmp1Dir));
  PARAM_ASSERT(IS_EPWM_CMP_DIRECTION(EPWM_ADCCmpInitType->EPWM_ADCCmp2Dir));

  /* Sets the EPWM ADC compare1 register value. */
  EPWM->ADC_CMP1 = EPWM_ADCCmpInitType->EPWM_ADCCmp1Value;

  /* Sets the EPWM ADC compare12 register value. */
  EPWM->ADC_CMP2 = EPWM_ADCCmpInitType->EPWM_ADCCmp2Value;

  /* Read the value of the EPWM compare config register. */
  tmpReg = EPWM->CMP_CFG;

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)

  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_ADCCmpInitType->EPWM_ADCCmp1State));
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_ADCCmpInitType->EPWM_ADCCmp2State));

  /* Clear EPWM ADC_CMP1_DIR bit. */
  tmpReg &= ~EPWM_CMP_CFG_ADC_CMP1_DIR_Msk;

  /* Set EPWM ADC_CMP1_DIR bit according to EPWM_ADCCompareInitStruct. */
  tmpReg |= (uint32_t)(EPWM_ADCCmpInitType->EPWM_ADCCmp1Dir << EPWM_CMP_CFG_ADC_CMP1_DIR_Pos);

  if(DISABLE != EPWM_ADCCmpInitType->EPWM_ADCCmp1State)
  {
    /* Enable EPWM ADC compare1 functions. */
    tmpReg |= EPWM_CMP_CFG_ADC_CMP1_EN_Msk;
  }
  else
  {
    /* Disable EPWM ADC compare1 functions. */
    tmpReg &= ~EPWM_CMP_CFG_ADC_CMP1_EN_Msk;
  }

  /* Clear EPWM ADC_CMP2_DIR bit. */
  tmpReg &= ~EPWM_CMP_CFG_ADC_CMP2_DIR_Msk;

  /* Set EPWM ADC_CMP2_DIR bit according to EPWM_ADCCompareInitStruct. */
  tmpReg |= (uint32_t)(EPWM_ADCCmpInitType->EPWM_ADCCmp2Dir << EPWM_CMP_CFG_ADC_CMP2_DIR_Pos);

  if(DISABLE != EPWM_ADCCmpInitType->EPWM_ADCCmp2State)
  {
    /* Enable EPWM ADC compare2 functions. */
    tmpReg |= EPWM_CMP_CFG_ADC_CMP2_EN_Msk;
  }
  else
  {
    /* Disable EPWM ADC compare2 functions. */
    tmpReg &= ~EPWM_CMP_CFG_ADC_CMP2_EN_Msk;
  }
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  /* Clear EPWM ADC_CMP1_DIR and ADC_CMP2_DIR bit. */
  tmpReg &= ~(EPWM_CMP_CFG_ADC_CMP1_DIR_Msk | EPWM_CMP_CFG_ADC_CMP2_DIR_Msk);

  /* Set EPWM ADC_CMP1_DIR bit according to EPWM_ADCCompareInitStruct. */
  tmpReg |= (uint32_t)(EPWM_ADCCmpInitType->EPWM_ADCCmp1Dir << EPWM_CMP_CFG_ADC_CMP1_DIR_Pos);

  /* Set EPWM ADC_CMP2_DIR bit according to EPWM_ADCCompareInitStruct. */
  tmpReg |= (uint32_t)(EPWM_ADCCmpInitType->EPWM_ADCCmp2Dir << EPWM_CMP_CFG_ADC_CMP2_DIR_Pos);
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */

  /* Store the new value. */
  EPWM->CMP_CFG = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Initialize the EPWM_ADCCmpInitType with default parameters.
 * @param   [out] EPWM_ADCCmpInitType: Pointer to a EPWM_ADCCmpInitTypeStruct structure
 *                which will be initialized.
 * @retval  None.
 ******************************************************************************/
void EPWM_ADCCmpInitStruct(EPWM_ADCCmpInitTypeStruct* EPWM_ADCCmpInitType)
{
  EPWM_ADCCmpInitType->EPWM_ADCCmp1Value = 0xFFFF;
  EPWM_ADCCmpInitType->EPWM_ADCCmp2Value = 0xFFFF;
  EPWM_ADCCmpInitType->EPWM_ADCCmp1Dir = EPWM_CMP_DIR_INCREASE;
  EPWM_ADCCmpInitType->EPWM_ADCCmp2Dir = EPWM_CMP_DIR_INCREASE;

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  EPWM_ADCCmpInitType->EPWM_ADCCmp1State = ENABLE;
  EPWM_ADCCmpInitType->EPWM_ADCCmp2State = ENABLE;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ADC compare1 register new value.
 * @param   [in]  EPWM_Value: Specifies the ADC compare1 register new value.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetADCCompare1Value(uint16_t EPWM_Value)
{
  /* Sets the EPWM ADC compare1 register value. */
  EPWM->ADC_CMP1 = EPWM_Value;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ADC compare2 register new value.
 * @param   [in]  EPWM_Value: Specifies the ADC compare2 register new value.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetADCCompare2Value(uint16_t EPWM_Value)
{
  /* Sets the EPWM ADC compare2 register value. */
  EPWM->ADC_CMP2 = EPWM_Value;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ADC compare1 direction.
 * @param   [in]  EPWM_Dir: Specifies the ADC compare1 direction.
 *                This parameter can be a value of @ref EPWM_CmpDirEnum.
 *                  @arg EPWM_CMP_DIR_INCREASE: Compare value in increase valid.
 *                  @arg EPWM_CMP_DIR_DECREASE: Compare value in decrease valid.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetADCCompare1Dir(EPWM_CmpDirEnum EPWM_Dir)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM compare config register. */
  tmpReg = EPWM->CMP_CFG;

  /* Clear EPWM ADC_CMP1_DIR bit. */
  tmpReg &= ~EPWM_CMP_CFG_ADC_CMP1_DIR_Msk;

  /* Set EPWM ADC_CMP1_DIR bit according to dir. */
  tmpReg |= (uint32_t)(EPWM_Dir << EPWM_CMP_CFG_ADC_CMP1_DIR_Pos);

  /* Store the new value. */
  EPWM->CMP_CFG = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ADC compare2 direction.
 * @param   [in]  EPWM_Dir: Specifies the ADC compare2 direction.
 *                This parameter can be a value of @ref EPWM_CmpDirEnum.
 *                  @arg EPWM_CMP_DIR_INCREASE: Compare value in increase valid.
 *                  @arg EPWM_CMP_DIR_DECREASE: Compare value in decrease valid.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetADCCompare2Dir(EPWM_CmpDirEnum EPWM_Dir)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM compare config register. */
  tmpReg = EPWM->CMP_CFG;

  /* Clear EPWM ADC_CMP2_DIR bit. */
  tmpReg &= ~EPWM_CMP_CFG_ADC_CMP2_DIR_Msk;

  /* Set EPWM ADC_CMP2_DIR bit according to dir. */
  tmpReg |= (uint32_t)(EPWM_Dir << EPWM_CMP_CFG_ADC_CMP2_DIR_Pos);

  /* Store the new value. */
  EPWM->CMP_CFG = tmpReg;
}

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM ADC compare1 functions.
 * @param   [in]  state: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_ADCCompare1Cmd(FunctionalState state)
{
  if(DISABLE != state)
  {
    /* Enable EPWM ADC compare1 functions. */
    EPWM->CMP_CFG |= EPWM_CMP_CFG_ADC_CMP1_EN_Msk;
  }
  else
  {
    /* Disable EPWM ADC compare1 functions. */
    EPWM->CMP_CFG &= ~EPWM_CMP_CFG_ADC_CMP1_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM ADC compare2 functions.
 * @param   [in]  state: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_ADCCompare2Cmd(FunctionalState state)
{
  if(DISABLE != state)
  {
    /* Enable EPWM ADC compare2 functions. */
    EPWM->CMP_CFG |= EPWM_CMP_CFG_ADC_CMP2_EN_Msk;
  }
  else
  {
    /* Disable EPWM ADC compare2 functions. */
    EPWM->CMP_CFG &= ~EPWM_CMP_CFG_ADC_CMP2_EN_Msk;
  }
}
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

/**
 *******************************************************************************
 * @brief   Initializes the EPWM peripheral channelx output function according to
 *          the specified parameters in the EPWM_CHInitTypeStruct.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_CHInitType: Structure pointer of EPWM channelx output configuration.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHInit(EPWM_ChannelEnum EPWM_Channel, EPWM_CHInitTypeStruct* EPWM_CHInitType)
{
  uint32_t tmpReg0 = 0u, tmpReg1 = 0u;

  /* Parameters check. */
  PARAM_ASSERT(IS_EPWM_CHANNEL(EPWM_Channel));
  PARAM_ASSERT(IS_EPWM_CMP_ACTION(EPWM_CHInitType->EPWM_Compare1Action));
  PARAM_ASSERT(IS_EPWM_CMP_ACTION(EPWM_CHInitType->EPWM_Compare2Action));
  PARAM_ASSERT(IS_EPWM_CMP_DIRECTION(EPWM_CHInitType->EPWM_Compare1Dir));
  PARAM_ASSERT(IS_EPWM_CMP_DIRECTION(EPWM_CHInitType->EPWM_Compare2Dir));
  PARAM_ASSERT(IS_EPWM_CH_INIT_STATUS(EPWM_CHInitType->EPWM_CHInitStatus));
  PARAM_ASSERT(IS_EPWM_CH_OUT_POLARITY(EPWM_CHInitType->EPWM_PPolarity));
  PARAM_ASSERT(IS_EPWM_CH_OUT_POLARITY(EPWM_CHInitType->EPWM_NPolarity));

  /* Sets the EPWM channel compare1 register value. */
  EPWM_CHCMP1(EPWM_Channel) = (uint32_t)EPWM_CHInitType->EPWM_Compare1Value;

  /* Sets the EPWM channel compare2 register value. */
  EPWM_CHCMP2(EPWM_Channel) = (uint32_t)EPWM_CHInitType->EPWM_Compare2Value;

  /* Read the value of the EPWM channel control register. */
  tmpReg0 = EPWM->CH_CR;

  /* Clear EPWM CH_CMP1_ACT,_CH_CMP2_ACT,CH_INIT_O,CH_NP,CH_PP bits. */
  tmpReg0 &= ~((EPWM_CH_CR_CH0_CMP1_ACT_Msk << 0x04u * EPWM_Channel) \
               | (EPWM_CH_CR_CH0_CMP2_ACT_Msk << 0x04u * EPWM_Channel) \
               | (EPWM_CH_CR_CH0_INIT_O_Msk << EPWM_Channel) \
               | (EPWM_CH_CR_CH0_NP_Msk << 0x02u * EPWM_Channel) \
               | (EPWM_CH_CR_CH0_PP_Msk << 0x02u * EPWM_Channel));

  /* Set EPWM CH_CMP1_ACT[1:0] bits according to EPWM_CHInitType. */
  tmpReg0 |= (uint32_t)(EPWM_CHInitType->EPWM_Compare1Action << (EPWM_CH_CR_CH0_CMP1_ACT_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_CMP2_ACT[1:0] bits according to EPWM_CHInitType. */
  tmpReg0 |= (uint32_t)(EPWM_CHInitType->EPWM_Compare2Action << (EPWM_CH_CR_CH0_CMP2_ACT_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_INIT_O bit according to EPWM_CHInitType. */
  tmpReg0 |= (uint32_t)(EPWM_CHInitType->EPWM_CHInitStatus << (EPWM_CH_CR_CH0_INIT_O_Pos + EPWM_Channel));

  /* Set EPWM CH_NP bit according to EPWM_CHInitType. */
  tmpReg0 |= (uint32_t)(EPWM_CHInitType->EPWM_NPolarity << (EPWM_CH_CR_CH0_NP_Pos + 0x02u * EPWM_Channel));

  /* Set EPWM CH_PP bit according to EPWM_CHInitType. */
  tmpReg0 |= (uint32_t)(EPWM_CHInitType->EPWM_PPolarity << (EPWM_CH_CR_CH0_PP_Pos + 0x02u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CH_CR = tmpReg0;

  /* Read the value of the EPWM compare config register. */
  tmpReg1 = EPWM->CMP_CFG;

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  /* Clear EPWM CH_CMP1_DIR,CH_CMP2_DIR,CH_CMP1_EN,CH_CMP2_EN bit. */
  tmpReg1 &= ~((EPWM_CMP_CFG_CH0_CMP1_DIR_Msk << 0x04u * EPWM_Channel) \
               | (EPWM_CMP_CFG_CH0_CMP2_DIR_Msk << 0x04u * EPWM_Channel) \
               | (EPWM_CMP_CFG_CH0_CMP1_EN_Msk << 0x04u * EPWM_Channel) \
               | (EPWM_CMP_CFG_CH0_CMP2_EN_Msk << 0x04u * EPWM_Channel));
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  /* Clear EPWM CH_CMP1_DIR,CH_CMP2_DIR bit. */
  tmpReg1 &= ~((EPWM_CMP_CFG_CH0_CMP1_DIR_Msk << 0x04u * EPWM_Channel) \
               | (EPWM_CMP_CFG_CH0_CMP2_DIR_Msk << 0x04u * EPWM_Channel));
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */


  /* Set EPWM CH_CMP1_DIR bit according to EPWM_CHInitType. */
  tmpReg1 |= (uint32_t)(EPWM_CHInitType->EPWM_Compare1Dir << (EPWM_CMP_CFG_CH0_CMP1_DIR_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_CMP2_DIR bit according to EPWM_CHInitType. */
  tmpReg1 |= (uint32_t)(EPWM_CHInitType->EPWM_Compare2Dir << (EPWM_CMP_CFG_CH0_CMP2_DIR_Pos + 0x04u * EPWM_Channel));


#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_CHInitType->EPWM_Compare1State));
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_CHInitType->EPWM_Compare2State));
  /* Set EPWM CH_CMP1_EN bit according to EPWM_CHInitType. */
  tmpReg1 |= (uint32_t)(EPWM_CHInitType->EPWM_Compare1State << (EPWM_CMP_CFG_CH0_CMP1_EN_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_CMP2_EN bit according to EPWM_CHInitType. */
  tmpReg1 |= (uint32_t)(EPWM_CHInitType->EPWM_Compare2State << (EPWM_CMP_CFG_CH0_CMP2_EN_Pos + 0x04u * EPWM_Channel));
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

  /* Store the new value. */
  EPWM->CMP_CFG = tmpReg1;
}

/**
 *******************************************************************************
 * @brief   Initialize the EPWM_CHInitType with default parameters.
 * @param   [in]  EPWM_CHInitType: Pointer to a EPWM_OutputInitTypeStruct structure
 *                which will be initialized.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHStructInit(EPWM_CHInitTypeStruct* EPWM_CHInitType)
{
  EPWM_CHInitType->EPWM_Compare1Value = 0xFFFF;
  EPWM_CHInitType->EPWM_Compare2Value = 0xFFFF;
  EPWM_CHInitType->EPWM_Compare1Action = EPWM_CMP_ACT_OUTPUT_FLIP;
  EPWM_CHInitType->EPWM_Compare2Action = EPWM_CMP_ACT_OUTPUT_FLIP;
  EPWM_CHInitType->EPWM_CHInitStatus = EPWM_CH_INIT_STATUS_0;
  EPWM_CHInitType->EPWM_NPolarity = EPWM_CH_OUT_POLARITY_NORMAL;
  EPWM_CHInitType->EPWM_PPolarity = EPWM_CH_OUT_POLARITY_NORMAL;
  EPWM_CHInitType->EPWM_Compare1Dir = EPWM_CMP_DIR_INCREASE;
  EPWM_CHInitType->EPWM_Compare2Dir = EPWM_CMP_DIR_INCREASE;
  
#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  EPWM_CHInitType->EPWM_Compare1State = ENABLE;
  EPWM_CHInitType->EPWM_Compare2State = ENABLE;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx compare1 register new value.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Value: Specifies the channelx compare1 register new value.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHCompare1Value(EPWM_ChannelEnum EPWM_Channel, uint16_t EPWM_Value)
{
  /* Sets the EPWM channel compare1 register value. */
  EPWM_CHCMP1(EPWM_Channel) = (uint32_t)EPWM_Value;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx compare2 register new value.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Value: Specifies the channelx compare1 register new value.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHCompare2Value(EPWM_ChannelEnum EPWM_Channel, uint16_t EPWM_Value)
{
  /* Sets the EPWM channel compare2 register value. */
  EPWM_CHCMP2(EPWM_Channel) = (uint32_t)EPWM_Value;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx compare1 new action.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Act: Specifies the channelx compare1 new action.
 *                This parameter can be a value of @ref EPWM_CmpActEnum.
 *                  @arg EPWM_CMP_ACT_OUTPUT_LOW: When counter is equal to
 *                       compare1 value,output low.
 *                  @arg EPWM_CMP_ACT_OUTPUT_HIGH: When counter is equal to
 *                       compare1 value,output high.
 *                  @arg EPWM_CMP_ACT_OUTPUT_FLIP: When counter is equal to
 *                       compare1 value,output flip.
 *                  @arg EPWM_CMP_ACT_OUTPUT_UNCHANGE: When counter is equal to
 *                       compare1 value,output unchange.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHCompare1Action(EPWM_ChannelEnum EPWM_Channel, EPWM_CmpActEnum EPWM_Act)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM channel control register. */
  tmpReg = EPWM->CH_CR;

  /* Clear EPWM CH_CMP1_ACT[1:0] bits. */
  tmpReg &= ~(EPWM_CH_CR_CH0_CMP1_ACT_Msk << 0x04u * EPWM_Channel);

  /* Set EPWM CH_CMP1_ACT[1:0] bits according to EPWM_Act. */
  tmpReg |= (uint32_t)(EPWM_Act << (EPWM_CH_CR_CH0_CMP1_ACT_Pos + 0x04u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CH_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx compare2 new action.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Act: Specifies the channelx compare1 new action.
 *                This parameter can be a value of @ref EPWM_CmpActEnum.
 *                  @arg EPWM_CMP_ACT_OUTPUT_LOW: When counter is equal to
 *                       compare1 value,output low.
 *                  @arg EPWM_CMP_ACT_OUTPUT_HIGH: When counter is equal to
 *                       compare1 value,output high.
 *                  @arg EPWM_CMP_ACT_OUTPUT_FLIP: When counter is equal to
 *                       compare1 value,output flip.
 *                  @arg EPWM_CMP_ACT_OUTPUT_UNCHANGE: When counter is equal to
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHCompare2Action(EPWM_ChannelEnum EPWM_Channel, EPWM_CmpActEnum EPWM_Act)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM channel control register. */
  tmpReg = EPWM->CH_CR;

  /* Clear EPWM CH_CMP2_ACT[1:0] bits. */
  tmpReg &= ~(EPWM_CH_CR_CH0_CMP2_ACT_Msk << 0x04u * EPWM_Channel);

  /* Set EPWM CH_CMP2_ACT[1:0] bits according to EPWM_Act. */
  tmpReg |= (uint32_t)(EPWM_Act << (EPWM_CH_CR_CH0_CMP2_ACT_Pos + 0x04u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CH_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channel0 initial output level.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Level: Specifies the channelx initial output level.
 *                This parameter can be a value of @ref EPWM_CHInitStatusEnum.
 *                  @arg EPWM_CH_INIT_SR_0: Channelx initial output status 0.
 *                  @arg EPWM_CH_INIT_SR_1: Channelx initial output status 1.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHInitOutputLevel(EPWM_ChannelEnum EPWM_Channel, EPWM_CHInitStatusEnum EPWM_InitStatus)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM channel control register. */
  tmpReg = EPWM->CH_CR;

  /* Clear EPWM CH_INIT_O bit. */
  tmpReg &= ~(EPWM_CH_CR_CH0_INIT_O_Msk << EPWM_Channel);

  /* Set EPWM CH_INIT_O bit according to EPWM_Level. */
  tmpReg |= (uint32_t)(EPWM_InitStatus << (EPWM_CH_CR_CH0_INIT_O_Pos + EPWM_Channel));

  /* Store the new value. */
  EPWM->CH_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx Nchannel polarity.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Pol: Specifies the channelx Nchannel polarity.
 *                This parameter can be a value of @ref EPWM_CHOutPolarityEnum.
 *                  @arg EPWM_CH_OUT_POLARITY_NORMAL: Channelx N channel normal output.
 *                  @arg EPWM_CH_OUT_POLARITY_INVERT: Channelx N channel invert output.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHNPolarity(EPWM_ChannelEnum EPWM_Channel, EPWM_CHOutPolarityEnum EPWM_Pol)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM channel control register. */
  tmpReg = EPWM->CH_CR;

  /* Clear EPWM CH_NP bit. */
  tmpReg &= ~(EPWM_CH_CR_CH0_NP_Msk << 0x02u * EPWM_Channel);

  /* Set EPWM CH_NP bit according to EPWM_Pol. */
  tmpReg |= (uint32_t)(EPWM_Pol << (EPWM_CH_CR_CH0_NP_Pos + 0x02u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CH_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx Pchannel polarity.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Pol: Specifies the channelx Pchannel polarity.
 *                This parameter can be a value of @ref EPWM_CHOutPolarityEnum.
 *                  @arg EPWM_CH_OUT_POLARITY_NORMAL: Channelx P channel normal output.
 *                  @arg EPWM_CH_OUT_POLARITY_INVERT: Channelx P channel invert output.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHPPolarity(EPWM_ChannelEnum EPWM_Channel, EPWM_CHOutPolarityEnum EPWM_Pol)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM channel control register. */
  tmpReg = EPWM->CH_CR;

  /* Clear EPWM CH_PP bit. */
  tmpReg &= ~(EPWM_CH_CR_CH0_PP_Msk << 0x02u * EPWM_Channel);

  /* Set EPWM CH_PP bit according to EPWM_Pol. */
  tmpReg |= (uint32_t)(EPWM_Pol << (EPWM_CH_CR_CH0_PP_Pos + 0x02u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CH_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx compare1 direction.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Dir: Specifies the channelx compare1 direction.
 *                This parameter can be a value of @ref EPWM_CmpDirEnum.
 *                  @arg EPWM_CMP_DIR_INCREASE: Compare value in increase valid.
 *                  @arg EPWM_CMP_DIR_DECREASE: Compare value in decrease valid.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHCompare1Dir(EPWM_ChannelEnum EPWM_Channel, EPWM_CmpDirEnum EPWM_Dir)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM compare configuration register. */
  tmpReg = EPWM->CMP_CFG;

  /* Clear EPWM CH_CMP1_DIR bit. */
  tmpReg &= ~(EPWM_CMP_CFG_CH0_CMP1_DIR_Msk << 0x4u * EPWM_Channel);

  /* Set EPWM CH_CMP1_DIR bit according to dir. */
  tmpReg |= (uint32_t)(EPWM_Dir << (EPWM_CMP_CFG_CH0_CMP1_DIR_Pos + 0x4u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CMP_CFG = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx compare2 direction.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Dir: Specifies the channelx compare2 direction.
 *                This parameter can be a value of @ref EPWM_CmpDirEnum.
 *                  @arg EPWM_CMP_DIR_INCREASE: Compare value in increase valid.
 *                  @arg EPWM_CMP_DIR_DECREASE: Compare value in decrease valid.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHCompare2Dir(EPWM_ChannelEnum EPWM_Channel, EPWM_CmpDirEnum EPWM_Dir)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM compare configuration register. */
  tmpReg = EPWM->CMP_CFG;

  /* Clear EPWM CH_CMP2_DIR bit. */
  tmpReg &= ~(EPWM_CMP_CFG_CH0_CMP2_DIR_Msk << 0x4u * EPWM_Channel);

  /* Set EPWM CH_CMP2_DIR bit according to dir. */
  tmpReg |= (uint32_t)(EPWM_Dir << (EPWM_CMP_CFG_CH0_CMP2_DIR_Pos + 0x4u * EPWM_Channel));

  /* Store the new value. */
  EPWM->CMP_CFG = tmpReg;
}

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM channelx compare1 functions.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  NewState: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHCompare1Cmd(EPWM_ChannelEnum EPWM_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable EPWM channel0 compare1 functions. */
    EPWM->CMP_CFG |= (EPWM_CMP_CFG_CH0_CMP1_EN_Msk << 0x04 * EPWM_Channel);
  }
  else
  {
    /* Disable EPWM channel0 compare1 functions. */
    EPWM->CMP_CFG &= ~(EPWM_CMP_CFG_CH0_CMP1_EN_Msk << 0x04 * EPWM_Channel);
  }
}

/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM channelx compare2 functions.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  NewState: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHCompare2Cmd(EPWM_ChannelEnum EPWM_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable EPWM channel0 compare2 functions. */
    EPWM->CMP_CFG |= (EPWM_CMP_CFG_CH0_CMP2_EN_Msk << 0x04 * EPWM_Channel);
  }
  else
  {
    /* Disable EPWM channel compare2 functions. */
    EPWM->CMP_CFG &= ~(EPWM_CMP_CFG_CH0_CMP2_EN_Msk << 0x04 * EPWM_Channel);
  }
}
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM channelx functions.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  NewState: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHCmd(EPWM_ChannelEnum EPWM_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable EPWM channel0 functions. */
    EPWM->CR |= (EPWM_CR_CH0_EN_Msk << EPWM_Channel);
  }
  else
  {
    /* Disable EPWM channel0 functions. */
    EPWM->CR &= ~(EPWM_CR_CH0_EN_Msk << EPWM_Channel);
  }
}

/**
 *******************************************************************************
 * @brief   Initializes the EPWM peripheral channel force output function according to
 *          the specified parameters in the EPWM_FOInitTypeStruct.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_FOInitType: Structure pointer of EPWM force output configuration.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHForceOutInit(EPWM_ChannelEnum EPWM_Channel, EPWM_FOInitTypeStruct* EPWM_FOInitType)
{
  uint32_t tmpReg = 0UL;

  /* Parameters check. */
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_FOInitType->EPWM_FONState));
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_FOInitType->EPWM_FOPState));
  PARAM_ASSERT(IS_EPWM_FORCE_OUT_LEVEL(EPWM_FOInitType->EPWM_FONLevel));
  PARAM_ASSERT(IS_EPWM_FORCE_OUT_LEVEL(EPWM_FOInitType->EPWM_FOPLevel));
  PARAM_ASSERT(IS_EPWM_CHANNEL(EPWM_Channel));

  /* Read the value of the EPWM output control register. */
  tmpReg = EPWM->OUT_CR;

  /* Clear EPWM CH_N_FORCE_O,CH0_P_FORCE_O,CH_N_FORCE_EN,CH_P_FORCE_EN bit. */
  tmpReg &= ~((EPWM_OUT_CR_CH0_N_FORCE_O_Msk \
               | EPWM_OUT_CR_CH0_P_FORCE_O_Msk \
               | EPWM_OUT_CR_CH0_N_FORCE_EN_Msk \
               | EPWM_OUT_CR_CH0_P_FORCE_EN_Msk) << 0x04u * EPWM_Channel);

  /* Set EPWM CH_P_FORCE_O bit according to EPWM_ForceOutInitStruct. */
  tmpReg |= (uint32_t)(EPWM_FOInitType->EPWM_FOPLevel << (EPWM_OUT_CR_CH0_P_FORCE_O_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_N_FORCE_O bit according to EPWM_ForceOutInitStruct. */
  tmpReg |= (uint32_t)(EPWM_FOInitType->EPWM_FONLevel << (EPWM_OUT_CR_CH0_N_FORCE_O_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_P_FORCE_EN bit according to EPWM_ForceOutInitStruct. */
  tmpReg |= (uint32_t)(EPWM_FOInitType->EPWM_FOPState << (EPWM_OUT_CR_CH0_P_FORCE_EN_Pos + 0x04u * EPWM_Channel));

  /* Set EPWM CH_N_FORCE_EN bit according to EPWM_ForceOutInitStruct. */
  tmpReg |= (uint32_t)(EPWM_FOInitType->EPWM_FONState << (EPWM_OUT_CR_CH0_N_FORCE_EN_Pos + 0x04u * EPWM_Channel));

  /* Store the new value. */
  EPWM->OUT_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Initialize the EPWM_ForceOutInitStruct with default parameters.
 * @param   [out] EPWM_ForceOutInitStruct: Pointer to a EPWM_FOInitTypeStruct structure
 *                which will be initialized.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHForceOutStructInit(EPWM_FOInitTypeStruct* EPWM_FOInitType)
{
  EPWM_FOInitType->EPWM_FONLevel = EPWM_FO_LEVEL_LOW;
  EPWM_FOInitType->EPWM_FOPLevel = EPWM_FO_LEVEL_LOW;
  EPWM_FOInitType->EPWM_FONState = DISABLE;
  EPWM_FOInitType->EPWM_FOPState = DISABLE;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx N channel force output level.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Level: Specifies the channelx N channel force output level.
 *                This parameter can be a value of @ref EPWM_FOLevelEnum.
 *                  @arg EPWM_FO_LEVEL_LOW: Channelx N channel force output low level.
 *                  @arg EPWM_FO_LEVEL_HIGH: Channelx N channel force output high level.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHNForceLevel(EPWM_ChannelEnum EPWM_Channel, EPWM_FOLevelEnum EPWM_Level)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM output control register. */
  tmpReg = EPWM->OUT_CR;

  /* Clear EPWM CH_N_FORCE_O bit. */
  tmpReg &= ~(EPWM_OUT_CR_CH0_N_FORCE_O_Msk << 0x04u * EPWM_Channel);

  /* Set EPWM CH_N_FORCE_O bit according to level. */
  tmpReg |= (uint32_t)(EPWM_Level << (EPWM_OUT_CR_CH0_N_FORCE_O_Pos + 0x04u * EPWM_Channel));

  /* Store the new value. */
  EPWM->OUT_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx P channel force output level.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Level: Specifies the channelx P channel force output level.
 *                This parameter can be a value of @ref EPWM_FOLevelEnum.
 *                  @arg EPWM_FO_LEVEL_LOW: Channelx P channel force output low level.
 *                  @arg EPWM_FO_LEVEL_HIGH: Channelx P channel force output high level.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetCHPForceLevel(EPWM_ChannelEnum EPWM_Channel, EPWM_FOLevelEnum EPWM_Level)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM output control register. */
  tmpReg = EPWM->OUT_CR;

  /* Clear EPWM CH_P_FORCE_O bit. */
  tmpReg &= ~(EPWM_OUT_CR_CH0_P_FORCE_O_Msk << 0x04u * EPWM_Channel);

  /* Set EPWM CH_P_FORCE_O bit according to level. */
  tmpReg |= (uint32_t)(EPWM_Level << (EPWM_OUT_CR_CH0_P_FORCE_O_Pos + 0x04u * EPWM_Channel));

  /* Store the new value. */
  EPWM->OUT_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM channel0 N channel force output.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  NewState: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHNForceCmd(EPWM_ChannelEnum EPWM_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable EPWM channel N channel force output. */
    EPWM->OUT_CR |= (EPWM_OUT_CR_CH0_N_FORCE_EN_Msk << 0x04u * EPWM_Channel);
  }
  else
  {
    /* Disable EPWM channel N channel force output. */
    EPWM->OUT_CR &= ~(EPWM_OUT_CR_CH0_N_FORCE_EN_Msk << 0x04u * EPWM_Channel);
  }
}

/**
 *******************************************************************************
 * @brief   Enables or disables the EPWM channelx P channel force output.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  NewState: This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_CHPForceCmd(EPWM_ChannelEnum EPWM_Channel, FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    /* Enable EPWM channel P channel force output. */
    EPWM->OUT_CR |= (EPWM_OUT_CR_CH0_P_FORCE_EN_Msk << 0x04u * EPWM_Channel);
  }
  else
  {
    /* Disable EPWM channel P channel force output. */
    EPWM->OUT_CR &= ~(EPWM_OUT_CR_CH0_P_FORCE_EN_Msk << 0x04u * EPWM_Channel);
  }
}

/**
 *******************************************************************************
 * @brief   EPWM update all shadow registers.
 * @retval  None.
 ******************************************************************************/
void EPWM_UpdateShadowRegister(void)
{
  /*  Software set 1 to update all shadow registers . */
  EPWM->UPDATE |= EPWM_UPDATE_UPDATE_Msk;
}

/**
 *******************************************************************************
 * @brief   Configuration EPWM death time len.
 * @param   [in]  EPWM_Value: Death time length.
 *                This parameter can be a number between 0 and 0x1FF.
 * @retval  None.
 ******************************************************************************/
void EPWM_DeathTimeLenConfig(uint16_t EPWM_Value)
{
  /* Set the dead time control register value. */
  EPWM->DT_CR = EPWM_Value;
}

/**
 *******************************************************************************
 * @brief   Initializes the EPWM peripheral emergency stop function according to
 *          the specified parameters in the EPWM_ESInitTypeStruct.
 * @param   [in]  EPWM_ESInitType: Structure pointer of EPWM ADC compare configuration.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESInit(EPWM_ESInitTypeStruct* EPWM_ESInitType)
{
  uint32_t tmpReg = 0UL;

  /* Parameters check. */
  PARAM_ASSERT(IS_EPWM_ES_FILT_SAMPEL_DIV(EPWM_ESInitType->EPWM_ESFiltSampleDiv));
  PARAM_ASSERT(IS_EPWM_ES_FILT_LEN(EPWM_ESInitType->EPWM_ESFiltLen));
  PARAM_ASSERT(IS_EPWM_ES_EXT_POLARITY(EPWM_ESInitType->EPWM_ESExtPolarity));
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_ESInitType->EPWM_ESExtState));
  PARAM_ASSERT(IS_EPWM_ES_ACMP_POLARITY(EPWM_ESInitType->EPWM_ESACMPPolarity));
  PARAM_ASSERT(IS_EPWM_ES_ACMP_CHANNEL(EPWM_ESInitType->EPWM_ESACMPChannel));
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  PARAM_ASSERT(IS_EPWM_ES_ACMP_MODE(EPWM_ESInitType->EPWM_ESACMPMode));
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_ESInitType->EPWM_ESACMPState));
  PARAM_ASSERT(IS_FUNCTION_STATE(EPWM_ESInitType->EPWM_ESDebugState));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH0NLevel));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH0PLevel));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH1NLevel));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH1PLevel));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH2NLevel));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH2PLevel));

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH3NLevel));
  PARAM_ASSERT(IS_EPWM_ES_CH_OUT_LEVEL(EPWM_ESInitType->EPWM_ESCH3PLevel));
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  /* Clear EPWM FLT_SAMPLE,FLT_LEN,EXT_STOP_EN,EXT_POL_SEL, ACMP_STOP_EN,
     ACMP_POL_SEL,ACMP_SEL,DBG_STOP_EN,CH0_N_STOP_O,CH0_P_STOP_O,CH1_N_STOP_O,
     CH1_P_STOP_O,CH2_N_STOP_O,CH2_P_STOP_O,CH3_N_STOP_O,CH3_P_STOP_O bits. */
  tmpReg &= ~(EPWM_STOP_CR_FLT_SAMPLE_Msk | EPWM_STOP_CR_FLT_LEN_Msk \
              | EPWM_STOP_CR_EXT_STOP_EN_Msk | EPWM_STOP_CR_EXT_POL_SEL_Msk \
              | EPWM_STOP_CR_ACMP_STOP_EN_Msk | EPWM_STOP_CR_ACMP_POL_SEL_Msk \
              | EPWM_STOP_CR_ACMP_SEL_Msk | EPWM_STOP_CR_DBG_STOP_EN_Msk \
              | EPWM_STOP_CR_CH0_N_STOP_O_Msk | EPWM_STOP_CR_CH0_P_STOP_O_Msk \
              | EPWM_STOP_CR_CH1_N_STOP_O_Msk | EPWM_STOP_CR_CH1_P_STOP_O_Msk \
              | EPWM_STOP_CR_CH2_N_STOP_O_Msk | EPWM_STOP_CR_CH2_P_STOP_O_Msk \
              | EPWM_STOP_CR_CH3_N_STOP_O_Msk | EPWM_STOP_CR_CH3_P_STOP_O_Msk);
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  /* Clear EPWM FLT_SAMPLE,FLT_LEN,EXT_STOP_EN,EXT_POL_SEL, ACMP_STOP_EN,
     ACMP_POL_SEL,ACMP_SEL,DBG_STOP_EN,ACMP_MODE,CH0_N_STOP_O,CH0_P_STOP_O,
     CH1_N_STOP_O,CH1_P_STOP_O,CH2_N_STOP_O,CH2_P_STOP_O bits. */
  tmpReg &= ~(EPWM_STOP_CR_FLT_SAMPLE_Msk | EPWM_STOP_CR_FLT_LEN_Msk \
              | EPWM_STOP_CR_EXT_STOP_EN_Msk | EPWM_STOP_CR_EXT_POL_SEL_Msk \
              | EPWM_STOP_CR_ACMP_STOP_EN_Msk | EPWM_STOP_CR_ACMP_POL_SEL_Msk \
              | EPWM_STOP_CR_ACMP_SEL_Msk | EPWM_STOP_CR_DBG_STOP_EN_Msk 
              | EPWM_STOP_CR_ACMP_MODE_Msk \
              | EPWM_STOP_CR_CH0_N_STOP_O_Msk | EPWM_STOP_CR_CH0_P_STOP_O_Msk \
              | EPWM_STOP_CR_CH1_N_STOP_O_Msk | EPWM_STOP_CR_CH1_P_STOP_O_Msk \
              | EPWM_STOP_CR_CH2_N_STOP_O_Msk | EPWM_STOP_CR_CH2_P_STOP_O_Msk);
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */


  /* Set EPWM FLT_SAMPLE[1:0] bits according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESFiltSampleDiv << EPWM_STOP_CR_FLT_SAMPLE_Pos);

  /* Set EPWM FLT_LEN[1:0] bits according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESFiltLen << EPWM_STOP_CR_FLT_LEN_Pos);

  /* Set EPWM EXT_STOP_EN bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESExtState << EPWM_STOP_CR_EXT_STOP_EN_Pos);

  /* Set EPWM EXT_POL_SEL bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESExtPolarity << EPWM_STOP_CR_EXT_POL_SEL_Pos);

  /* Set EPWM ACMP_STOP_EN bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESACMPState << EPWM_STOP_CR_ACMP_STOP_EN_Pos);

  /* Set EPWM ACMP_POL_SEL bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESACMPPolarity << EPWM_STOP_CR_ACMP_POL_SEL_Pos);

  /* Set EPWM ACMP_SEL bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESACMPChannel << EPWM_STOP_CR_ACMP_SEL_Pos);
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  /* Set EPWM ACMP_SEL bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESACMPMode << EPWM_STOP_CR_ACMP_MODE_Pos);
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */

  /* Set EPWM DBG_STOP_EN bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESDebugState << EPWM_STOP_CR_DBG_STOP_EN_Pos);

  /* Set EPWM CH0_N_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH0NLevel << EPWM_STOP_CR_CH0_N_STOP_O_Pos);

  /* Set EPWM CH0_P_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH0PLevel << EPWM_STOP_CR_CH0_P_STOP_O_Pos);

  /* Set EPWM CH1_N_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH1NLevel << EPWM_STOP_CR_CH1_N_STOP_O_Pos);

  /* Set EPWM CH1_P_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH1PLevel << EPWM_STOP_CR_CH1_P_STOP_O_Pos);

  /* Set EPWM CH2_N_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH2NLevel << EPWM_STOP_CR_CH2_N_STOP_O_Pos);

  /* Set EPWM CH2_P_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH2PLevel << EPWM_STOP_CR_CH2_P_STOP_O_Pos);

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  /* Set EPWM CH3_N_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH3NLevel << EPWM_STOP_CR_CH3_N_STOP_O_Pos);
  /* Set EPWM CH3_P_STOP_O bit according to EPWM_ESInitType. */
  tmpReg |= (uint32_t)(EPWM_ESInitType->EPWM_ESCH3PLevel << EPWM_STOP_CR_CH3_P_STOP_O_Pos);
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Initialize the EPWM_ESInitType with default parameters.
 * @param   [in]  EPWM_ESInitType Pointer to a EPWM_ESInitTypeStruct structure which will be initialized.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESStructInit(EPWM_ESInitTypeStruct* EPWM_ESInitType)
{
  EPWM_ESInitType->EPWM_ESFiltSampleDiv = EPWM_ES_FILT_SAMPLE_DIV1;
  EPWM_ESInitType->EPWM_ESFiltLen = EPWM_ES_FLT_LEN8;
  EPWM_ESInitType->EPWM_ESExtPolarity = EPWM_ES_EXT_POLARITY_LOW;
  EPWM_ESInitType->EPWM_ESExtState = DISABLE;
  EPWM_ESInitType->EPWM_ESACMPPolarity = EPWM_ES_ACMP_POLARITY_LOW;
#if defined (DPM32M015)   
  EPWM_ESInitType->EPWM_ESACMPChannel = EPWM_ES_ACMP1;
#else /* DPM32M08x || DPM32M05x || DPM32M03x || DPM32M036 || DPM32M030 */
  EPWM_ESInitType->EPWM_ESACMPChannel = EPWM_ES_ACMP0;
#endif /* DPM32M015 */
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  EPWM_ESInitType->EPWM_ESACMPMode = EPWM_ES_ACMP_MODE_LATCH;
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */

  EPWM_ESInitType->EPWM_ESACMPState = DISABLE;
  EPWM_ESInitType->EPWM_ESDebugState = DISABLE;
  EPWM_ESInitType->EPWM_ESCH0NLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
  EPWM_ESInitType->EPWM_ESCH0PLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
  EPWM_ESInitType->EPWM_ESCH1NLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
  EPWM_ESInitType->EPWM_ESCH1PLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
  EPWM_ESInitType->EPWM_ESCH2NLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
  EPWM_ESInitType->EPWM_ESCH2PLevel = EPWM_ES_CH_OUT_LEVEL_LOW;

#if defined (DPM32M08x) || defined (DPM32M05x) || defined (DPM32M03x)
  EPWM_ESInitType->EPWM_ESCH3NLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
  EPWM_ESInitType->EPWM_ESCH3PLevel = EPWM_ES_CH_OUT_LEVEL_LOW;
#endif /* DPM32M08x || DPM32M05x || DPM32M03x */

}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ememrgency stop filter sample division.
 * @param   [in]  EPWM_Div: Specifies the filter sample division.
 *                This parameter can be a value of @ref EPWM_ESFiltSampleDivEnum.
 *                  @arg EPWM_ES_FLT_SAMPLE_DIV1: The filter sample clock is equal to PCLK.
 *                  @arg EPWM_ES_FLT_SAMPLE_DIV4: The filter sample clock is equal to PCLK/4.
 *                  @arg EPWM_ES_FLT_SAMPLE_DIV16: The filter sample clock is equal to PCLK/16.
 *                  @arg EPWM_ES_FLT_SAMPLE_DIV32: The filter sample clock is equal to PCLK/32.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESFiltSampleDiv(EPWM_ESFiltSampleDivEnum EPWM_Div)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM FLT_SAMPLE[1:0] bits. */
  tmpReg &= ~EPWM_STOP_CR_FLT_SAMPLE_Msk;

  /* Set EPWM FLT_SAMPLE[1:0] bits according to EPWM_Div. */
  tmpReg |= (uint32_t)(EPWM_Div << EPWM_STOP_CR_FLT_SAMPLE_Pos);

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ememrgency stop filter sample cycles length.
 * @param   [in]  EPWM_Len: Specifies the filter sample cycles length.
 *                This parameter can be a value of @ref EPWM_ESFiltLenEnum.
 *                  @arg EPWM_ES_FLT_LEN1: Filter samples 1 cycles length.
 *                  @arg EPWM_ES_FLT_LEN8: Filter samples 8 cycles length.
 *                  @arg EPWM_ES_FLT_LEN16: Filter samples 16 cycles length.
 *                  @arg EPWM_ES_FLT_LEN32: Filter samples 32 cycles length.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESFiltLen(EPWM_ESFiltLenEnum EPWM_Len)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM FLT_LEN[1:0] bits. */
  tmpReg &= ~EPWM_STOP_CR_FLT_LEN_Msk;

  /* Set EPWM FLT_LEN[1:0] bits according to EPWM_Len. */
  tmpReg |= (uint32_t)(EPWM_Len << EPWM_STOP_CR_FLT_LEN_Pos);

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ememrgency stop external trigger polarity.
 * @param   [in]  EPWM_Pol: Specifies the exit trigger polarity.
 *                This parameter can be a value of @ref EPWM_ESExtPolarityEnum.
 *                  @arg EPWM_ES_EXT_POLARITY_LOW: Low level trigger ememrgency stop.
 *                  @arg EPWM_ES_EXT_POLARITY_HIGH: High level trigger ememrgency stop.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESExtPolarity(EPWM_ESExtPolarityEnum EPWM_Pol)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM EXT_POL_SEL bit. */
  tmpReg &= ~EPWM_STOP_CR_EXT_POL_SEL_Msk;

  /* Set EPWM EXT_POL_SEL bit according to EPWM_Pol. */
  tmpReg |= (uint32_t)(EPWM_Pol << EPWM_STOP_CR_EXT_POL_SEL_Pos);

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Enable or disable EPWM external trigger emergency stop functions.
 * @param   [in]  state: New state of the exit state bit.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESExtCmd(FunctionalState state)
{
  if(DISABLE != state)
  {
    EPWM->STOP_CR |= EPWM_STOP_CR_EXT_STOP_EN_Msk;
  }
  else
  {
    EPWM->STOP_CR &= ~EPWM_STOP_CR_EXT_STOP_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ememrgency stop ACMP trigger polarity.
 * @param   [in]  EPWM_Pol: Specifies the ACMP trigger polarity.
 *                This parameter can be a value of @ref EPWM_ESACMPPolarityEnum.
 *                  @arg EPWM_ES_ACMP_POLARITY_LOW: Low level trigger ememrgency stop.
 *                  @arg EPWM_ES_ACMP_POLARITY_HIGH: High level trigger ememrgency stop.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESACMPPolarity(EPWM_ESACMPPolarityEnum EPWM_Pol)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM ACMP_POL_SEL bit. */
  tmpReg &= ~EPWM_STOP_CR_ACMP_POL_SEL_Msk;

  /* Set EPWM ACMP_POL_SEL bit according to EPWM_Pol. */
  tmpReg |= (uint32_t)(EPWM_Pol << EPWM_STOP_CR_ACMP_POL_SEL_Pos);

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM ememrgency stop ACMP channel.
 * @param   [in]  EPWM_Chl: Specifies the ACMP channel.
 *                This parameter can be a value of @ref EPWM_ESACMPChannelEnum.
 *                DPM32M08x|DPM32M05x|DPM32M03x:
 *                  @arg EPWM_ES_ACMP0: ACMP channel0.
 *                  @arg EPWM_ES_ACMP1: ACMP channel1.
 *                  @arg EPWM_ES_ACMP2: ACMP channel2.
 *                  @arg EPWM_ES_ACMP3: ACMP channel3.
 *                DPM32M036|DPM32M030:
 *                  @arg EPWM_ES_ACMP0: ACMP channel0.
 *                  @arg EPWM_ES_ACMP1: ACMP channel1.
 *                DPM32M015:
 *                  @arg EPWM_ES_ACMP1: ACMP channel0.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESACMPChannel(EPWM_ESACMPChannelEnum EPWM_Chl)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM ACMP_SEL bits. */
  tmpReg &= ~EPWM_STOP_CR_ACMP_SEL_Msk;

  /* Set EPWM ACMP_SEL bit according to EPWM_Chl. */
  tmpReg |= (uint32_t)(EPWM_Chl << EPWM_STOP_CR_ACMP_SEL_Pos);

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
/**
 *******************************************************************************
 * @brief   Sets the EPWM ememrgency stop ACMP mode.
 * @param   [in]  EPWM_ACMPMode: Specifies the ACMP mode.
 *                This parameter can be a value of @ref EPWM_ESACMPModeEnum.
 *                  @arg EPWM_ES_ACMP_MODE_LATCH: Latch mode
 *                  @arg EPWM_ES_ACMP_MODE_WAVE: Wave mode.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESACMPMode(EPWM_ESACMPModeEnum EPWM_ACMPMode)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM ACMP_SEL[1:0] bits. */
  tmpReg &= ~EPWM_STOP_CR_ACMP_MODE_Msk;

  /* Set EPWM ACMP_SEL[1:0] bit according to EPWM_Chl. */
  tmpReg |= (uint32_t)(EPWM_ACMPMode << EPWM_STOP_CR_ACMP_MODE_Pos);

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */

/**
 *******************************************************************************
 * @brief   Enable or disable EPWM ACMP trigger emergency stop functions.
 * @param   [in]  NewState: New state of the ACMP state bit.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESACMPCmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    EPWM->STOP_CR |= EPWM_STOP_CR_ACMP_STOP_EN_Msk;
  }
  else
  {
    EPWM->STOP_CR &= ~EPWM_STOP_CR_ACMP_STOP_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Enable or disable EPWM debug switch to stop level functions.
 * @param   [in]  NewState: New state of the debug state bit.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESDebugCmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    EPWM->STOP_CR |= EPWM_STOP_CR_DBG_STOP_EN_Msk;
  }
  else
  {
    EPWM->STOP_CR &= ~EPWM_STOP_CR_DBG_STOP_EN_Msk;
  }
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx N channel ememrgency stop output level.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Level: Specifies the channelx N channel ememrgency stop output level.
 *                This parameter can be a value of @ref EPWM_ESOutLevelEnum.
 *                  @arg EPWM_ES_CH_OUT_LEVEL_LOW: Channelx N channel ememrgency stop
 *                       output low level.
 *                  @arg EPWM_ES_CH_OUT_LEVEL_High: Channelx N channel ememrgency stop
 *                       output high level.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESCHNLevel(EPWM_ChannelEnum EPWM_Channel, EPWM_ESOutLevelEnum EPWM_Level)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM CH_N_STOP_O bit. */
  tmpReg &= ~(EPWM_STOP_CR_CH0_N_STOP_O_Msk << 0x02u * EPWM_Channel);

  /* Set EPWM CH_N_STOP_O bit according to EPWM_Level. */
  tmpReg |= (uint32_t)(EPWM_Level << (EPWM_STOP_CR_CH0_N_STOP_O_Pos + 0x02u * EPWM_Channel));

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Sets the EPWM channelx P channel ememrgency stop output level.
 * @param   [in]  EPWM_Channel: Specifies the EPWM channel.
 *                This parameter can be a value of @ref EPWM_ChannelEnum.
 *                  @arg EPWM_CH0: EPWM channel 0.
 *                  @arg EPWM_CH1: EPWM channel 1.
 *                  @arg EPWM_CH2: EPWM channel 2.
 *                  @arg EPWM_CH3: EPWM channel 3.
 * @param   [in]  EPWM_Level: Specifies the channelx P channel ememrgency stop output level.
 *                This parameter can be a value of @ref EPWM_ESOutLevelEnum.
 *                  @arg EPWM_ES_CH_OUT_LEVEL_LOW: Channelx P channel ememrgency stop
 *                       output low level.
 *                  @arg EPWM_ES_CH_OUT_LEVEL_High: Channelx P channel ememrgency
 *                       stop output high level.
 * @retval  None.
 ******************************************************************************/
void EPWM_SetESCHPLevel(EPWM_ChannelEnum EPWM_Channel, EPWM_ESOutLevelEnum EPWM_Level)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM emergency stop control register. */
  tmpReg = EPWM->STOP_CR;

  /* Clear EPWM CH_P_STOP_O bit. */
  tmpReg &= ~(EPWM_STOP_CR_CH0_P_STOP_O_Msk << 0x02u * EPWM_Channel);

  /* Set EPWM CH_P_STOP_O bit according to EPWM_Level. */
  tmpReg |= (uint32_t)(EPWM_Level << (EPWM_STOP_CR_CH0_P_STOP_O_Pos + 0x02u * EPWM_Channel));

  /* Store the new value. */
  EPWM->STOP_CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Get emergency stop type status.
 * @param   [in]  EPWM_ESStop: Specifies the emergency stop type.
 *                This parameter can be a value of @ref EPWM_ESStopStatusEnum.
 *                  @arg EPWM_ES_STOP_SR_SOFT: Get soft stop status.
 *                  @arg EPWM_ES_STOP_SR_EXT: Get external stop status.
 *                  @arg EPWM_ES_STOP_SR_ACMP: Get ACMP stop status.
 * @retval  FlagState: The new state of emergency stop type (SET or RESET).
 ******************************************************************************/
FlagState EPWM_GetESStopStatus(EPWM_ESStopStatusEnum EPWM_ESStop)
{
  FlagState state = RESET;

  if(RESET != (EPWM->STOP_SR & ((uint32_t)EPWM_ESStop)))
  {
    /* Stop status bit has set. */
    state = SET;
  }
  else
  {
    /* Stop status bit has reset. */
    state = RESET;
  }

  /* Return the status of the stop status. */
  return state;
}

/**
 *******************************************************************************
 * @brief   Software setting EPWM brake.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESSoftwareBrake(void)
{
  EPWM->STOP_SR |= (uint32_t)EPWM_STOP_SR_STOP_Msk;
}

/**
 *******************************************************************************
 * @brief   Software setting EPWM continue.
 * @retval  None.
 ******************************************************************************/
void EPWM_ESSoftwareContinue(void)
{
  EPWM->STOP_SR &= (uint32_t)~EPWM_STOP_SR_STOP_Msk;
}

#if defined (DPM32M08x) || defined (DPM32M05x)
/**
 *******************************************************************************
 * @brief   Enable or disable EPWM counter to zero DMA request.
 * @param   [in]  NewState: New state of the zero DMA request.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_DMACmd(FunctionalState NewState)
{
  if(DISABLE != NewState)
  {
    EPWM->CR |= EPWM_CR_PERIOD_DE_Msk;
  }
  else
  {
    EPWM->CR &= ~EPWM_CR_PERIOD_DE_Msk;
  }
}

#endif  /* DPM32M08x || DPM32M05x */

/**
 *******************************************************************************
 * @brief   Enable or disable EPWM interrupt type.
 * @param   [in]  EPWM_IntType: Specifies the interrupt type.
 *                This parameter can be any combination of @ref EPWM_IntTypeEnum.
 *                  @arg EPWM_INT_TYPE_ARR: Counter equal to load value interrupt.
 *                  @arg EPWM_INT_TYPE_PERIOD: Counter equal to zero interrupt.
 *                  @arg EPWM_INT_TYPE_ADC_CMP1: Counter equal to ADC_CMP1 value interrupt.
 *                  @arg EPWM_INT_TYPE_ADC_CMP2: Counter equal to ADC_CMP2 value interrupt.
 *                  @arg EPWM_INT_TYPE_STOP: Stop interrupt.
 * @param   [in]  NewState: New state of the interrupt.
 *                This parameter can be: ENABLE or DISABLE.
 * @retval  None.
 ******************************************************************************/
void EPWM_IntCmd(uint16_t EPWM_IntType, FunctionalState NewState)
{
  uint32_t tmpReg = 0UL;

  /* Read the value of the EPWM control register. */
  tmpReg = EPWM->CR;

  if(DISABLE != NewState)
  {
    /* Set EPWM interrupt bits according to EPWM_IntType. */
    tmpReg |= (uint32_t)EPWM_IntType;
  }
  else
  {
    /* Clear EPWM interrupt bits. */
    tmpReg &= ~(uint32_t)EPWM_IntType;
  }

  /* Store the new value. */
  EPWM->CR = tmpReg;
}

/**
 *******************************************************************************
 * @brief   Get the specifies interrupt type enable or disable.
 * @param   [in]  EPWM_IntType: Specifies the interrupt type.
 *                This parameter can be a value of @ref EPWM_IntTypeEnum.
 *                  @arg EPWM_INT_FLAG_LOAD_VAL: Counter equal to load value interrupt.
 *                  @arg EPWM_INT_TYPE_PERIOD: Counter equal to zero interrupt.
 *                  @arg EPWM_INT_TYPE_ADC_CMP1: Counter equal to ADC_CMP1 value interrupt.
 *                  @arg EPWM_INT_TYPE_ADC_CMP2: Counter equal to ADC_CMP2 value interrupt.
 *                  @arg EPWM_INT_TYPE_STOP: Stop interrupt.
 * @retval  FunctionalState: The specifies interrupt type status.
 *                This parameter can be: ENABLE or DISABLE.
 ******************************************************************************/
FunctionalState EPWM_GetIntCmdStatus(EPWM_IntTypeEnum EPWM_IntType)
{
  FunctionalState state = DISABLE;

  if(RESET != (EPWM->CR & ((uint32_t)EPWM_IntType)))
  {
    /* Interrupt is enable. */
    state = ENABLE;
  }
  else
  {
    /* Interrupt is disable. */
    state = DISABLE;
  }

  return state;
}

/**
 *******************************************************************************
 * @brief   Get the specified EPWM flag is set or not.
 * @param   [in]  EPWM_IntFlag: Specifies the EPWM interrupt flag.
 *                This parameter can be a value of @ref EPWM_IntFlagEnum.
 *                  @arg EPWM_INT_FLAG_ARR: Counter load value flag.
 *                  @arg EPWM_INT_FLAG_PERIOD: Counter zero flag.
 *                  @arg EPWM_INT_FLAG_ADC_CMP1: Counter ADC_CMP1 value flag.
 *                  @arg EPWM_INT_FLAG_ADC_CMP2: Counter ADC_CMP2 value flag.
 *                  @arg EPWM_INT_FLAG_STOP: Stop flag.
 * @retval  FlagState: The new state of EPWM_IntFlag (SET or RESET).
 ******************************************************************************/
FlagState EPWM_GetIntFlagStatus(EPWM_IntFlagEnum EPWM_IntFlag)
{
  FlagState state = RESET;

  /* Get the status of the Interrupt */
  if(RESET != (EPWM->SR & ((uint32_t)EPWM_IntFlag)))
  {
    state = SET;
  }
  else
  {
    state = RESET;
  }

  /* Return the status of the interrupt flag. */
  return state;
}

/**
 *******************************************************************************
 * @brief   Clears the EPWM interrupt flags.
 * @param   [in]  EPWM_IntFlag: Specifies the EPWM interrupt flag.
 *                This parameter can be a value of @ref EPWM_IntFlagEnum.
 *                  @arg EPWM_INT_FLAG_ARR: Counter Load alue flag.
 *                  @arg EPWM_INT_FLAG_PERIOD: Counter zero flag.
 *                  @arg EPWM_INT_FLAG_ADC_CMP1: Counter ADC_CMP1 value flag.
 *                  @arg EPWM_INT_FLAG_ADC_CMP2: Counter ADC_CMP2 value flag.
 *                  @arg EPWM_INT_FLAG_STOP: Stop flag.
 * @retval  None.
 ******************************************************************************/
void EPWM_ClearIntFlag(EPWM_IntFlagEnum EPWM_IntFlag)
{
  /* Clear interrupt flags.*/
  EPWM->SR = ((uint32_t)EPWM_IntFlag);
}
