/*
 *  AD7175_2_driver.h
 *
 *  Created on: 13. 12. 2019
 *  Author: 	Vitoslavský Ondøej
 *  Company: 	UVB Technik
 *  ADC: 		AD7175-2
 *  Datasheet: 	https://www.analog.com/media/en/technical-documentation/data-sheets/AD7175-2.pdf
 *  			https://www.analog.com/media/en/technical-documentation/user-guides/eval-ad7175-2sdz_ug-741.pdf
 *
 *
 *
 *
 *  Description:
 *  	This file is used for communication with AD7175-2 Analog-Digital Converter.
 *
 *		----------register---------------------line--
 *  	COMMUNICATIONS REGISTER (8bit) 			58
 * 		STATUS REGISTER (8bit) 					101
 *		ADC MODE REGISTER (16bit) 				154
 *		INTERFACE MODE REGISTER (16bit)			216
 *		REGISTER CHECK (24bit) 					289
 *		DATA REGISTER (24bit) 					297
 *		GPIO CONFIGURATION REGISTER (16bit)		310
 *		ID REGISTER (16bit)						366
 *		CHANNEL REGISTER (16bit)				372
 *		SETUP CONFIGURATION REGISTER (16bit)	436
 *		FILTER CONFIGURATION REGISTER (16bit)	490
 *  	OFFSET REGISTER (24bit)					564
 *  	GAIN REGISTER (24bit)					573

 */

#ifndef AD7175_2_DRIVER_H_
#define AD7175_2_DRIVER_H_

 /* AD SPI Interface pins  */
 #define AD_SPI                           SPI1

 #define AD_SPI_SCK_PIN                   GPIO_PIN_5
 #define AD_SPI_SCK_GPIO_PORT             GPIOA

 #define AD_SPI_MISO_PIN                  GPIO_PIN_6
 #define AD_SPI_MISO_GPIO_PORT            GPIOA

 #define AD_SPI_MOSI_PIN                  GPIO_PIN_7
 #define AD_SPI_MOSI_GPIO_PORT            GPIOA

 #define AD_CS_PIN                        GPIO_PIN_1
 #define AD_CS_GPIO_PORT                  GPIOC
 #define AD_DUMMY_BYTE				  	  0x00

 #define AD_MAX_VOLTAGE                   (5.)
 #define AD_MIN_VOLTAGE                   (-5.)


 //COMMUNICATIONS REGISTER (8bit)
 //This bit determines if the command is a read or write operation.
typedef enum
{
	AD_WRITE = 0x00, //Write command.
	AD_READ = 0x40, //Read command.
}AdcMode;

 //The register address bits determine which register is to be read from or
 //written to as part of the current communication.
typedef enum
{
	STATUS_REG = 0x00,
	ADCMODE_REG = 0x01,
	INTERFACE_REG = 0x02,
	CHECKSUM_REG = 0x03,
	DATA_REG = 0x04,
	GPIO_REG = 0x06,
	ID_REG = 0x07,
	CH0_REG = 0x10,
	CH1_REG = 0x11,
	CH2_REG = 0x12,
	CH3_REG = 0x13,
	SETUP0_REG = 0x20,
	SETUP1_REG = 0x21,
	SETUP2_REG = 0x22,
	SETUP3_REG = 0x23,
	FILTER0_REG = 0x28,
	FILTER1_REG = 0x29,
	FILTER2_REG = 0x2A,
	FILTER3_REG = 0x2B,
	OFFSET0_REG = 0x30,
	OFFSET1_REG = 0x31,
	OFFSET2_REG = 0x32,
	OFFSET3_REG = 0x33,
	GAIN0_REG = 0x38,
	GAIN1_REG = 0x39,
	GAIN2_REG = 0x3A,
	GAIN3_REG = 0x3B,
} AdcRegister;



 //STATUS REGISTER (8bit)
 /*The status register is an 8-bit register that contains ADC and serial
  *interface status information. It can optionally be appended to the data
  *register by setting the DATA_STAT bit in the interface mode register.*/
 #define STAT_RES 0x80U

 //RDY
 /*The status of RDY is output to the DOUT/RDY pin whenever CS is low and a
 register is not being read. This bit goes low when the ADC has written a
 new result to the data register. In ADC calibration modes, this bit goes low
 when the ADC has written the calibration result. RDY is brought high
 automatically by a read of the data register.*/
 #define STAT_NRDY 	0x80U //Awaiting new data result.
 #define STAT_RDY 	0x00U //New data result available.

 //ADC_ERROR
 /*This bit by default indicates if an ADC overrange or underrange has
 occurred. The ADC result is clamped to 0xFFFFFF for overrange errors and
 0x000000 for underrange errors. This bit is updated when the ADC result is
 written and is cleared at the next update after removing the overrange or
 underrange condition.*/
 #define STAT_ADERR 	0x40U //Error.

 //CRC_ERROR
 /*This bit indicates if a CRC error has taken place during a register write.
  *For register reads, the host microcontroller determines if a CRC error has
  *occurred. This bit is cleared by a read of this register.*/
 #define STAT_CRERR 	0x20U //Error.

//REG_ERROR
 /*This bit indicates if the content of one of the internal registers has
  *changed from the value calculated when the register integrity check was
  *activated. The check is activated by setting the REG_CHECK bit in the
  *interface mode register. This bit is cleared by clearing the REG_CHECK bit.*/
 #define STAT_REGERR	0x10U //Error.

 //CHANNEL
 /*These bits indicate which channel was active for the ADC conversion
  *whose result is currently in the data register. This may be different from
  *the channel currently being converted. The mapping is a direct map from
  *the channel register; therefore, Channel 0 results in 0x0 and Channel 3
  *results in 0x3. */
 #define STAT_CH0 	0x00U //Channel 0.
 #define STAT_CH1 	0x01U //Channel 1.
 #define STAT_CH2 	0x02U //Channel 2.
 #define STAT_CH3 	0x03U //Channel 3.








 //ADC MODE REGISTER (16bit)
 /*The ADC mode register controls the operating mode of the ADC and the master
  *clock selection. Write to ADCmode register resets filter register and starts
  *new conversion or calibration.*/
 #define ADC_RES 0x8000U
 #define ADC_REG_VAL (ADC_REFEN|ADC_HIDELDI|ADC_SINSYCE|ADC_DEL0u|ADC_MDCON|ADC_CKIN)

 //REF_EN
 /*Enables internal reference and outputs a buffered 2.5 V to the REFOUT pin.*/
 #define ADC_REFEN 		0x8000U //Enabled.
 #define ADC_REFDIS 	0x0000U //Disabled.

 //HIDE_DELAY
 /*If a programmable delay has been set using the DELAY bits, this bit allows
 the delay to be hidden by absorbing the delay into the conversion time
 for selected data rates with the sinc5 + sinc1 filter. See the Delay section
 for more information. */
 #define ADC_HIDELEN	0x4000U //Enabled.
 #define ADC_HIDELDI	0x0000U //Disabled.

 //SYNC_CYC
 /*This bit can be used when only a single channel is active to set the ADC to
 only output at the settled filter data rate. */
 #define ADC_SINSYCD	0x0000U //Disabled.
 #define ADC_SINSYCE	0x2000U //Enabled.

//DELAY
 /*These bits allow a programmable delay to be added after a channel switch
 to allow settling of external circuitry before the ADC starts processing the
 input. */
 #define ADC_DEL0u		0x0000U //0 us.
 #define ADC_DEL4u		0x0100U //4 us.
 #define ADC_DEL16u		0x0200U //16 us.
 #define ADC_DEL40u		0x0300U //40 us.
 #define ADC_DEL100u	0x0400U //100 us.
 #define ADC_DEL200u	0x0500U //200 us.
 #define ADC_DEL500u	0x0600U //500 us.
 #define ADC_DELA1m		0x0700U //1 ms.

 //MODE
 /*These bits control the operating mode of the ADC. See the Operating
 Modes section for more information.*/
 #define ADC_MDCON		0x0000U //Continuous conversion mode.
 #define ADC_MDSIN		0x0010U //Single conversion mode.
 #define ADC_MDSTD		0x0020U //Standby mode.
 #define ADC_MDPWD		0x0030U //Power-down mode.
 #define ADC_MDINOF		0x0040U //Internal offset calibration.
 #define ADC_MDSYSOF	0x0060U //System offset calibration.
 #define ADC_MDSYSGN	0x0070U //System gain calibration.

 //CLOCKSEL
 /*This bit selects the ADC clock source. Selecting internal oscillator also
 enables the internal oscillator.*/
 #define ADC_CKIN	0x0000U //Internal oscillator.
 #define ADC_CKINX2	0x0004U //Internal oscillator output on XTAL2/CLKIO pin.
 #define ADC_CKEXX2	0x0008U //External clock input on XTAL2/CLKIO pin.
 #define ADC_CKEXEC	0x000CU //External crystal on XTAL1 and XTAL2/CLKIO pins.





 //INTERFACE MODE REGISTER
 /*The interface mode register configures various serial interface options.*/
 #define INT_RES 0x0000U
 #define INT_REG_VAL (ALT_SYNCDI|IOSTRENGTHDI|DOUT_RESETDI|CONTREADDI|DATA_STATEN|REG_CHECKDI|CRC_ENDIS|WL16_24)

 //ALT_SYNC
 /*This bit enables a different behavior of the SYNC/ERROR pin to allow the
 use of SYNC/ERROR as a control for conversions when cycling channels
 (see the description of the SYNC_EN bit in the GPIO Configuration Register
 section for details).*/
 #define ALT_SYNCDI	0x0000U //Disabled.
 #define ALT_SYNCEN	0x1000U //Enabled.

 //IOSTRENGTH
 /*This bit controls the drive strength of the DOUT/RDY pin. Set this bit when
 reading from the serial interface at high speed with a low IOVDD supply
 and moderate capacitance.*/
 #define IOSTRENGTHDI	0x0000U //Disabled (default).
 #define IOSTRENGTHEN	0x0800U //Enabled.

 //DOUT_RESET
 /*See DOUT_RESET section for more information.*/
 #define DOUT_RESETDI	0x0000U //Disabled.
 #define DOUT_RESETEN	0x0100U //Enabled.

 //CONTREAD
 /*This enables continuous read of the ADC data register. The ADC must be
 configured in continuous conversion mode to use continuous read. For
 more details, see the Operating Modes section.*/
 #define CONTREADDI	0x0000U //Disabled.
 #define CONTREADEN	0x0080U //Enabled.

 //DATA_STAT
 /*This enables the status register to be appended to the data register when
 read so that channel and status information are transmitted with the data.
 This is the only way to be sure that the channel bits read from the status
 register correspond to the data in the data register.*/
 #define DATA_STATDI	0x0000U //Disabled.
 #define DATA_STATEN	0x0040U //Enabled.

 //REG_CHECK
 /*This bit enables a register integrity checker, which can monitor any
 change in the value of the user registers. To use this feature, configure all
 other registers as desired, with this bit cleared. Then write to this register to set
 the REG_CHECK bit to 1. If the contents of any of the registers change, the
 REG_ERROR bit is set in the status register. To clear the error, set the
 REG_CHECK bit to 0. Neither the interface mode register nor the ADC data
 or status registers are included in the registers that are checked. If a
 register must have a new value written, this bit must first be cleared;
 otherwise, an error is flagged when the new register contents are written.*/
 #define REG_CHECKDI	0x0000U //Disabled.
 #define REG_CHECKEN	0x0020U //Enabled.

 //CRC_EN
 /*Enables CRC protection of register reads/writes. CRC increases the
 number of bytes in a serial interface transfer by one. See the CRC
 Calculation section for more details.*/
 #define CRC_ENDIS	0x0000U //Disabled.
 #define CRC_ENXOR	0x0004U //XOR checksum enabled for register read transactions; register writes still use CRC with these bits set.
 #define CRC_ENRW	0x0008U //CRC checksum enabled for read and write transactions.

 //WL16
 /*Changes the ADC data register to 16 bits. The ADC is not reset by a write
 to the interface mode register; therefore, the ADC result is not rounded to
 the correct word length immediately after writing to these bits. The first
 new ADC result is correct.*/
 #define WL16_24	0x0000U //24-bit data.
 #define WL16_16	0x0001U //16-bit data.





 //REGISTER CHECK
 /*The register check register is a 24-bit checksum calculated by exclusively OR'ing the contents of the user registers. The REG_CHECK bit
 in the interface mode register must be set for this to operate; otherwise, the register reads 0.*/
 #define REGCHECK_RES	0x000000U
 /*This register contains the 24-bit checksum of user registers when the
 REG_CHECK bit is set in the interface mode register.*/


 //DATA REGISTER
 /*The data register contains the ADC conversion result. The encoding is offset binary, or it can be changed to unipolar by the
 BI_UNIPOLARx bit in the setup configuration registers. Reading the data register brings the RDY bit and the RDY output high if it had
 been low. The ADC result can be read multiple times; however, because the RDY output has been brought high, it is not possible to know
 if another ADC result is imminent. After the command to read the ADC register is received, the ADC does not write a new result into the
 data register.*/
 #define DATA_RES	0x000000U
 /*This 24 bit register contains the ADC conversion result. If DATA_STAT is set in
 the interface mode register, the status register is appended to this
 register when read, making this a 32-bit register. If WL16 is set in the
 interface mode register, this register is reduced to 16 bits.*/


 //GPIO CONFIGURATION REGISTER
 /*The GPIO configuration register controls the general-purpose input/output pins of the ADC.*/
 #define GPIO_RES	0x0800U
 #define GPIO_REG_VAL	(GPIO_SYNCDI|GPIO_ERRDIS|IPEN1D|IPEN0D|OPEN1D|OPEN0D)

 //SYNC_EN
 /*This bit enables the SYNC/ERROR pin as a sync input. When the pin is low, this
 holds the ADC and filter in reset until SYNC/ERROR pin goes high. An alternative
 operation of the SYNC/ERROR pin is available when the ALT_SYNC bit in the
 interface mode register is set. This mode only works when multiple channels are
 enabled. In this case, a low on the SYNC/ERROR pin does not immediately reset the
 filter/modulator. Instead, if the SYNC/ERROR pin is low when the channel is due to
 be switched, the modulator and filter are prevented from starting a new
 conversion. Bringing SYNC/ERROR high begins the next conversion. This
 alternative sync mode allows SYNC/ERROR to be used while cycling through channels.*/
 #define GPIO_SYNCEN	0x0800U //Enabled.
 #define GPIO_SYNCDI	0x0000U //Disabled.

 //ERR_EN
 /*These bits enable the SYNC/ERROR pin as an error input/output.*/
 #define GPIO_ERRDIS 	0x0000U //Disabled.
 #define GPIO_ERRIN		0x0200U /*SYNC/ERROR is an error input. The (inverted) readback state is OR'ed with other
	 error sources and is available in the ADC_ERROR bit in the status register. The SYNC/
	 ERROR pin state can also be read from the ERR_DAT bit in this register.*/
 #define GPIO_ERODO		0x0400U /*SYNC/ERROR is an open-drain error output. The status register error bits are OR'ed,
	 inverted, and mapped to the SYNC/ERROR pin. The SYNC/ERROR pins of multiple
	 devices can be wired together to a common pull-up resistor so that an error on
	 any device can be observed.*/
 #define GPIO_ERGPO		0x0600U /*SYNC/ERROR is a general-purpose output. The status of the pin is controlled by the
	 ERR_DAT bit in this register. This output is referenced between IOVDD and DGND,
	 as opposed to the AVDD1 and AVSS levels used by the general-purpose input/
	 output pins. The SYNC/ERROR pin has an active pull-up in this case.*/

 //IP_EN1
 /*This bit turns GPIO1 into an input. Inputs are referenced to AVDD1 or AVSS.*/
 #define IPEN1D	0x0000U //Disabled.
 #define IPEN1I	0x0020U //Enabled.

 //IP_EN0
 /*This bit turns GPIO0 into an input. Inputs are referenced to AVDD1 or AVSS.*/
 #define IPEN0D	0x0000U //Disabled.
 #define IPEN0I	0x0010U //Enabled.

 //OP_EN1
 /*This bit turns GPIO1 into an output. Outputs are referenced between AVDD1 and AVSS.*/
 #define OPEN1D	0x0000U //Disabled.
 #define OPEN1I	0x0008U //Enabled.

 //OP_EN0
 /*This bit turns GPIO0 into an output. Outputs are referenced between AVDD1 and AVSS.*/
 #define OPEN0D	0x0000U //Disabled.
 #define OPEN0I	0x0004U //Enabled.




 //ID REGISTER
 /*The ID register returns a 16-bit ID. For the AD7175-2, this must be 0x0CDX.*/
 #define ID_RES	0x0CD0U



 //CHANNEL REGISTER
 /*The channel registers are 16-bit registers that select which channels are currently active, which inputs are selected for each channel, and
 which setup configures the ADC for that channel.*/
 #define CH0_RES	0x8001U
 #define CH1_RES	0x0001U
 #define CH2_RES	CH1_RES
 #define CH3_RES	CH1_RES

 #define CH_REG0_VAL		CH_DI|SETUP_SEL0|AINPOS0|AINNEG1
 #define CH_REG1_VAL		CH_DI|SETUP_SEL1|AINPOS2|AINNEG4
 #define CH_REG2_VAL		CH_DI|SETUP_SEL1|AINPOS3|AINNEG4
 #define CH_REG3_VAL		CH3_RES


 //CH_EN0
 /*This bit enables Channel 0. If more than one channel is enabled, the ADC
 automatically sequences between them.*/
 #define CH_DI 0x0000U //Disabled.
 #define CH_EN 0x8000U //Enabled (default ch0).

 //SETUP_SEL0
 /*These bits identify which of the four setups configure the ADC for this
 channel. A setup comprises a set of four registers: setup configuration register,
 filter configuration register, offset register, and gain register. All channels
 can use the same setup, in which case the same 2-bit value must be written
 to these bits on all active channels, or up to four channels can be
 configured differently.*/
 #define SETUP_SEL0 0x0000U //Setup 0.
 #define SETUP_SEL1 0x1000U //Setup 1.
 #define SETUP_SEL2 0x2000U //Setup 2.
 #define SETUP_SEL3 0x3000U //Setup 3.

 //AINPOS0
 /*These bits select which input is connected to the positive input of the
 ADC for this channel.*/
 #define AINPOS0 0x0000U //AIN0 (default).
 #define AINPOS1 0x0020U //AIN1.
 #define AINPOS2 0x0040U //AIN2.
 #define AINPOS3 0x0060U //AIN3.
 #define AINPOS4 0x0080U //AIN4.
 #define AINPOTP 0x0220U //Temperature sensor+.
 #define AINPOTM 0x0240U //Temperature sensor-.
 #define AINPOAP 0x0260U //((AVDD1 - AVSS)/5)+ (analog input buffers must be enabled).
 #define AINPOAM 0x0280U //((AVDD1 - AVSS)/5)- (analog input buffers must be enabled).
 #define AINPORP 0x02A0U //REF+.
 #define AINPORM 0x02C0U //REF-.

 //AINNEG0
 /*These bits select which input is connected to the negative input of the
 ADC for this channel.*/
 #define AINNEG0 0x0000U //AIN0.
 #define AINNEG1 0x0001U //AIN1 (default).
 #define AINNEG2 0x0002U //AIN2.
 #define AINNEG3 0x0003U //AIN3.
 #define AINNEG4 0x0004U //AIN4.
 #define AINNETP 0x0011U //Temperature sensor+.
 #define AINNETM 0x0012U //Temperature sensor-.
 #define AINNEAP 0x0013U //((AVDD1 - AVSS)/5)+ (analog input buffers must be enabled).
 #define AINNEAM 0x0014U //((AVDD1 - AVSS)/5)- (analog input buffers must be enabled).
 #define AINNERP 0x0015U //REF+.
 #define AINNERM 0x0016U //REF-.



 //SETUP CONFIGURATION REGISTER
 /*The setup configuration registers are 16-bit registers that configure the reference selection, input buffers, and output coding of the ADC.*/
 #define SET_RES		0x1320U
 #define SET_REG0_VAL BI_BIPOLAR|REFBUFPEN|REFBUFMEN|AINBUFPDI|AINBUFMDI|BURNOUT_DI|REF_SELEX
 #define SET_REG1_VAL BI_UNIPOLAR|REFBUFPEN|REFBUFMEN|AINBUFPDI|AINBUFMDI|BURNOUT_DI|REF_SELEX
 #define SET_REG2_VAL SET_RES
 #define SET_REG3_VAL SET_RES

 //BI_UNIPOLAR0
 /*This bit sets the output coding of the ADC for Setup 0. */
 #define BI_UNIPOLAR	0x0000U //Unipolar coded output.
 #define BI_BIPOLAR		0x1000U //Bipolar coded output (offset binary).

 //REFBUF0+
 /*This bit enables or disables the REF+ input buffer. */
 #define REFBUFPDI  	0x0000U //REF+ buffer disabled.
 #define REFBUFPEN  	0x0800U //REF+ buffer enabled.

 //REFBUF0-
 /*This bit enables or disables the REF- input buffer.*/
 #define REFBUFMDI  	0x0000U //REF- buffer disabled.
 #define REFBUFMEN  	0x0400U //REF- buffer enabled.

 //AINBUF0+
 /*This bit enables or disables the AIN+ input buffer. */
 #define AINBUFPDI  	0x0000U //AIN+ buffer disabled.
 #define AINBUFPEN  	0x0200U //AIN+ buffer enabled.

 //AINBUF0-
 /*This bit enables or disables the AIN- input buffer. */
 #define AINBUFMDI  	0x0000U //AIN- buffer disabled.
 #define AINBUFMEN  	0x0100U //AIN- buffer enabled.

 //BURNOUT_EN0
 /*This bit enables a 10 uA current source on the positive analog input
 selected and a 10 uA current sink on the negative analog input selected.
 The burnout currents are useful in diagnosis of an open wire, whereby the
 ADC result goes to full scale. Enabling the burnout currents during
 measurement results in an offset voltage on the ADC. This means the
 strategy for diagnosing an open wire operates best by turning on the
 burnout currents at intervals, before or after precision measurements. */
 #define BURNOUT_EN 	0x0080U
 #define BURNOUT_DI 	0x0000U

 //REF_SEL0
 /*These bits allow you to select the reference source for ADC conversion on
 Setup 0. */
 #define REF_SELEX	0x0000U //External Reference.
 #define REF_SELIN 	0x0020U //Internal 2.5 V Reference. This must also be enabled in the ADC mode register.
 #define REF_SELAA 	0x0030U //AVDD1 - AVSS. This can be used as a diagnostic to validate other reference values.




 //FILTER CONFIGURATION REGISTER
 /*The filter configuration registers are 16-bit registers that configure the ADC data rate and filter options. Writing to any of these registers
 resets any active ADC conversion and restarts converting at the first channel in the sequence.*/
 #define FIL_RES	0x0500U
 #define FIL_REG0_VAL 	SINC3_MAP|SINC3_FRQ //ENHFILTDI|ENHFIL16|ORDER3|ODR500
 #define FIL_REG1_VAL 	SINC3_MAP|SINC3_FRQ //ENHFILTDI|ENHFIL16|ORDER5|ODR1k
 #define FIL_REG2_VAL 	SINC3_MAP|SINC3_FRQ
 #define FIL_REG3_VAL 	0x1234 //test value

 //SINC3_MAP0
 /*If this bit is set, the mapping of the filter register changes to directly
 program the decimation rate of the sinc3 filter for Setup 0. All other
 options are eliminated. This allows fine tuning of the output data rate and
 filter notch for rejection of specific frequencies. The data rate when on a
 single channel equals fMOD/(32 × FILTCON0[14:0]). */
 //fMOD=8*10^6

 #define SINC3_MAP	0x8000U
 #define SINC3_FRQ	416U //1250U to select 66Hz data rate => 15ms (Datasheet)
 	 	 	 	 	 	 //583U to select 142Hz data rate => 7ms (Datasheet)
 	 	 	 	 	 	 //540U to select 142Hz data rate => 7ms (real + VCP)
 	 	 	 	 	 	 //416U to select 200Hz data rate => 5ms (Datasheet)
						 //374U to select 200.2Hz data rate => 4.995ms (real) - closest to 5ms

//if more channels are active, change delay in ADC MODE register
#define SINC3_FRQ2 374U

 //ENHFILTEN0
 /*This bit enables various postfilters for enhanced 50 Hz/60 Hz rejection for
 Setup 0. The ORDER0 bits must be set to 00 to select the sinc5 + sinc1
 filter for this to work. */
 #define ENHFILTDI	0x0000U 	//Disabled.
 #define ENHFILTEN	0x0800U //Enabled

 //ENHFILT0
 /*These bits select between various postfilters for enhanced 50 Hz/60 Hz
 rejection for Setup 0. */
 #define ENHFIL27 0x0200U //27 SPS, 47 dB rejection, 36.7 ms settling.
 #define ENHFIL25 0x0300U //25 SPS, 62 dB rejection, 40 ms settling.
 #define ENHFIL20 0x0500U //20 SPS, 86 dB rejection, 50 ms settling.
 #define ENHFIL16 0x0600U //16.67 SPS, 92 dB rejection, 60 ms settling.

 //ORDER0
 /*These bits control the order of the digital filter that processes the
 modulator data for Setup 0. */
 #define ORDER5	0x0000U //Sinc5 + sinc1 (default).
 #define ORDER3	0x0060U //Sinc3.

 //ODR0
 /*These bits control the output data rate of the ADC and, therefore, the
 settling time and noise for Setup 0. Rates shown as for sinc5 + sinc 1 filter.
 See Table 19 to Table 22. */
 #define ODR250k	0x0000U  //250,000.
 #define ODR125k	0x0001U  //125,000.
 #define ODR62k		0x0002U  //62,500.
 #define ODR50k		0x0003U  //50,000.
 #define ODR31k		0x0004U  //31,250.
 #define ODR25k		0x0005U  //25,000.
 #define ODR15k		0x0006U  //15,625.
 #define ODR10k		0x0007U  //10,000.
 #define ODR5k		0x0008U  //5000.
 #define ODR2k		0x0009U  //2500.
 #define ODR1k		0x000AU  //1000.
 #define ODR500		0x000BU  //500.
 #define ODR400		0x000CU  //397.5.
 #define ODR200		0x000DU  //200.
 #define ODR100		0x000EU  //100.
 #define ODR60		0x000FU  //59.92.
 #define ODR50		0x0010U  //49.96.
 #define ODR20		0x0011U  //20.
 #define ODR16		0x0012U  //16.66.
 #define ODR10		0x0013U  //10.
 #define ODR5		0x0014U  //5.

 //OFFSET REGISTER
 /*The offset (zero-scale) registers are 24-bit registers that can compensate for any offset error in the ADC or in the system.*/
 #define OFF_RES	 0x800000U
 //Offset calibration coefficient for Setup 0.
 #define OFF_REG0_VAL 0x7ffde0U //0x800000U, ch0 0x7ffb80U moje kalibrace
 #define OFF_REG1_VAL OFF_RES
 #define OFF_REG2_VAL OFF_RES
 #define OFF_REG3_VAL OFF_RES

 //GAIN REGISTER
 /*The gain (full-scale) registers are 24-bit registers that can compensate for any gain error in the ADC or in the system.*/
 #define GAIN_RES 0x500000U
 //Gain calibration coefficient for Setup 0.
 #define GAIN_REG0_VAL 0x5555C0U //0x5555C0U OK -
 #define GAIN_REG1_VAL GAIN_REG0_VAL
 #define GAIN_REG2_VAL GAIN_REG0_VAL
 #define GAIN_REG3_VAL GAIN_REG0_VAL



 #define AD_IS_CH0(Data) 		(AD_STATUS(Data)&0x03U)==(0x00U)
 #define AD_IS_CH1(Data) 		(AD_STATUS(Data)&0x03U)==(0x01U)
 #define AD_IS_CH2(Data) 		(AD_STATUS(Data)&0x03U)==(0x02U)
 #define AD_IS_CH3(Data) 		(AD_STATUS(Data)&0x03U)==(0x03U)
 #define AD_IS_ERROR(Data)		(AD_STATUS(Data)&0x40U)==(0x40U)
 #define AD_IS_NEW_DATA() 		HAL_GPIO_ReadPin(AD_SPI_MISO_GPIO_PORT,AD_SPI_MISO_PIN)==GPIO_PIN_RESET
 #define AD_DISCONNECTED(Data)  (Data==0x00U)
 #define AD_IS_ACTIVE()			(AD_Regcheck(ID_REG,ID_RES))
 #define AD_STATUS(Data)		(Data & 0x000000FF)
 #define AD_DATA(Data)  		(Data>>8)

/**
  * @brief 	Starts communication.
  * @note   Starts communication with ADC by pulling Chip Select down.
  * @param  None.
  * @retval None.
  */
 void AD_Com_Start();

 /**
   * @brief  Stops communication.
   * @note   Stops communication with ADC by pulling Chip Select up.
   * @param  None.
   * @retval None.
   */
 void AD_Com_Stop();

 /**
   * @brief  Writes data.
   * @note   Writes data to ADC by using SPI.
   * @param  data data to be send.
   * @param  bytes number of bytes to be send.
   * @retval none.
   */
 void AD_Send(uint32_t data,uint8_t bytes);

 /**
   * @brief  Reads data.
   * @note   Reads data from ADC by using SPI.
   * @param  bytes number of bytes to be read.
   * @retval Data from selected register.
   */
 uint32_t AD_Read(uint8_t bytes);


 /**
   * @brief  Initialization of ADC.
   * @note   Initializes GPIO and SPI used for communication with ADC.
   * 		 Writes settings to all used registers. This function can be modified,
   * 		 depending on the number of channels or other default settings
   * @param  None.
   * @retval None.
   */
 void AD_Init();

 /**
   * @brief  Low Level Initialization.
   * @note   Sets SPI Low level configuration (clock, pins and alternate function to AF 5).
   * 		 Is automatically called in AD_Init().
   * @param  None.
   * @retval None.
   */
 void AD_LowLevel_Init();

 /**
   * @brief  SPI Initialization.
   * @note   Sets SPI configuration and enables SPI.
   *    	 Is automatically called in AD_Init().
   * @param  None.
   * @retval None.
   */
 void AD_SPI_Init();

 /**
   * @brief  Connects ADC.
   * @note   Resets ADC and tries to read ADC's ID
   * @param  None.
   * @retval None.
   */
 void AD_Connect();

 /**
   * @brief  Resets ADC.
   * @note   Resets ADC by writing at least 3 bytes of ones to set all
   * 		 registers to its default values
   * @param  None.
   * @retval None.
   */
 void AD_Reset();


 /**
   * @brief  Size of register.
   * @note   Returns size of register in bytes.
   * @param  reg adress of ADC register.
   * @retval Returns size of ADC register in bytes (1,2,3).
   * 		 Returns 0 if param is invalid
   */
 uint8_t AD_Register_Size(AdcRegister reg);


 /**
   * @brief  Reads Data and status.
   * @note   Reads Data and status from ADC. Status is appended to Data register
   * 		 only if DATA_STATEN bit is enabled in interface register.
   * @param  none.
   * @retval Returns 24 bit data with 8 bit status appended. To separate data and
   * 		 Status you can use AD_STATUS(Retval) and AD_DATA(Retval)
   */
 uint32_t AD_Data_Status_Read();


 /**
   * @brief  Writes and checks data.
   * @note   Writes data to ADC register and checks if write was successful by
   * 		 reading from same register and comparing its value with "check" data.
   * @param  reg ADC register.
   * @param  check Data to be written to register.
   * @retval Returns 1 if operation was successful, otherwise returns 0.
   */
 uint8_t AD_Regcheck(AdcRegister reg, uint32_t check);



 /**
   * @brief  Writes data.
   * @note   Writes data to ADC register.
   * @param  reg ADC register.
   * @param  send Data to be written to register.
   * @retval none.
   */
 void AD_Write_To_Reg(AdcRegister reg,uint32_t send);


 /**
   * @brief  Reads data.
   * @note   Reads data from ADC register.
   * @param  reg ADC register.
   * @retval Value of selected ADC register.
   */
 uint32_t AD_Read_From_Reg(AdcRegister reg);

 /* Does offset calibration to selected channel
  * set mode to 0 for internal calibration(inputs are connected internally)
  * set mode to 1 for system calibration(it is required to connect input pins manually)*/


 /**
   * @brief  Offset calibration.
   * @note   Does offset calibration with selected channel. New offset value is
   * 		 saved to offset register of selected channel
   * @param  channel number of channel, can be value between 0 and 3.
   * @param  calibration_mode can be ADC_MDINOF for internal offset calibration or
   * 		 ADC_MDSYSOF for system offset calibration.
   * @retval New Value in offset register.
   */
 uint32_t AD_Offset_Calibration(uint8_t channel, uint8_t calibration_mode);


 /**
   * @brief  Enables channel.
   * @note   Enables channel reading by writing CH_EN bit to its register.
   * @param  channel number of channel, can be value between 0 and 3.
   * @retval none.
   */
 void AD_Enable_Channel(uint8_t channel);

 /**
   * @brief  Disables channel.
   * @note   Disables channel reading by writing CH_DI bit to its register.
   * @param  channel number of channel, can be value between 0 and 3.
   * @retval none.
   */
 void AD_Disable_Channel(uint8_t channel);



#endif /* AD7175_2_DRIVER_H_ */
