/*!
 * @file    	apm32f10x_adc.h
 *
 * @brief	 	This file contains all the functions prototypes for the ADC firmware library
 *
 * @details	
 *
 * @version		V1.0.0
 *
 * @date    	2019-8-6
 *
 */

#ifndef __APM32F10x_ADC_H
#define __APM32F10x_ADC_H

#ifdef __cplusplus
 extern "C" {
#endif
	 
#include "apm32f10x.h"

/**
 * @brief	ADC Config structure definition
 */
typedef struct
{
	uint32_t Mode;
	uint8_t ScanConvMode;
	uint8_t ContinuosConvMode;
	uint32_t ExternalTrigConv;
	uint32_t DataAlign;
	uint8_t NbrOfChannel;
}ADC_ConfigStruct_T;

/**
 * @brief	Configuration Mode enumeration
 */
typedef enum
{
	ADC_MODE_INDEPENDENT = 0x00000000,
	ADC_MODE_REGINJECSIMULT = 0x00010000,
	ADC_MODE_REGSIMULT_ALTERTRIG = 0x00020000,
	ADC_MODE_INJECSIMULT_FASTTNTERL = 0x00030000,
	ADC_MODE_INJECSIMULT_SLOWINTERL = 0x00040000,
	ADC_MODE_INJECSIMULT = 0x00050000,
	ADC_MODE_REGSIMULT = 0x00060000,
	ADC_MODE_FASTINTERL = 0x00070000,
	ADC_MODE_SLOWINTERL = 0x00080000,
	ADC_MODE_ALTERTRIG = 0x00090000
}ADC_MODE_T;

/**
 * @brief	ADC external trigger sources for regular channels conversion enumeration
 */
typedef enum
{
	ADC_EXTERNALTRIGCONV_T1_CC1 = 0x00000000,
	ADC_EXTERNALTRIGCONV_T1_CC2 = 0x00020000,
	ADC_EXTERNALTRIGCONV_T2_CC2 = 0x00060000,
	ADC_EXTERNALTRIGCONV_T3_TRGO = 0x00080000,
	ADC_EXTERNALTRIGCONV_T4_CC4 = 0x000A0000,
	ADC_EXTERNALTRIGCONV_EXT_IT11_TIM8_TRGO = 0x000C0000,
	ADC_EXTERNALTRIGCONV_T1_CC3 = 0x00040000,
	ADC_EXTERNALTRIGCONV_None = 0x000E0000,
	
	ADC_EXTERNALTRIGCONV_T3_CC1 = 0x00000000,
	ADC_EXTERNALTRIGCONV_T2_CC3 = 0x00030000,
	ADC_EXTERNALTRIGCONV_T8_CC1 = 0x00060000,
	ADC_EXTERNALTRIGCONV_T8_TRGO = 0x00080000,
	ADC_EXTERNALTRIGCONV_T5_CC1 = 0x000A0000,
	ADC_EXTERNALTRIGCONV_T5_CC3 = 0x000C0000
}ADC_EXTERNALTRIGCONV_T;

/**
 * @brief	ADC Data Align
 */
typedef enum
{
	ADC_DATA_ALIGN_RIGHT = 0x00000000,
	ADC_DATA_ALIGN_LEFT = 0x00000800
}ADC_DATA_ALIGN_T;

/**
 * @brief	ADC Channels
 */
typedef enum
{
	ADC_CHANNEL_0 = 0x00,
	ADC_CHANNEL_1 = 0x01,
	ADC_CHANNEL_2 = 0x02,
	ADC_CHANNEL_3 = 0x03,
	ADC_CHANNEL_4 = 0x04,
	ADC_CHANNEL_5 = 0x05,
	ADC_CHANNEL_6 = 0x06,
	ADC_CHANNEL_7 = 0x07,
	ADC_CHANNEL_8 = 0x08,
	ADC_CHANNEL_9 = 0x09,
	ADC_CHANNEL_10 = 0x0A,
	ADC_CHANNEL_11 = 0x0B,
	ADC_CHANNEL_12 = 0x0C,
	ADC_CHANNEL_13 = 0x0D,
	ADC_CHANNEL_14 = 0x0E,
	ADC_CHANNEL_15 = 0x0F,
	ADC_CHANNEL_16 = 0x10,
	ADC_CHANNEL_17 = 0x11,
	ADC_CHANNEL_TEMPSENSOR = 0x10,
	ADC_CHANNEL_VREFINT = 0x11
}ADC_CHANNEL_T;

/**
 * @brief	ADC Sampling Time
 */
typedef enum
{
	ADC_SAMPLE_TIME_1CYCLE5 = 0x00,
	ADC_SAMPLE_TIME_7CYCLE5 = 0x01,
	ADC_SAMPLE_TIME_13CYCLE5 = 0x02,
	ADC_SAMPLE_TIME_28CYCLE5 = 0x03,
	ADC_SAMPLE_TIME_41CYCLE5 = 0x04,
	ADC_SAMPLE_TIME_55CYCLE5 = 0x05,
	ADC_SAMPLE_TIME_71CYCLE5 = 0x06,
	ADC_SAMPLE_TIME_239CYCLE5 = 0x07
}ADC_SAMPLE_TIME_T;

/**
 * @brief	ADC external trigger sources for injected channels conversion 
 */
typedef enum
{
	ADC_EXTERNAL_TRIG_INJEC_CONV_T2_TRGO = 0x00002000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T2_CC1 = 0x00003000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T3_CC4 = 0x00004000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T4_TRGO = 0x00005000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_EXT_IT15_TIM8_CC4 = 0x00006000,
	
	ADC_EXTERNAL_TRIG_INJEC_CONV_T1_TRGO = 0x00000000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T1_CC4 = 0x00001000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_NONE = 0x00007000,
	
	ADC_EXTERNAL_TRIG_INJEC_CONV_T4_CC3 = 0x00002000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T8_CC2 = 0x00004000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T8_CC4 = 0x00005000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T5_TRGO = 0x00005000,
	ADC_EXTERNAL_TRIG_INJEC_CONV_T5_CC4 = 0x00006000
}ADC_EXTERNAL_TRIG_INJEC_CONV_T;

/**
 * @brief	ADC Injected channels
 */
typedef enum
{
	ADC_INJECTED_CHANNEL_1 = 0x14,
	ADC_INJECTED_CHANNEL_2 = 0x18,
	ADC_INJECTED_CHANNEL_3 = 0x1C,
	ADC_INJECTED_CHANNEL_4 = 0x20
}ADC_INJECTED_CHANNEL_T;

/**
 * @brief	ADC Analog Watchdog Selection
 */
typedef enum
{
	ADC_ANALOG_WATCHDOG_SINGLE_REG_ENABLE = 0x00800200,
	ADC_ANALOG_WATCHDOG_SINGLE_INJEC_ENABLE = 0x00400200,
	ADC_ANALOG_WATCHDOG_SINGLE_REG_OR_INJEC_ENABLE = 0x00C00200,
	ADC_ANALOG_WATCHDOG_ALL_REG_ENABLE = 0x00800000,
	ADC_ANALOG_WATCHDOG_ALL_INJEC_ENABLE = 0x00400000,
	ADC_ANALOG_WATCHDOG_ALL_REG_ALL_INJEC_ENABLE = 0x00C00000,
	ADC_ANALOG_WATCHDOG_NONE = 0x00000000
}ADC_ANALOG_WATCHDOG_T;

/**
 * @brief	ADC Interrupt enumeration
 */
typedef enum
{
	ADC_IT_EOC = 0x0220,
	ADC_IT_AWD = 0x0140,
	ADC_IT_JEOC = 0x0480
}ADC_IT_T;

/**
 * @brief	ADC Flag
 */
typedef enum
{
	ADC_FLAG_AWD = 0x01,
	ADC_FLAG_EOC = 0x02,
	ADC_FLAG_JEOC = 0x04,
	ADC_FLAG_JSTRT = 0x08,
	ADC_FLAG_STRT = 0x10
}ADC_FLAG_T;

/**
 * @brief	ADC_IJD Offset
 */
typedef enum
{
	IJD_OFFSET = 0x28
}IJD_OFFSET_T;

/**
 * @brief	ADC_RDG register address
 */
typedef enum
{
	RDG_ADDRESS = 0x4001244C
}RDG_ADDRESS_T;

/**
 * @brief	IJSQ_SET typedef
 */
typedef enum
{
	IJSQ_IJSQ_SET = 0x0000001F
}IJSQ_SET_T;

/**
 * @brief	ADC_IJSQ register address
 */
typedef enum
{
	IJSQ_IJSL_SET = 0x00300000
}IJSQ_IJSL_SET_T;

/**
 * @brief	SMPT SET typedef
 */
typedef enum
{
	SMPT1_SMPT_SET = 0x00000007,
	SMPT2_SMPT_SET = 0x00000007
}SMPT_SET_T;

/**
 * @brief	RGSQ SET typedef
 */
typedef enum
{
	RGSQ3_RGSQ_SET = 0x0000001F,
	RGSQ2_RGSQ_SET = 0x0000001F,
	RGSQ1_RGSQ_SET = 0x0000001F
}RGSQ_SET_T;

/*  Function used to set the ADC configuration to the default reset state *****/
void ADC_Reset(ADC_T* adc);
/* Initialization and Configuration functions *********************************/
void ADC_Config(ADC_T* adc, ADC_ConfigStruct_T* configStruct);
void ADC_StructInit(ADC_ConfigStruct_T* configStruct);
void ADC_Enable(ADC_T* adc);
void ADC_Disable(ADC_T* adc);
/* DMA functions **********************************************************/
void ADC_DMA_Enable(ADC_T* adc);
void ADC_DMA_Disable(ADC_T* adc);
/* Interrupt functions *********************************/
void ADC_EnableInterrupt(ADC_T* adc, uint16_t interrupt);
void ADC_DisableInterrupt(ADC_T* adc, uint16_t interrupt);
/* Configuration functions **********************************************************/
void ADC_Calibration_Reset(ADC_T* adc);
uint8_t ADC_ReadCalibrationResetFlag(ADC_T* adc);
void ADC_CalibrationStart(ADC_T* adc);
uint8_t ADC_ReadCalibrationStartFlag(ADC_T* adc);
void ADC_SoftwareStartConvEnable(ADC_T* adc);
void ADC_SoftwareStartConvDisable(ADC_T* adc);
uint8_t ADC_ReadSoftwareStartConvFlag(ADC_T* adc);
void ADC_DiscModeChannelCountConfig(ADC_T* adc, uint8_t number);
void ADC_DiscModeEnable(ADC_T* adc);
void ADC_DiscModeDisable(ADC_T* adc);
void ADC_RegularChannelConfig(ADC_T* adc, uint8_t channel,uint8_t rank, uint8_t sampleTime);
void ADC_ExternalTrigConvEnable(ADC_T* adc);
void ADC_ExternalTrigConvDisable(ADC_T* adc);
uint16_t ADC_ReadConversionValue(ADC_T* adc);
uint32_t ADC_ReadDualModeConversionValue(ADC_T* adc);
void ADC_InjectedConvEnable(ADC_T* adc);
void ADC_InjectedConvDisable(ADC_T* adc);
void ADC_InjectedDiscModeEnable(ADC_T* adc);
void ADC_InjectedDiscModeDisable(ADC_T* adc);
void ADC_ExternalTrigInjectedConvConfig(ADC_T* adc, uint32_t externalTrigInjecConv);
void ADC_ExternalTrigInjectedConvEnable(ADC_T* adc);
void ADC_ExternalTrigInjectedConvDisable(ADC_T* adc);
void ADC_SoftwareStartInjectedConvEnable(ADC_T* adc);
void ADC_SoftwareStartInjectedConvDisable(ADC_T* adc);
uint8_t ADC_ReadSoftwareStartInjectedConvFlag(ADC_T* adc);
void ADC_InjectedChannelConfig(ADC_T* adc, uint8_t channel, uint8_t rank, uint8_t sampleTime);
void ADC_InjectedSequencerLengthConfig(ADC_T* adc, uint8_t length);
void ADC_SetInjectedOffset(ADC_T* adc, uint8_t channel, uint16_t offSet);
uint16_t ADC_ReadInjectedConversionValue(ADC_T* adc, uint8_t channel);
/* Analog watchdog functions **********************************************************/
void ADC_AnalogWatchdogEnable(ADC_T* adc, uint32_t analogWatchdog);
void ADC_AnalogWatchdogDisable(ADC_T* adc);
void ADC_AnalogWatchdogThresholdsConfig(ADC_T* adc, uint16_t highThreshold, uint16_t lowThreshold);
void ADC_AnalogWatchdogSingleChannelConfig(ADC_T* adc, uint8_t channel);
/* Temp sensor functions **********************************************************/
void ADC_TempSensorVrefintEnable(ADC_T* adc);
void ADC_TempSensorVrefintDisable(ADC_T* adc);
/* Read or clear flag functions **********************************************************/
uint8_t ADC_ReadFlag(ADC_T* adc, uint8_t flag);
void ADC_ClearFlag(ADC_T* adc, uint8_t flag);
uint8_t ADC_ReadIntFlag(ADC_T* adc, uint16_t interrupt);
void ADC_ClearIntPendingBit(ADC_T* adc, uint16_t interrupt);

#ifdef __cplusplus
}
#endif

#endif /* __APM32F10x_ADC_H */
