/**
  ******************************************************************************
 * @file    hal_adc.h
 * @brief   Header file of ADC Module library.
 *
 * @version V1.0
 * @date    15 Dec 2017
 * @author  AE Team
 * @note
 *
 * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
 *
 ******************************************************************************
 */

#ifndef __HAL_ADC_H
#define __HAL_ADC_H
#ifdef __cplusplus
 extern "C" {
#endif

#include "utils.h"
#include "hal_dma.h"
#include "hal_pis.h"

/** @addtogroup ES32FXXX_HAL
  * @{
  */

/** @addtogroup ADC
  * @{
  */

/** @defgroup ADC_Pubulic_Types ADC Pubulic Types
  * @{
  */

/**
  * @brief ADC  State structures definition
  */
typedef enum {
	ADC_STATE_RESET         = 0x0,    /**< ADC not yet initialized or disabled */
	ADC_STATE_READY         = 0x1,    /**< ADC peripheral ready for use */
	ADC_STATE_BUSY_INTERNAL = 0x2,    /**< ADC is busy to internal process */
	ADC_STATE_TIMEOUT       = 0x4,    /**< TimeOut occurrence */
	ADC_STATE_ERROR         = 0x10,   /**< Internal error occurrence */
	ADC_STATE_REG_BUSY      = 0x100,  /**< Conversion on group regular is ongoing or can occur */
	ADC_STATE_REG_EOC       = 0x200,  /**< Conversion data available on group regular */
	ADC_STATE_INJ_BUSY      = 0x1000, /**< Conversion on group injected is ongoing or can occur */
	ADC_STATE_INJ_EOC       = 0x2000, /**< Conversion data available on group injected */
	ADC_STATE_AWD           = 0x10000 /**< Out-of-window occurrence of analog watchdog */
} adc_state_t;

/**
  *@brief ADC Error Code
  */
typedef enum {
	ADC_ERROR_NONE     = 0x0, /**< No error */
	ADC_ERROR_INTERNAL = 0x1, /**< ADC IP internal error*/
	ADC_ERROR_OVR      = 0x2, /**< Overrun error */
	ADC_ERROR_DMA      = 0x4  /**< DMA transfer error */
} adc_error_t;

/**
  *@brief ADC data  alignment
  */
typedef enum {
	ADC_DATAALIGN_RIGHT = 0x0, /**< ADC data alignment right */
	ADC_DATAALIGN_LEFT  = 0x1  /**< ADC data alignment left */
} adc_data_align_t;

/**
  *@brief ADC scan mode
  */
typedef enum {
	ADC_SCAN_DISABLE = 0x0, /**< ADC scan disable */
	ADC_SCAN_ENABLE  = 0x1  /**< ADC scan enable */
} adc_scan_mode_t;

/**
  *@brief ADC config  regular channal trigger the EOC IT mode
  */
typedef enum {
	ADC_REOCS_MODE_ALL = 0x0, /**< ADC set REOC after regular convert sequence finish */
	ADC_REOCS_MODE_ONE = 0x1  /**< ADC set REOC after one regular convert finish */
} adc_reocs_mode_t;

/**
  *@brief  ADC channels
  */
typedef enum {
	ADC_CHANNEL_0  = 0x0,  /**< ADC channel 0 */
	ADC_CHANNEL_1  = 0x1,  /**< ADC channel 1 */
	ADC_CHANNEL_2  = 0x2,  /**< ADC channel 2 */
	ADC_CHANNEL_3  = 0x3,  /**< ADC channel 3 */
	ADC_CHANNEL_4  = 0x4,  /**< ADC channel 4 */
	ADC_CHANNEL_5  = 0x5,  /**< ADC channel 5 */
	ADC_CHANNEL_6  = 0x6,  /**< ADC channel 6 */
	ADC_CHANNEL_7  = 0x7,  /**< ADC channel 7 */
	ADC_CHANNEL_8  = 0x8,  /**< ADC channel 8 */
	ADC_CHANNEL_9  = 0x9,  /**< ADC channel 9 */
	ADC_CHANNEL_10 = 0xA,  /**< ADC channel 10 */
	ADC_CHANNEL_11 = 0xB,  /**< ADC channel 11 */
	ADC_CHANNEL_12 = 0xC,  /**< ADC channel 12 */
	ADC_CHANNEL_13 = 0xD,  /**< ADC channel 13 */
	ADC_CHANNEL_14 = 0xE,  /**< ADC channel 14 */
	ADC_CHANNEL_15 = 0xF,  /**< ADC channel 15 */
	ADC_CHANNEL_16 = 0x10, /**< ADC channel 16 */
	ADC_CHANNEL_17 = 0x11, /**< ADC channel 17 */
	ADC_CHANNEL_18 = 0x12, /**< ADC channel 18 */
	ADC_CHANNEL_19 = 0x13  /**< ADC channel 19 */
} adc_channels_t;

/**
  *@brief  ADC sampling times
  */
typedef enum {
	ADC_SAMPLETIME_1  = 0x0, /**< ADC sampling times 1 clk */
	ADC_SAMPLETIME_2  = 0x1, /**< ADC sampling times 2 clk */
	ADC_SAMPLETIME_4  = 0x2, /**< ADC sampling times 4 clk */
	ADC_SAMPLETIME_15 = 0x3  /**< ADC sampling times 15 clk */
} adc_samp_times_t;

/**
  *@brief   ADC rank into regular group
  */
typedef enum {
	ADC_REGULAR_RANK_1  = 0x1, /**< ADC regualar channel rank 1 */
	ADC_REGULAR_RANK_2  = 0x2, /**< ADC regualar channel rank 2 */
	ADC_REGULAR_RANK_3  = 0x3, /**< ADC regualar channel rank 3 */
	ADC_REGULAR_RANK_4  = 0x4, /**< ADC regualar channel rank 4 */
	ADC_REGULAR_RANK_5  = 0x5, /**< ADC regualar channel rank 5 */
	ADC_REGULAR_RANK_6  = 0x6, /**< ADC regualar channel rank 6 */
	ADC_REGULAR_RANK_7  = 0x7, /**< ADC regualar channel rank 7 */
	ADC_REGULAR_RANK_8  = 0x8, /**< ADC regualar channel rank 8 */
	ADC_REGULAR_RANK_9  = 0x9, /**< ADC regualar channel rank 9 */
	ADC_REGULAR_RANK_10 = 0xA, /**< ADC regualar channel rank 10 */
	ADC_REGULAR_RANK_11 = 0xB, /**< ADC regualar channel rank 11 */
	ADC_REGULAR_RANK_12 = 0xC, /**< ADC regualar channel rank 12 */
	ADC_REGULAR_RANK_13 = 0xD, /**< ADC regualar channel rank 13 */
	ADC_REGULAR_RANK_14 = 0xE, /**< ADC regualar channel rank 14 */
	ADC_REGULAR_RANK_15 = 0xF, /**< ADC regualar channel rank 15 */
	ADC_REGULAR_RANK_16 = 0x10 /**< ADC regualar channel rank 16 */
} adc_regular_rank_t;

/**
  * @brief ADC rank into injected group
  */
typedef enum {
	ADC_INJECTED_RANK_1 = 0x1, /**< ADC injected channel rank 1 */
	ADC_INJECTED_RANK_2 = 0x2, /**< ADC injected channel rank 2 */
	ADC_INJECTED_RANK_3 = 0x3, /**< ADC injected channel rank 3 */
	ADC_INJECTED_RANK_4 = 0x4  /**< ADC injected channel rank 4 */
} adc_injected_rank_t;

/**
  * @brief ADC analog watchdog mode
  */
typedef enum {
	ADC_ANAWTD_NONE          = 0x0,      /**< No watch dog */
	ADC_ANAWTD_SING_REG      = 0x800200, /**< One Reg channel watch dog */
	ADC_ANAWTD_SING_INJEC    = 0x400200, /**< One Inj channel Injec watch dog */
	ADC_ANAWTD_SING_REGINJEC = 0xC00200, /**< One Reg and Inj channel watch dog */
	ADC_ANAWTD_ALL_REG       = 0x800000, /**< All Reg channel watch dog */
	ADC_ANAWTD_ALL_INJEC     = 0x400000, /**< All Inj channel watch dog */
	ADC_ANAWTD_ALL_REGINJEC  = 0xC00000  /**< All Reg and Inj channel watch dog */
} adc_ana_wtd_mode_t;

/**
  * @brief ADC Event type
  */
typedef enum {
	ADC_AWD_EVENT = (1U << 0), /**< ADC analog watch dog event */
} adc_event_type_t;

/**
  * @brief ADC interrupts definition
  */
typedef enum {
	ADC_IT_REOC = (1U << 5),  /**< ADC it reoc */
	ADC_IT_AWD  = (1U << 6),  /**< ADC it awd */
	ADC_IT_JEOC = (1U << 7),  /**< ADC it jeoc */
	ADC_IT_OVR  = (1U << 26)  /**< ADC it ovr */
} adc_interrupts_t;

/**
  * @brief ADC flags definition
  */
typedef enum {
	ADC_FLAG_AWD   = (1U << 0), /**<ADC flag awd */
	ADC_FLAG_REOC  = (1U << 1), /**<ADC flag reoc*/
	ADC_FLAG_JEOC  = (1U << 2), /**<ADC flag jeoc */
	ADC_FLAG_OVR   = (1U << 3), /**<ADC flag ovr */
	ADC_FLAG_JSTRT = (1U << 8), /**<ADC flag jstrt */
	ADC_FLAG_RSTRT = (1U << 9)  /**<ADC flag rstrt */
} adc_flags_t;

/**
  * @brief ADC CLD DIV definition
  */
typedef enum {
	ADC_CKDIV_2   = 0x0, /**< ADC CLK DIV 2 */
	ADC_CKDIV_4   = 0x1, /**< ADC CLK DIV 4 */
	ADC_CKDIV_8   = 0x2, /**< ADC CLK DIV 8 */
	ADC_CKDIV_16  = 0x3, /**< ADC CLK DIV 16 */
	ADC_CKDIV_32  = 0x4, /**< ADC CLK DIV 32 */
	ADC_CKDIV_64  = 0x5, /**< ADC CLK DIV 64 */
	ADC_CKDIV_128 = 0x6, /**< ADC CLK DIV 128 */
	ADC_CKDIV_256 = 0x7  /**< ADC CLK DIV 256 */
} adc_clk_div_t;

/**
  * @brief ADC negative reference voltage definition
  */
typedef enum {
	ADC_NEG_REF_VOLT_VSS   = 0x0, /**< ADC negative regerence voltage vss */
	ADC_NEG_REF_VOLT_VREFN = 0x1  /**< ADC negative regerence voltage vrefn */
} adc_neg_ref_volt_t;

/**
  * @brief ADC positive reference voltage definition
  */
typedef enum {
	ADC_POS_REF_VOLT_VDD        = 0x0, /**< ADC posotove reference is VDD */
	ADC_POS_REF_VOLT_2V         = 0x1, /**< ADC posotove reference is internal 2V */
	ADC_POS_REF_VOLT_VREEFP     = 0x2, /**< ADC posotove reference is VREEFP */
	ADC_POS_REF_VOLT_VREEFP_BUF = 0x3  /**< ADC posotove reference is VREEFP BUFFER */
} adc_pos_ref_volt_t;

/**
  * @brief ADC numbers of regular conversion channals
  */
typedef enum {
	ADC_NBR_OF_REGULAR_CONV_1  = 0x0, /**< ADC number of regualr conversion 1 */
	ADC_NBR_OF_REGULAR_CONV_2  = 0x1, /**< ADC number of regualr conversion 2 */
	ADC_NBR_OF_REGULAR_CONV_3  = 0x2, /**< ADC number of regualr conversion 3 */
	ADC_NBR_OF_REGULAR_CONV_4  = 0x3, /**< ADC number of regualr conversion 4 */
	ADC_NBR_OF_REGULAR_CONV_5  = 0x4, /**< ADC number of regualr conversion 5 */
	ADC_NBR_OF_REGULAR_CONV_6  = 0x5, /**< ADC number of regualr conversion 6 */
	ADC_NBR_OF_REGULAR_CONV_7  = 0x6, /**< ADC number of regualr conversion 7 */
	ADC_NBR_OF_REGULAR_CONV_8  = 0x7, /**< ADC number of regualr conversion 8 */
	ADC_NBR_OF_REGULAR_CONV_9  = 0x8, /**< ADC number of regualr conversion 9 */
	ADC_NBR_OF_REGULAR_CONV_10 = 0x9, /**< ADC number of regualr conversion 10 */
	ADC_NBR_OF_REGULAR_CONV_11 = 0xA, /**< ADC number of regualr conversion 11 */
	ADC_NBR_OF_REGULAR_CONV_12 = 0xB, /**< ADC number of regualr conversion 12 */
	ADC_NBR_OF_REGULAR_CONV_13 = 0xC, /**< ADC number of regualr conversion 13 */
	ADC_NBR_OF_REGULAR_CONV_14 = 0xD, /**< ADC number of regualr conversion 14 */
	ADC_NBR_OF_REGULAR_CONV_15 = 0xE, /**< ADC number of regualr conversion 15 */
	ADC_NBR_OF_REGULAR_CONV_16 = 0xF  /**< ADC number of regualr conversion 16 */
} adc_nbr_of_regular_conv_t;

/**
  * @brief ADC numbers of injected conversion channals
  */
typedef enum {
	ADC_NBR_OF_INJECTED_CONV_1 = 0x0, /**< ADC number of injected conversion 1 */
	ADC_NBR_OF_INJECTED_CONV_2 = 0x1, /**< ADC number of injected conversion 2 */
	ADC_NBR_OF_INJECTED_CONV_3 = 0x2, /**< ADC number of injected conversion 3 */
	ADC_NBR_OF_INJECTED_CONV_4 = 0x3  /**< ADC number of injected conversion 4 */
} adc_nbr_of_injected_conv_t;

/**
  * @brief ADC numbers of channals in discontinuous conversion mode
  */
typedef enum {
	ADC_NBR_OF_DISC_CONV_1 = 0x0, /**< ADC number of discontinuous conversion 1 */
	ADC_NBR_OF_DISC_CONV_2 = 0x1, /**< ADC number of discontinuous conversion 2 */
	ADC_NBR_OF_DISC_CONV_3 = 0x2, /**< ADC number of discontinuous conversion 3 */
	ADC_NBR_OF_DISC_CONV_4 = 0x3, /**< ADC number of discontinuous conversion 4 */
	ADC_NBR_OF_DISC_CONV_5 = 0x4, /**< ADC number of discontinuous conversion 5 */
	ADC_NBR_OF_DISC_CONV_6 = 0x5, /**< ADC number of discontinuous conversion 6 */
	ADC_NBR_OF_DISC_CONV_7 = 0x6, /**< ADC number of discontinuous conversion 7 */
	ADC_NBR_OF_DISC_CONV_8 = 0x7  /**< ADC number of discontinuous conversion 8 */
} adc_nbr_of_disc_conv_t;

/**
  * @brief ADC resolution of conversion
  */
typedef enum {
	ADC_RESOLUTION_OF_CONV_6  = 0x3, /**< ADC resolution of conversion 12 */
	ADC_RESOLUTION_OF_CONV_8  = 0x2, /**< ADC resolution of conversion 10 */
	ADC_RESOLUTION_OF_CONV_10 = 0x1, /**< ADC resolution of conversion 8 */
	ADC_RESOLUTION_OF_CONV_12 = 0x0  /**< ADC resolution of conversion 6 */
} adc_res_of_conv_t;

/**
  * @brief ADC trigger conversion mode
  */
typedef enum {
	ADC_TRIG_CONV_SOFT        = 0x0, /**< ADC tirgger conversion soft */
	ADC_TRIG_CONV_PIS         = 0x1, /**< ADC tirgger conversion pis */
	ADC_TRIG_CONV_PIS_OR_SOFT = 0x2  /**< ADC tirgger conversion all */
} adc_trig_conv_mode_t;

/**
  * @brief  Structure definition of ADC and regular group initialization
  */
typedef struct {
	adc_data_align_t data_align;             /**< Specifies ADC data alignment */
	adc_scan_mode_t scan_conv_mode;          /**< Choose scan mode enable or not */
	type_func_t continuous_conv_mode;        /**< Choose continuous mode enable or not */
	adc_nbr_of_regular_conv_t nbr_of_conv;   /**< Number of Reg ranks will be converted */
	type_func_t discontinuous_conv_mode;     /**< Discontinuous mode enable or not */
	adc_nbr_of_disc_conv_t nbr_of_disc_conv; /**< Number of discontinuous conversions channel */
	adc_res_of_conv_t resolution_of_conv;    /**< The precision of conversion */
	adc_clk_div_t  clk_div;			 /**< ADCCLK divider */
	adc_reocs_mode_t reocs_mode;		 /**< Trigger the REOC FALG mode */
	type_func_t gaincal;			 /**< Enable or disable the gainal*/
	type_func_t offcal;			 /**< Enable or disable the offcal*/
	adc_neg_ref_volt_t  neg_ref_voltage;     /**< The negative reference voltage*/
	adc_pos_ref_volt_t  pos_ref_voltage;     /**< The positive reference voltage*/
	type_func_t diff;	                 /**< Enable or disable the diff */
	type_func_t lsen;	                 /**< Enable or disable the lsen */
	type_func_t vrbuf;	                 /**< Enable or disable the vrbuf*/
	type_func_t vcmen;	                 /**< Enable or disable the vvmen*/
	type_func_t vrefen;	                 /**< Enable or disable the vrefen*/
} adc_init_t;

/**
  * @brief  Structure definition of ADC channel for regular group
  */
typedef struct {
	adc_channels_t channel;         /**< The channel to configure into ADC regular group */
	adc_regular_rank_t rank;        /**< The rank in the regular group sequencer */
	adc_samp_times_t sampling_time; /**< Sampling time value to be set */
} adc_channel_conf_t;

/**
  * @brief  ADC Configuration analog watchdog definition
  */
typedef struct {
	adc_ana_wtd_mode_t watchdog_mode; /**< Configures the ADC analog watchdog mode*/
	adc_channels_t channel;           /**< Selects which ADC channel to monitor by analog watchdog */
	type_func_t it_mode;              /**< Whether the analog watchdog is configured in interrupt */
	uint32_t high_threshold;     	  /**< The ADC analog watchdog High threshold value. */
	uint32_t low_threshold;      	  /**< The ADC analog watchdog Low threshold value. */
} adc_analog_wdg_conf_t;

/**
  * @brief  ADC Configuration injected Channel structure definition
  */
typedef struct {
	adc_channels_t injected_channel;                 /**< Selection of ADC channel to configure */
	adc_injected_rank_t injected_rank;               /**< Rank in the injected group sequencer */
	adc_samp_times_t injected_sampling_time;         /**< Sampling time value for selected channel */
	uint32_t injected_offset;                        /**< The offset about converted data */
	adc_nbr_of_injected_conv_t injected_nbr_of_conv; /**< The number of Injected ranks */
	type_func_t injected_discontinuous_conv_mode;    /**< Injected sequence's Discontinuous function */
	type_func_t auto_injected_conv;                  /**< Injected sequence's auto function */
} adc_injection_conf_t;

/**
  * @brief  ADC handle Structure definition
  */
typedef struct adc_handle_s {
	ADC_TypeDef *perh;                            /**< Register base address */
	adc_init_t init;                              /**< ADC required parameters */
#ifdef HAL_DMA
	dma_handle_t hdma;                            /**< Pointer DMA Handler */
	pis_handle_t adc_dma_pis_handle;              /**< Pointer PIS Handler for connect adc and dma */
#endif
	lock_state_t lock;                            /**< ADC locking object */
	adc_state_t state;                            /**< ADC communication state  */
	adc_error_t error_code;                       /**< ADC Error code */
	pis_handle_t regular_pis_handle;              /**< PIS for connect regular channel and trigger */
	pis_handle_t injected_pis_handle;             /**< PIS for connect injected channel and trigger */
	adc_trig_conv_mode_t regular_trig_conv_mode;  /**< ADC regular channel trigger mode */
	adc_trig_conv_mode_t injected_trig_conv_mode; /**< ADC injected channel trigger mode */

	void (*adc_init_cbk)(struct adc_handle_s *arg);	       /**< adc init callback */
	void (*adc_de_init_cbk)(struct adc_handle_s *arg);     /**< adc de_init callback */
	void (*adc_reg_cplt_cbk)( struct adc_handle_s *arg);   /**< Regluar Conversion complete callback */
	void (*adc_inj_cplt_cbk)( struct adc_handle_s *arg);   /**< Injected Conversion complete callback */
	void (*adc_out_of_win_cbk)( struct adc_handle_s *arg); /**< Level out of window callback */
	void (*adc_error_cbk)(struct adc_handle_s *arg);       /**< adc error callback */
	void (*adc_ovr_cbk)(struct adc_handle_s *arg);	       /**< adc ovr callback */
} adc_handle_t;

/**
  * @}
  */

/** @defgroup ADC_Public_Macros ADC Public Macros
  * @{
  */
#define ADC_ENABLE(handle) 			((handle)->perh->CR2.ADEN = 1)
#define ADC_DISABLE(handle) 			((handle)->perh->CR2.ADEN = 0)
#define ADC_ENABLE_IT(handle, interrupt)  	((handle)->perh->CR1.Word |= (interrupt))
#define ADC_DISABLE_IT(handle, interrupt) 	((handle)->perh->CR1.Word &= ~(interrupt))
#define ADC_GET_IT_SOURCE(handle, interrupt)	(((handle)->perh->CR1.Word & (interrupt)) == (interrupt))
#define ADC_GET_FLAG(handle, flag)		(((handle)->perh->SR.Word & (flag)) == (flag))
#define ADC_CLEAR_FLAG(handle,flag)		((handle)->perh->SFCR.Word = (flag))
#define ADC_REG_TRIG_BY_SOFT(handle)		((handle)->perh->CR2.RTRIG = 1)
#define ADC_INJ_TRIG_BY_SOFT(handle)		((handle)->perh->CR2.JTRIG = 1)
#define ADC_RESET_HANDLE_STATE(handle)		((handle)->state = ADC_STATE_RESET)
/**
  * @}
  */

/** @defgroup ADC_Private_Macros ADC Private Macros
  * @{
  */
#define IS_ADC_INJECTED_RANK_TYPE(x)		((x) <= ADC_INJECTED_RANK_4)
#define IS_ADC_REGULAR_RANK_TYPE(x)		((x) <= ADC_REGULAR_RANK_16)
#define IS_ADC_SAMPLING_TIMES_TYPE(x)		(((x) == ADC_SAMPLETIME_1) || \
                                                 ((x) == ADC_SAMPLETIME_2) || \
					         ((x) == ADC_SAMPLETIME_4) || \
					         ((x) == ADC_SAMPLETIME_15))
#define IS_ADC_CHANNELS_TYPE(x)			((x) <= ADC_CHANNEL_19)
#define IS_ADC_SCAN_MODE_TYPE(x)		(((x) == ADC_SCAN_DISABLE) || \
                                                 ((x) ==  ADC_SCAN_ENABLE) )
#define IS_ADC_DATA_ALIGN_TYPE(x)		(((x) == ADC_DATAALIGN_RIGHT) || \
                                                 ((x) == ADC_DATAALIGN_LEFT))
#define IS_ADC_ANALOG_WTD_MODE_TYPE(x)  	(((x) == ADC_ANAWTD_NONE)          || \
						 ((x) == ADC_ANAWTD_SING_REG)      || \
						 ((x) == ADC_ANAWTD_SING_INJEC)    || \
						 ((x) == ADC_ANAWTD_SING_REGINJEC) || \
						 ((x) == ADC_ANAWTD_ALL_REG)       || \
						 ((x) == ADC_ANAWTD_ALL_INJEC)     || \
						 ((x) == ADC_ANAWTD_ALL_REGINJEC))
#define IS_ADC_INTERRUPTS_TYPE(x)		(((x) == ADC_IT_REOC) || \
						 ((x) == ADC_IT_AWD)  || \
						 ((x) == ADC_IT_JEOC) ||  \
						 ((x) == ADC_IT_OVR ))
#define IS_ADC_FLAGS_TYPE(x)			(((x) == ADC_FLAG_AWD)   || \
						 ((x) == ADC_FLAG_REOC)  || \
						 ((x) == ADC_FLAG_JEOC)  || \
						 ((x) == ADC_FLAG_OVR)   || \
						 ((x) == ADC_FLAG_JSTRT) || \
						 ((x) == ADC_FLAG_RSTRT))
#define IS_ADC_CLK_DIV_TYPE(x)			(((x) == ADC_CKDIV_2)   || \
						 ((x) == ADC_CKDIV_4)   || \
						 ((x) == ADC_CKDIV_8)   || \
						 ((x) == ADC_CKDIV_16)  || \
						 ((x) == ADC_CKDIV_32)  || \
						 ((x) == ADC_CKDIV_64)  || \
						 ((x) == ADC_CKDIV_128) || \
						 ((x) == ADC_CKDIV_256))
#define IS_ADC_NEG_REF_VOLTAGE_TYPE(x)		(((x) == ADC_NEG_REF_VOLT_VSS ) || \
                                                 ((x) == ADC_NEG_REF_VOLT_VREFN ))
#define IS_POS_REF_VOLTAGE_TYPE(x)		(((x) == ADC_POS_REF_VOLT_VDD)    || \
						 ((x) == ADC_POS_REF_VOLT_2V)     || \
						 ((x) == ADC_POS_REF_VOLT_VREEFP) || \
						 ((x) == ADC_POS_REF_VOLT_VREEFP_BUF))
#define IS_ADC_NBR_OF_REGULAR_TYPE(x)		((x) <= ADC_NBR_OF_REGULAR_CONV_16)
#define IS_ADC_NBR_OF_INJECTED_TYPE(x)		((x) <= ADC_NBR_OF_INJECTED_CONV_4)
#define IS_ADC_NBR_OF_DISC_CONV_TYPE(x)		((x) <= ADC_NBR_OF_DISC_CONV_8)
#define IS_ADC_RESOLUTION_OF_CONV_TYPE(x)	(((x) == ADC_RESOLUTION_OF_CONV_12) || \
                                                 ((x) == ADC_RESOLUTION_OF_CONV_6)  || \
						 ((x) == ADC_RESOLUTION_OF_CONV_8)  || \
						 ((x) == ADC_RESOLUTION_OF_CONV_10))
#define IS_ADC_TRIG_CONV_MODE_TYPE(x)		(((x) == ADC_TRIG_CONV_SOFT) || \
                                                 ((x) == ADC_TRIG_CONV_PIS)  || \
                                                 ((x) == ADC_TRIG_CONV_PIS_OR_SOFT))
#define IS_ADC_TYPE(x) 				(((x) == ADC0) || \
						 ((x) == ADC1))
#define IS_ADC_REOCS_MODE_TYPE(x)		(((x) == ADC_REOCS_MODE_ALL) || \
						 ((x) == ADC_REOCS_MODE_ONE))
#define IS_ADC_EVENT_TYPE(x)			((x) == ADC_AWD_EVENT)
#define IS_ADC_INJECTED_OFFSET_TYPE(x)		((x) <= 0xfff)
#define IS_HTR_TYPE(x)				((x) <= 0xfff)
#define IS_LTR_TYPE(x)				((x) <= 0xfff)
/**
  * @}
  */

/** @addtogroup ADC_Public_Functions
  * @{
  */

/** @addtogroup ADC_Public_Functions_Group1
  * @{
  */
hal_status_t adc_init(adc_handle_t* hperh);
hal_status_t adc_init_default(adc_handle_t *hperh);
/**
  * @}
  */

/** @addtogroup ADC_Public_Functions_Group2
  * @{
  */
hal_status_t adc_regular_start(adc_handle_t* hperh);
hal_status_t adc_regular_stop(adc_handle_t* hperh);
hal_status_t adc_regular_poll_for_conversion(adc_handle_t* hperh, uint32_t timeout);
hal_status_t adc_poll_for_event(adc_handle_t* hperh, adc_event_type_t event_type,uint32_t timeout);
hal_status_t adc_regular_start_it(adc_handle_t* hperh);
hal_status_t adc_regular_stop_it(adc_handle_t* hperh);
#ifdef HAL_DMA
hal_status_t adc_start_dma(adc_handle_t* hperh, uint16_t *buf, uint16_t size, uint8_t channel);
hal_status_t adc_stop_dma(adc_handle_t* hperh);
#endif
uint32_t adc_regular_get_value(adc_handle_t* hperh);
hal_status_t adc_injected_start(adc_handle_t* hperh);
hal_status_t adc_injected_stop(adc_handle_t* hperh);
hal_status_t adc_injected_poll_for_conversion(adc_handle_t* hperh, uint32_t timeout);
hal_status_t adc_injected_start_it(adc_handle_t* hperh);
hal_status_t adc_injected_stop_it(adc_handle_t* hperh);
uint32_t adc_injected_get_value(adc_handle_t* hperh, adc_injected_rank_t injected_rank);
void adc_irq_handler(adc_handle_t* hperh);
/**
  * @}
  */

/** @addtogroup ADC_Public_Functions_Group3
  * @{
  */
hal_status_t adc_regular_config_channel(adc_handle_t* hperh, adc_channel_conf_t* config);
hal_status_t adc_injected_config_channel(adc_handle_t* hperh, adc_injection_conf_t* config);
hal_status_t adc_analog_wdg_config(adc_handle_t* hperh, adc_analog_wdg_conf_t* analog_wdg_config);
/**
  * @}
  */

/** @addtogroup ADC_Public_Functions_Group4
  * @{
  */
uint32_t adc_get_state(adc_handle_t* hperh);
uint32_t adc_get_error(adc_handle_t *hperh);
/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */
#ifdef __cplusplus
 extern "C" }
#endif

#endif /* __HAL_ADC_H */
