/**
 *******************************************************************************
 * @file    dpm32m0xx_pvd.h
 *
 * @brief   Header file for PVD firmware driver.
 *
 * @author  DPM
 *
 * @version V1.0.0
 *
 * @date    2023-11-01
 *
 *******************************************************************************/

#ifndef __DPM32M0XX_PVD_H__
#define __DPM32M0XX_PVD_H__

#ifdef __cplusplus
extern "C" {
#endif

#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wpadded"
#endif

#include "dpm32m0xx.h"

/**
 ******************************************************************************
 * @brief PVD trigger type enumeration.
 *****************************************************************************/
typedef enum
{
  PVD_TRIGGER_TYPE_FALLING        = 0x00UL,                   /*!< Comparison result falling edge trigger.
                                                                   Reference voltage is lower than VDD. */
  PVD_TRIGGER_TYPE_RISING         = 0x02UL,                   /*!< Comparison result rising edge trigger.
                                                                   Reference voltage is higher than VDD */
  PVD_TRIGGER_TYPE_LOW_LEVEL      = 0x04UL,                   /*!< The comparison result is low level trigger.
                                                                   Reference voltage is lower than VDD */
  PVD_TRIGGER_TYPE_HIGH_LEVEL     = PVD_CR_TRIG_TYPE_Msk      /*!< The comparison result is a high level trigger.
                                                                   Reference voltage is higher than VDD */
} PVD_TriggerTypeEnum;

/**
 ******************************************************************************
 * @brief PVD trigger result enumeration.
 *****************************************************************************/
typedef enum
{
  PVD_TRIGGER_RESULT_INT        = 0x00UL,                     /*!< Trigger interrupt. */
  PVD_TRIGGER_RESULT_RESET      = PVD_CR_TRIG_RESULT_Msk      /*!< Trigger system reset. */
} PVD_TriggerResultEnum;

/**
 ******************************************************************************
 * @brief PVD detection reference voltage enumeration.
 *****************************************************************************/
typedef enum
{
  PVD_VREF_SEL_22        = 0x20UL,        /*!< The detection reference voltage is 2.2V. */
  PVD_VREF_SEL_24        = 0x30UL,        /*!< The detection reference voltage is 2.4V. */
  PVD_VREF_SEL_26        = 0x40UL,        /*!< The detection reference voltage is 2.6V. */
  PVD_VREF_SEL_28        = 0x50UL,        /*!< The detection reference voltage is 2.8V. */
  PVD_VREF_SEL_30        = 0x60UL,        /*!< The detection reference voltage is 3.0V. */
  PVD_VREF_SEL_32        = 0x70UL,        /*!< The detection reference voltage is 3.2V. */
  PVD_VREF_SEL_34        = 0x80UL,        /*!< The detection reference voltage is 3.4V. */
  PVD_VREF_SEL_36        = 0x90UL,        /*!< The detection reference voltage is 3.6V. */
  PVD_VREF_SEL_38        = 0xA0UL,        /*!< The detection reference voltage is 3.8V. */
  PVD_VREF_SEL_40        = 0xB0UL,         /*!< The detection reference voltage is 4.0V. */
#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
  PVD_VREF_SEL_42        = 0xC0UL,         /*!< The detection reference voltage is 4.2V. */
  PVD_VREF_SEL_44        = 0xD0UL,         /*!< The detection reference voltage is 4.4V. */
  PVD_VREF_SEL_46        = 0xE0UL,         /*!< The detection reference voltage is 4.6V. */
  PVD_VREF_SEL_48        = 0xF0UL,         /*!< The detection reference voltage is 4.8V. */
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */
} PVD_VrefSelEnum;

/**
 ******************************************************************************
 * @brief PVD filter length enumeration.
 *****************************************************************************/
typedef enum
{
  PVD_FILTER_LEN1        = 0x0000UL,                /*!< Filter length is 1. */
  PVD_FILTER_LEN8        = 0x0400UL,                /*!< Filter length is 8. */
  PVD_FILTER_LEN16       = 0x0800UL,                /*!< Filter length is 16. */
  PVD_FILTER_LEN32       = PVD_CR_FLT_LEN_Msk       /*!< Filter length is 32. */
} PVD_FilterLenEnum;

/**
 ******************************************************************************
 * @brief PVD filter sample enumeration.
 *****************************************************************************/
typedef enum
{
  PVD_FILTER_SAMPLE_PCLK1        = 0x0000UL,                  /*!< Filter smaple is PCLK divider 1. */
  PVD_FILTER_SAMPLE_PCLK4        = 0x0100UL,                  /*!< Filter smaple is PCLK divider 4. */
  PVD_FILTER_SAMPLE_PCLK16       = 0x0200UL,                  /*!< Filter smaple is PCLK divider 16. */
  PVD_FILTER_SAMPLE_PCLK32       = PVD_CR_FLT_SAMPLE_Msk      /*!< Filter smaple is PCLK divider 32. */
} PVD_FilterSampleEnum;

/**
 ******************************************************************************
 * @brief PVD filter initialization structure.
 *****************************************************************************/
typedef struct
{
  PVD_FilterLenEnum             FiltLen;          /*!< Filter smaple length.
                                                       This parameter can be a value of @ref PVD_FilterLenEnum. */
  PVD_FilterSampleEnum          FiltSample;       /*!< Filter sample divider.
                                                       This parameter can be a value of @ref PVD_FilterSampleEnum. */
  FunctionalState               FiltState;        /*!< Filter state.
                                                       This parameter can be a value of @ref FunctionalState. */
} PVD_FilterInitTypeStruct;

/**
 ******************************************************************************
 * @brief PVD initialization structure.
 *****************************************************************************/
typedef struct
{
  PVD_TriggerTypeEnum           PVD_TriggerType;                /*!< PVD trigger type.
                                                                     This parameter can be a value of @ref PVD_TriggerTypeEnum. */
  PVD_TriggerResultEnum         PVD_TriggerResult;              /*!< PVD trigger result.
                                                                     This parameter can be a value of @ref PVD_TriggerResultEnum. */
  PVD_VrefSelEnum               PVD_VrefSel;                    /*!< PVD detection reference voltage.
                                                                     This parameter can be a value of @ref PVD_VrefSelEnum. */
  PVD_FilterInitTypeStruct      PVD_Filter;                     /*!< PVD filter initialization structure. */
} PVD_InitTypeStruct;


/* PVD Param Check. */
#define IS_PVD_TRIGGER_TYPE(x)      (((x) == PVD_TRIGGER_TYPE_FALLING)   || \
                                     ((x) == PVD_TRIGGER_TYPE_RISING)    || \
                                     ((x) == PVD_TRIGGER_TYPE_LOW_LEVEL) || \
                                     ((x) == PVD_TRIGGER_TYPE_HIGH_LEVEL))

#define IS_PVD_TRIGGER_RESULT(x)    (((x) == PVD_TRIGGER_RESULT_INT) || \
                                     ((x) == PVD_TRIGGER_RESULT_RESET))

#if defined (DPM32M036) || defined (DPM32M030) || defined (DPM32M015)   
#define IS_PVD_VREF_SEL(x)          (((x) == PVD_VREF_SEL_22) || \
                                     ((x) == PVD_VREF_SEL_24) || \
                                     ((x) == PVD_VREF_SEL_26) || \
                                     ((x) == PVD_VREF_SEL_28) || \
                                     ((x) == PVD_VREF_SEL_30) || \
                                     ((x) == PVD_VREF_SEL_32) || \
                                     ((x) == PVD_VREF_SEL_34) || \
                                     ((x) == PVD_VREF_SEL_36) || \
                                     ((x) == PVD_VREF_SEL_38) || \
                                     ((x) == PVD_VREF_SEL_40) || \
                                     ((x) == PVD_VREF_SEL_42) || \
                                     ((x) == PVD_VREF_SEL_44) || \
                                     ((x) == PVD_VREF_SEL_46) || \
                                     ((x) == PVD_VREF_SEL_48))
#else /* DPM32M08x || DPM32M05x || DPM32M03x */
#define IS_PVD_VREF_SEL(x)          (((x) == PVD_VREF_SEL_22) || \
                                     ((x) == PVD_VREF_SEL_24) || \
                                     ((x) == PVD_VREF_SEL_26) || \
                                     ((x) == PVD_VREF_SEL_28) || \
                                     ((x) == PVD_VREF_SEL_30) || \
                                     ((x) == PVD_VREF_SEL_32) || \
                                     ((x) == PVD_VREF_SEL_34) || \
                                     ((x) == PVD_VREF_SEL_36) || \
                                     ((x) == PVD_VREF_SEL_38) || \
                                     ((x) == PVD_VREF_SEL_40))
#endif /* DPM32M036 || DPM32M030 || DPM32M015 */

#define IS_PVD_FILTER_LEN(x)        (((x) == PVD_FILTER_LEN1)  || \
                                     ((x) == PVD_FILTER_LEN8)  || \
                                     ((x) == PVD_FILTER_LEN16) || \
                                     ((x) == PVD_FILTER_LEN32))

#define IS_PVD_FILTER_SAMPLE(x)     (((x) == PVD_FILTER_SAMPLE_PCLK1)  || \
                                     ((x) == PVD_FILTER_SAMPLE_PCLK4)  || \
                                     ((x) == PVD_FILTER_SAMPLE_PCLK16) || \
                                     ((x) == PVD_FILTER_SAMPLE_PCLK32))


/* Deinitializes and initialization and cmd functions. */
void                    PVD_DeInit(void);
void                    PVD_Init(PVD_InitTypeStruct* PVD_InitType);
void                    PVD_StructInit(PVD_InitTypeStruct* PVD_InitType);
void                    PVD_Cmd(FunctionalState NewState);

/* PVD configuration functions. */
void                    PVD_SetTriggerType(PVD_TriggerTypeEnum PVD_TriggerType);
void                    PVD_SetTriggerResult(PVD_TriggerResultEnum PVD_TriggerResult);
void                    PVD_SetVref(PVD_VrefSelEnum PVD_Vref);
void                    PVD_FilterInit(PVD_FilterInitTypeStruct* PVD_FiltInitType);
void                    PVD_FilterCmd(FunctionalState NewState);

/* PVD interrupt related functions. */
void                    PVD_IntCmd(FunctionalState NewState);
FunctionalState         PVD_GetIntCmdStatus(void);
FlagState               PVD_GetIntFlagStatus(void);
void                    PVD_ClearIntFlag(void);

/* PVD management functions. */
FlagState               PVD_GetReadyFlagStatus(void);
FlagState               PVD_GetResFlagStatus(void);


#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
#pragma clang diagnostic pop
#endif

#ifdef __cplusplus
}

#endif

#endif /* __DPM32M0XX_PVD_H__ */
