iamsolar
Published © GPL3+

A Library for Getting the Best Out of the AD7793 ADC

The AD7793.h library provided by Analog Devices has been adapted for using on Arduino along with the SPI library.

IntermediateFull instructions provided10,938
A Library for Getting the Best Out of the AD7793 ADC

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
Analog Devices AD7793
×1
Pullup resistor 47 kOhm
×3
4.99 kOhm 0.1% 10 ppm/°C reference resistor
×1
RTD PT100, 4 lead cable
×1
10 nF and 100 nF ceramic capacitors
×5
10 µF tantalum capacitor
×1
1 kOhm current limiting resistor
×6
610 Ohm voltage bias resistor
×1

Story

Read more

Schematics

Temperature and voltage measurement circuit schematics.

Code

AD7793_example.ino

Arduino
This is an example sketch for testing communication between the Arduino and the
AD7793 using the AD7793 library from Analog Devices which I have adapted for the Arduino.
The sketch reads the ID number of the AD7793, then uses the ADC to measure the voltage on the analog voltage pin 13 and the temperature inside the chip. These are the 3 functions that can be performed by the barebone chip (not counting in the pullup resistors which must be present).
/*
This is an example sketch for testing communication between the Arduino and the
AD7793 using the AD7793 library on the Analog Devices web site adapted for the Arduino
by Ph. Sonnet, April 8, 2019

The AD7793 and the Arduino Atmega328 R3 are connected in the following way : 

Arduino R3 pin#    AD7793 pin#     Pullup resistors
    8   GPIO      3   ~CS   50 KOhm
    9   RDY       15  DOUT/~RDY  
    12  MISO      15  DOUT/~RDY
    11  MOSI      16  DIN             50 KOhm
    10  CS        not connected   
    13  SCK       1   CLK             50 KOhm

The sketch reads the ID number of the AD7793, then uses the ADC to
measure the voltage on the analog voltage pin 13 and the temperature
inside the chip. These are the 3 functions that can be performed by the
barebone chip (not counting in the pullup resistors which must be present).  


*/
  #include <AD7793.h>
  #include <Communication.h>
  #include <SPI.h>
  float Vref = 1.17; /* AD7783 internal reference voltage */ 

void setup() {
  
  Serial.begin(9600);
  while (!Serial);
  
  unsigned char answer = AD7793_Init();   /* Initializes the AD7793 and checks if the device is present*/
  Serial.print("AD7793 status = ");
  Serial.println(answer); /* Answer is 1 when the device is initialized and the ID is read and recognized */ 
  Serial.println("");
}

void loop() {
  
  AD7793_SetChannel(AD7793_CH_AVDD_MONITOR);  /* AVDD Monitor, gain 1/6, internal 1.17V reference */
  unsigned long conv = AD7793_SingleConversion();  /* Returns the result of a single conversion. */                                          
  float AVDD = ((conv - 8388608.0) / 8388608.0) * 1.17 / (1/6.0) ; /* Note: 8388608 = 2exp(23) = 0x8000000 = the output code of 0 V in bipolar mode */
  Serial.print("Analog supply voltage (AVDD) = ");
  Serial.print(AVDD, 4);
  Serial.println(" V");

  AD7793_SetChannel(AD7793_CH_TEMP); /* Temp Sensor, gain 1, Internal current reference */
  conv = AD7793_SingleConversion();  /* Returns the result of a single conversion. */
  float Temp = (((conv - 8388608.0) / 8388608.0) * 1.17 * 1000 / 0.810) - 273;  /* Sentitivity is approximately 0.81 mV/°K, according to AD7793 datasheet */
                                                                                /* To improve precision, it should be further calibrated by the user. */
  Serial.print("Chip temperature = ");
  Serial.print(Temp, 2);
  Serial.println(" C");
   
  delay(1000);
}

example_Volt_RTD_AD7793.ino

Arduino
AD7793_example_Volt_RTD.ino

Arduino

This example shows how to use an AD7793 converter to perform successively two measurements:
1) a single voltage reading in the range from 0 to 0.58 V on AD7793 channel 2
2) a repeated temperature reading using a 4-wire PT100 RTD and a ratiometric measurement circuit on AD7793 channel 1.
/*
 This example shows how to use an AD7793 converter to perform successively two measurements:
 1) a single voltage reading in the range from 0 to 0.58 V on AD7793 channel 2 (0.58 = 1.17V AD7793 internal reference divided by 2);
 2) a repeated temperature reading using a 4-wire PT100 RTD and a ratiometric measurement circuit on AD7793 channel 1 (up to 144 C; 
 for higher temperature or to use PT1000, simply lower the gain). 
 
 Using RTDs in a ratiometric measurement has the advantage in that it eliminates sources of error such as the accuracy and drift of 
 the excitation current source (provided by the AD7793) and the influence of the RTC sensor lead resistance.
 The basics for 4-wire RTD ratiometric measurement and calculation using an ADC can be found at: 
 http://www.mosaic-industries.com/embedded-systems/microcontroller-projects/temperature-measurement/platinum-rtd-sensors/amplifier-circuit-schematics  
  
 The schematics and part specifications used in this example are according to Figure 7 in 
 "Analog Front-End Design Considerations for RTD Ratiometric Temperature Measurements" by B. Zhang and A. Buda:
 https://www.analog.com/en/analog-dialogue/articles/afe-design-considerations-rtd-ratiometric.html
 However, in the present example, reference resistor is 4.99 Kohm, 0.1%, 10 ppm/C. 
 
 For additional details about RTD signal conditioning, see "Completely Integrated 4-Wire RTD Measurement System 
 "Using a Low Power, Precision, 24-Bit, Sigma-Delta ADC circuit", Note CN-0381 from Analog Devices: 
 https://www.analog.com/media/en/reference-design-documentation/reference-designs/CN0381.pdf  "

 The AD7793 and the Arduino Atmega328 R3 are connected in the following way : 

 Arduino R3 pin#   AD7793 pin#    Pullup resistors
     8   GPIO      3   ~CS             50 KOhm
     9   RDY       15  DOUT/~RDY  
     12  MISO      15  DOUT/~RDY
     11  MOSI      16  DIN             50 KOhm
     10  CS        not connected   
     13  SCK       1   CLK             50 KOhm

 Ph. Sonnet, May 1, 2019
 */
 
#include <AD7793.h>
#include <Communication.h>
#include <SPI.h>

unsigned long conv; /* The 24 bit output code resulting from a conversion by the ADC and read from the data register */
float Vref; /* The external reference voltage applied between pins REFIN(+) and REFIN(-)and resulting from the excitation current flowing through the reference resistor  */
float GAIN; /* Gain of the AD7793 unternal instrumentation amplifier */
float V; /* The voltage read on the analog input channel 2 (should be between -0.57 +0.57 when gain is set to 1) */
float RREF = 4990.0; /* The reference resistor: here, 4.99 Kohm, 0.1%, 10ppm/C */
float RRTD; /* The measured resistance of the RTD */ 
float temp; /* The temperature read on the analog input channel 1 */
float R0 = 100.0; /* RTD resistance at 0C */
float A = 3.9083E-3; /* Coefficient for t in the Callender-Van Dusen equation for temperature > 0C */
float B = -5.775E-7; /* Coefficient for t squared in the Callender-Van Dusen equation for temperature > 0C */

void setup() {
    Serial.begin(9600);      
    
    
    unsigned char answer = AD7793_Init(); /* Initialize AD7793 and check if the device is present */
    Serial.print("AD7793 status = ");
    if (answer == 1) {
      Serial.println("OK");
    }
    else {
      Serial.println("Device is not present");
    }
    
    AD7793_Reset(); /* Sends 32 consecutive 1's on SPI in order to reset the part */       
    AD7793_SetChannel(AD7793_CH_AIN2P_AIN2M); /* Selects channel 2 of AD7793 */
    AD7793_SetGain(AD7793_GAIN_1); /* Sets the gain to 1 */
    AD7793_SetIntReference(AD7793_REFSEL_INT); /* Sets the reference source for the ADC. */
    conv = AD7793_SingleConversion();
    
    Vref = 1.17; /* This is the internal reference voltage provided by the AD7793, expressed in volt */
    GAIN = 1.0; 
    V = 1000 * (conv - 8388608.0) / (8388608.0 * GAIN/Vref); /* Computes the read voltage from the conversion code, in mV */
    Serial.print("Voltage (mV) = ");
    Serial.println(V);

    Serial.println("Temperature (Celsius)");
    Serial.println("====================");
        
    AD7793_Reset(); /* Sends 32 consecutive 1's on SPI in order to reset the part */   
    AD7793_SetChannel(AD7793_CH_AIN1P_AIN1M); /* Selects channel 1 of AD7793 */
    AD7793_SetGain(AD7793_GAIN_32); /* Sets the gain to 32 */
    GAIN = 32.0;
    
    /* As the gain of the internal instrumentation amplifier has been changed, Analog Devices recommends performing a calibration  */
    AD7793_Calibrate(AD7793_MODE_CAL_INT_ZERO, AD7793_CH_AIN1P_AIN1M); /* Performs Internal Zero calibration to the specified channel. */
    AD7793_Calibrate(AD7793_MODE_CAL_INT_FULL, AD7793_CH_AIN1P_AIN1M); /* Performs Internal Full Calibration to the specified channel. */
    
    AD7793_SetIntReference(AD7793_REFSEL_EXT); /* Sets the voltage reference source for the ADC */
    AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IOUT1_IEXC2_IOUT2); /*Sets the direction of the internal excitation current source */

    AD7793_SetMode(AD7793_MODE_CONT);  /* Continuous Conversion Mode */
    AD7793_SetExcitCurrent(AD7793_EN_IXCEN_210uA);/* Sets the current of the AD7793 internal excitation current source */
    delay(1000); /* Allows excitation current to settle before starting conversions*/    
}

void loop() {
    conv = AD7793_ContinuousSingleRead();
    RRTD = RREF * (conv - 8388608.0) / (8388608.0 * GAIN); /* Computes the RTD resistance from the conversion code */
    temp = (sqrt(sq(A) - 4*B*(1.0 - RRTD/R0))-A)/(2*B);    /* Callender-Van Dusen equation temp > 0C */
    Serial.println(temp);
    delay(1000);
    }

Readme.txt

Plain text
How to implement the AD7793 library (Ph. Sonnet, Mach 29, 2019)
===================================

Directory AD7793 must be created in the Aduino "libraries" directory 
and must contain the following files : 

AD7793.h
AD7793.cpp
Communication.h
Communication.cpp


How to connect the AD7793 to the Arduino Atmega328 or MEGA
===========================================================

AD7793 pin 16 (DIN), Master Out Slave In (MOSI), must be connected to pin 11 (for Atmega328) or pin 51 (for MEGA). 

AD7793 pin 15 (DOUT/~RDY), Master In Slave Out (MISO), must be connected to pin 12 (for Atmega328) or pin 50 (for MEGA). 
It must also be connected to another digital pin af the Arduino. Suppose that you choose pin 9 for this purpose. 
This pin number must be specified in the Communication.h file by editing the #define ADI_PAR_CS_PIN line in the "GPIO Definitions" section. 

AD7793 pin 1 (CLK), Serial Clock (SCK), must be connected to Pin 13 (for Atmega328) or pin 52 (for MEGA).

AD7793 pin 3(~CS), Chip Select (CS) should not be connected to pin 10 (for Atmega328) or pin 53 (for MEGA), as it is supposed by the SPI library. 
Instead, another digital pin of the Arduino must be used. Suppose that you choose pin 8 for this purpose. 
This pin number must be specified in the Communication.h file by editing the #define ADI_PAR_CS_PIN line in the "GPIO Definitions" section.

From my experience, it is crucial to insert pullup resistors (for instance, 50 KOhm) in the MOSI, CS and CLK circuits, to ensure reliable
communication between the AD7793 and the Arduino. 


Preprocessing instructions 
==========================
  Here are the preprocessing instruction which must be inserted before setup()
  into your sketch.

#include <AD7793.h>
#include <Communication.h>
#include <SPI.h>
    
Initialization 
==============
  This must be inserted as such into setup(). No need to initialize the
  SPI channel, because this is taken care of by the AD7793_Init()function.

unsigned char answer = AD7793_Init();  /* Initializes the AD7793 and checks if the device is present*/
AD7793_Reset();    /* Sends 32 consecutive 1 on SPI in order to reset the part */


Preprogramed register setting functions
========================================
  Just insert these functions into your sketch as they are listed here, and they will
  access the various AD7793 registers (Status, Mode, Configuration, Data, IO and Data) and set parameters 
  according to the needs of your project. 

Status register
...............

unsigned char answer = AD7793_Ready();   /* Reads the Ready Bit for ADC */  
unsigned char answer = AD7793_Error();  /* Reads the ADC Error Bit */ 
unsigned char answer = AD7793_Channel3(); /* Indicates that channel 3 is being converted by the ADC */ 
unsigned char answer = AD7793_Channel2(); /* Indicates that channel 2 is being converted by the ADC */ 
unsigned char answer = AD7793_Channel1(); /* Indicates that channel 1 is being converted by the ADC */    

Mode register
..............

AD7793_SetMode(AD7793_MODE_CONT);  /* Continuous Conversion Mode */
D7793_SetMode(AD7793_MODE_SINGLE);  /* Single Conversion Mode */
AD7793_SetMode(AD7793_MODE_IDLE);  /* Idle Mode */
AD7793_SetMode(AD7793_MODE_PWRDN);  /* Power-Down Mode */
AD7793_SetMode(AD7793_MODE_CAL_INT_ZERO); /* Internal Zero-Scale Calibration */
AD7793_SetMode(AD7793_MODE_CAL_INT_FULL); /* Internal Full-Scale Calibration */
AD7793_SetMode(AD7793_MODE_CAL_SYS_ZERO); /* System Zero-Scale Calibration */
AD7793_SetMode(AD7793_MODE_CAL_SYS_FULL); /* System Full-Scale Calibration */

AD7793_SetClockSource(AD7793_CLK_INT);  /* Internal 64 kHz Clk not available at the CLK pin */
AD7793_SetClockSource(AD7793_CLK_INT_CO); /* Internal 64 kHz Clk available at the CLK pin */
AD7793_SetClockSource(AD7793_CLK_EXT);  /* External 64 kHz Clock */
AD7793_SetClockSource(AD7793_CLK_EXT_DIV2); /* External Clock divided by 2 */

AD7793_SetFilterUpdateRate(AD7793_RATE_NIL); /* Filter Update Rate: nil */
AD7793_SetFilterUpdateRate(AD7793_RATE_470); /* Filter Update Rate: 470Hz */
AD7793_SetFilterUpdateRate(AD7793_RATE_242); /* Filter Update Rate: 242Hz */
AD7793_SetFilterUpdateRate(AD7793_RATE_123); /* Filter Update Rate: 123Hz */
AD7793_SetFilterUpdateRate(AD7793_RATE_62); /* Filter Update Rate: 62Hz
AD7793_SetFilterUpdateRate(AD7793_RATE_50); /* Filter Update Rate: 50Hz */
AD7793_SetFilterUpdateRate(AD7793_RATE_39); /* Filter Update Rate: 39Hz */
AD7793_SetFilterUpdateRate(AD7793_RATE_33_2); /* Filter Update Rate: 33.2Hz */
AD7793_SetFilterUpdateRate(AD7793_RATE_19_6); /* Filter Update Rate: 19.6Hz 90dB (60Hz only) */ 
AD7793_SetFilterUpdateRate(AD7793_RATE_16_7_50_60); /* Filter Update Rate: 16.7Hz 80dB (50Hz only) */
AD7793_SetFilterUpdateRate(AD7793_RATE_12_5);  /* Filter Update Rate: 12.5Hz 66dB (50 and 60Hz) */
AD7793_SetFilterUpdateRate(AD7793_RATE_10);  /* Filter Update Rate: 10Hz 69dB (50 and 60Hz) */
AD7793_SetFilterUpdateRate(AD7793_RATE_8_33);  /* Filter Update Rate: 8.33Hz 70dB (50 and 60Hz) */
AD7793_SetFilterUpdateRate(AD7793_RATE_6_25);  /* Filter Update Rate: 6.25Hz 72dB (50 and 60Hz) */
AD7793_SetFilterUpdateRate(AD7793_RATE_4_17);  /* Filter Update Rate: 4.17Hz 74dB (50 and 60Hz) */

Configuration register
......................

AD7793_SetBiasVoltage(AD7793_VBIAS_GEN_DISABL); /* Bias voltage generator disabled */
AD7793_SetBiasVoltage(AD7793_VBIAS_AIN1_NEG);   /* Bias voltage generator to AIN1(-) * 
AD7793_SetBiasVoltage(AD7793_VBIAS_AIN2_NEG); /* Bias voltage generator to AIN2(-) */

AD7793_EnableBurnoutCurr();  /* Enable burnout current of AD7793 */
AD7793_DisableBurnoutCurr();  /* Disable burnout current of AD7793 */

AD7793_EnableUnipolar();  /* Enable unipolar coding of AD7793 */
AD7793_DisableBipolar();  /* Enable bipolar coding of AD7793 */

AD7793_EnableCurrBoost();  /* Enable bias voltage generator current boost of AD7793 */
AD7793_DisableCurrBoost();  /* Disable bias voltage generator current boost of AD7793 */

AD7793_AD7793_SetGain(AD7793_GAIN_1);  /* Gain of 1, In-amp not used  */ 
AD7793_AD7793_SetGain(AD7793_GAIN_2);  /* Gain of 2, In-amp not used */ 
AD7793_AD7793_SetGain(AD7793_GAIN_4);  /* Set the gain of the In-amp to 4 */ 
AD7793_AD7793_SetGain(AD7793_GAIN_8);  /* Set the gain of the In-amp to 8 */ 
AD7793_AD7793_SetGain(AD7793_GAIN_16);  /* Set the gain of the In-amp to 16 */ 
AD7793_AD7793_SetGain(AD7793_GAIN_32);  /* Set the gain of the In-amp to 32 */ 
AD7793_AD7793_SetGain(AD7793_GAIN_64);  /* Set the gain of the In-amp to 64 */ 
AD7793_AD7793_SetGain(AD7793_GAIN_128); /* Set the gain of the In-amp to 128 */ 

AD7793_SetIntReference(AD7793_REFSEL_INT);  /* Select internal reference voltage source for the ADC */
AD7793_SetIntReference(AD7793_REFSEL_EXT);  /* External voltage reference applied between REFIN(+) and REFIN(–) */

AD7793_EnableBufMode();  /* Enable buffered mode of AD7793 */
AD7793_DisableBufMode();  /* Disable buffered mode of AD7793 */

AD7793_SetChannel(AD7793_CH_AIN1P_AIN1M); /* Select channel AIN1(+) - AIN1(-) */           
AD7793_SetChannel(AD7793_CH_AIN2P_AIN2M); /* Select channel AIN2(+) - AIN2(-) */
AD7793_SetChannel(AD7793_CH_AIN3P_AIN3M); /* Select channel AIN3(+) - AIN3(-) */
AD7793_SetChannel(AD7793_CH_TEMP);    /* Temp Sensor, gain 1, Internal current reference */
AD7793_SetChannel(AD7793_CH_AVDD_MONITOR); /* AVDD Monitor, gain 1/6, internal 1.17V reference */

IO Register
===========

AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IOUT1_IEXC2_IOUT2); /* IEXC1 connect to IOUT1, IEXC2 connect to IOUT2 */
AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IOUT2_IEXC2_IOUT1); /* IEXC1 connect to IOUT2, IEXC2 connect to IOUT1 */
AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IEXC2_IOUT1);  /* Both current sources IEXC1,2 connect to IOUT1  */
AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IEXC2_IOUT2);  /* Both current sources IEXC1,2 connect to IOUT2 */
AD7793_SetExcitCurrent(AD7793_EN_IXCEN_DISABLE); /* Disable excitation current*/
AD7793_SetExcitCurrent(AD7793_EN_IXCEN_10uA);  /* Excitation Current 10uA */
AD7793_SetExcitCurrent(AD7793_EN_IXCEN_210uA);  /* Excitation Current 210uA */
AD7793_SetExcitCurrent(AD7793_EN_IXCEN_1mA);  /* Excitation Current 1mA */


Return the result of conversion
===============================

unsigned long conv = AD7793_SingleConversion(); /* Returns the result of a single conversion. */
unsigned long conv = AD7793_ContinuousReadAvg(unsigned char sampleNumber); /* Returns the average of several conversion results. */
unsigned long conv = AD7793_ContinuousSingleRead(); /* Returns a single measurement, provided continuous mesurement mode has been set up. */


Calibration
===========

void AD7793_Calibrate(unsigned char mode, unsigned char channel); /* Performs the given calibration to the specified channel. */

Values for parameter mode:
For performing an internal Zero-Scale Calibration: AD7793_MODE_CAL_INT_ZERO
For performing an internal Full-Scale Calibration: AD7793_MODE_CAL_INT_FULL
For performing a system Zero-Scale Calibration: AD7793_MODE_CAL_SYS_ZERO
For performing a Full-Scale Calibration: AD7793_MODE_CAL_SYS_FULL

Values for parameter mode:
For selecting channel 1 AIN1(+) - AIN1(-): AD7793_CH_AIN1P_AIN1M
For selecting channel 2 AIN2(+) - AIN2(-): AD7793_CH_AIN2P_AIN2M
For selecting channel 3 AIN3(+) - AIN3(-): AD7793_CH_AIN3P_AIN3M


Power-on/reset default register setting
======================================

After powering on or resetting the AD7793, the registers are set just as if all the following commands had been executed:

Mode register
...............

AD7793_SetMode(AD7793_MODE_CONT);  /* Continuous Conversion Mode */
AD7793_SetClockSource(AD7793_CLK_INT);  /* Internal 64 kHz Clk not available at the CLK pin */
AD7793_SetFilterUpdateRate(AD7793_RATE_NIL); /* Filter Update Rate: nil */

Configuration register
......................

AD7793_SetBiasVoltage(AD7793_VBIAS_GEN_DISABL); /* Bias voltage generator disabled */
AD7793_DisableBurnoutCurr();    /* Disable burnout current of AD7793 */
AD7793_DisableBipolar();    /* Enable bipolar coding of AD7793 */
AD7793_DisableCurrBoost();    /* Disable bias voltage generator current boost of AD7793 */
AD7793_AD7793_SetGain(AD7793_GAIN_128);  /* Set the gain of the In-amp to 128 */
AD7793_SetIntReference(AD7793_REFSEL_EXT); /* External voltage reference applied between REFIN(+) and REFIN(–) */
AD7793_EnableBufMode();    /* Enable buffered mode of AD7793 */
AD7793_SetChannel(AD7793_CH_AIN1P_AIN1M); /* Select channel AIN1(+) - AIN1(-) */

IO register
...........

AD7793_SetExcitDirection(AD7793_DIR_IEXC1_IOUT1_IEXC2_IOUT2); /* IEXC1 connect to IOUT1, IEXC2 connect to IOUT2 */
AD7793_SetExcitCurrent(AD7793_EN_IXCEN_DISABLE);  /* Disable excitation current*/

Communication.cpp

C/C++
/***************************************************************************//**
 *   @file   Communication.c
 *   @brief  Implementation of Communication Driver.
 *   @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
 * Copyright 2012(c) Analog Devices, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Analog Devices, Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *  - The use of this software may or may not infringe the patent rights
 *    of one or more patent holders.  This license does not release you
 *    from the requirement that you obtain separate licenses from these
 *    patent holders to use this software.
 *  - Use of the software either in source or binary form, must be run
 *    on or directly connected to an Analog Devices Inc. component.
 *
 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
********************************************************************************
 *   SVN Revision: 500
*******************************************************************************

********************************************************************************
 *   Modified and adapted for Arduino by Ph. Sonnet.  March 27, 2019, Version 1.1
*******************************************************************************/

/******************************************************************************/
/* Include Files                                                              */
/******************************************************************************/
#include "AD7793.h"
#include "Arduino.h"
#include "Communication.h"
#include "SPI.h"

/***************************************************************************//**
 * @brief Initializes the SPI communication peripheral.
 *
 * @param lsbFirst - Transfer format (0 or 1).
 *                   Example: 0x0 - MSB first.
 *                            0x1 - LSB first.
 * @param clockFreq - SPI clock frequency (Hz).
 *                    Example: 1000 - SPI clock frequency is 1 kHz.
 * @param clockPol - SPI clock polarity (0 or 1).
 *                   Example: 0x0 - idle state for SPI clock is low.
 *	                          0x1 - idle state for SPI clock is high.
 * @param clockPha - SPI clock phase (0 or 1).
 *                   Example: 0x0 - data is latched on the leading edge of SPI
 *                                  clock and data changes on trailing edge.
 *                            0x1 - data is latched on the trailing edge of SPI
 *                                  clock and data changes on the leading edge.
 *
 * @return 0 - Initialization failed, 1 - Initialization succeeded.
*******************************************************************************/

unsigned char SPI_Init()
{	ADI_PART_CS_PIN_OUT;
	ADI_PART_CS_HIGH;
	GPIO1_PIN_IN;

	SPI.begin(); // configure the SPI port for your SPI device.
	SPI.beginTransaction(SPI_SETTINGS); // implements the SPI communication settings you defined in Communication.h
    return(1);
}

/***************************************************************************//**
 * @brief Writes data to SPI.
 *
 * @param data - Write data buffer:
 *               - first byte is the chip select number;
 *               - from the second byte onwards are located data bytes to write.
 * @param bytesNumber - Number of bytes to write.
 *
 * @return Number of written bytes.
*******************************************************************************/
unsigned char SPI_Write(unsigned char* data,
                        unsigned char bytesNumber)
{
	int SCNumber = data[0];

	ADI_PART_CS_LOW;
	SPI.transfer(&data[1],bytesNumber);
	if (SCNumber == 0x1) {
		ADI_PART_CS_HIGH;
		}
	return(bytesNumber);
}

/***************************************************************************//**
 * @brief Reads data from SPI.
 *
 * @param data - As an input parameter, data represents the write buffer:
 *               - first byte is the chip select number;
 *               - from the second byte onwards are located data bytes to write.
 *               As an output parameter, data represents the read buffer:
 *               - from the first byte onwards are located the read data bytes.
 * @param bytesNumber - Number of bytes to write.
 *
 * @return Number of written bytes.
*******************************************************************************/
unsigned char SPI_Read(unsigned char* data,
                       unsigned char bytesNumber)
{ int i = 0;


    ADI_PART_CS_LOW;
    int SCNumber = data[0];
   for(i = 1 ;i < bytesNumber + 1 ; i ++)
    {
		  data[i-1] = SPI.transfer(data[i]);
	}
    if (SCNumber == 0x1) {
		ADI_PART_CS_HIGH;
		}
 	return(bytesNumber);
	}

Communication.h

C/C++
/***************************************************************************//**
 *   @file   Communication.h
 *   @brief  Header file of Communication Driver.
 *   @author DBogdan (dragos.bogdan@analog.com)
********************************************************************************
 * Copyright 2012(c) Analog Devices, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Analog Devices, Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *  - The use of this software may or may not infringe the patent rights
 *    of one or more patent holders.  This license does not release you
 *    from the requirement that you obtain separate licenses from these
 *    patent holders to use this software.
 *  - Use of the software either in source or binary form, must be run
 *    on or directly connected to an Analog Devices Inc. component.
 *
 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
********************************************************************************
 *   SVN Revision: 500
*******************************************************************************

********************************************************************************
 *   Modified and adapted for Arduino by Ph. Sonnet.  March 27, 2019, Version 1.1
*******************************************************************************/


#ifndef _COMMUNICATION_H_
#define _COMMUNICATION_H_
#include "SPI.h"

/******************************************************************************/
/* GPIO Definitions                                                           */
/******************************************************************************/

#define ADI_PART_CS_PIN      8  // Pin of the Arduino to which the ADC Chip Select pin is connected.
								// Leave the Arduino #10 pin unconnected, contrarily to what is normally assumed by the SPI library.
#define ADI_PART_CS_PIN_OUT  pinMode(ADI_PART_CS_PIN,OUTPUT)
#define ADI_PART_CS_LOW      digitalWrite(ADI_PART_CS_PIN,LOW)
#define ADI_PART_CS_HIGH     digitalWrite(ADI_PART_CS_PIN,HIGH)
#define GPIO1_PIN            9  // Pin of the Arduino to which the ADC Dout/Data Ready pin is connected for determining the end of conversion/calibration using a polling sequence.
								// Note: the Aduino #12 pin must also be connected to the ADC Dout/Data Ready pin, as requested by the SPI library.
#define GPIO1_PIN_IN         pinMode(GPIO1_PIN,INPUT)
#define GPIO1_STATE          digitalRead(GPIO1_PIN)
#define SPI_SETTINGS         SPISettings(4000000, MSBFIRST, SPI_MODE3) // 4 MHz clock, MSB first, mode 0

/******************************************************************************/
/* Functions Prototypes                                                       */
/******************************************************************************/

/* Initializes the SPI communication peripheral. */
unsigned char SPI_Init();

/* Writes data to SPI. */
unsigned char SPI_Write(unsigned char* data,
                        unsigned char bytesNumber);
/* Reads data from SPI. */
unsigned char SPI_Read(unsigned char* data,
                       unsigned char bytesNumber);

#endif	// _COMMUNICATION_H_

AD7793.cpp

C/C++
/***************************************************************************//**
 *   @file   AD7793.c
 *   @brief  Implementation of AD7793 Driver.
 *   @author Bancisor MIhai
********************************************************************************
 * Copyright 2012(c) Analog Devices, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Analog Devices, Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *  - The use of this software may or may not infringe the patent rights
 *    of one or more patent holders.  This license does not release you
 *    from the requirement that you obtain separate licenses from these
 *    patent holders to use this software.
 *  - Use of the software either in source or binary form, must be run
 *    on or directly connected to an Analog Devices Inc. component.
 *
 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
********************************************************************************
 *   SVN Revision: 500
*******************************************************************************

********************************************************************************
 *   Modified and adapted for Arduino by Ph. Sonnet.  March 9, 2019, Version 1.1
*******************************************************************************/

/******************************************************************************/
/* Include Files                                                              */
/******************************************************************************/
#include "AD7793.h"				// AD7793 definitions.
#include "Communication.h"		// Communication definitions.
#include "Arduino.h"
#include "SPI.h"

/***************************************************************************//**
 * @brief Initializes the AD7793 and checks if the device is present.
 *
 * @return status - Result of the initialization procedure.
 *                  Example: 1 - if initialization was successful (ID is 0x0B).
 *                           0 - if initialization was unsuccessful.
*******************************************************************************/

unsigned char AD7793_Init(void)
{
	unsigned char status = 0x1;

    SPI_Init();
    if((AD7793_GetRegisterValue(AD7793_REG_ID, 1, 1) & AD7793_ID_MASK) != AD7793_ID)
	{
		status = 0x0;
	}

	return(status);
}
/***************************************************************************//**
 * @brief Sends 32 consecutive 1's on SPI in order to reset the part.
 *
 * @return  None.
*******************************************************************************/
void AD7793_Reset(void)
{
	unsigned char dataToSend[5] = {0x01, 0xff, 0xff, 0xff, 0xff};

    //ADI_PART_CS_LOW;
	SPI_Write(dataToSend,4);
	//ADI_PART_CS_HIGH;
}
/***************************************************************************//**
 * @brief Reads the Ready Bit for ADC
 *
 * @return status: 1 - if conversion is not yet completed and data is not yet written to the data register.
 *                 0 - if data is written to the ADC data register.
*******************************************************************************/
unsigned char AD7793_Ready(void)
{
	unsigned char status = 0x0;

	if((AD7793_GetRegisterValue(AD7793_REG_STAT, 1, 1) & AD7793_STAT_RDY) == 0x80)
	{
		status = 0x1;
	}

	return(status);
}
/***************************************************************************//**
* @brief Reads the ADC error bit.
 *
 * @return status: 1 - result written to ADC data register all clamped has been all clamped to 1 or 0.
 *                 0 - No error due to overrrange, underrange or other error sources.
*******************************************************************************/
unsigned char AD7793_Error(void)
{
	unsigned char status = 0x0;

    if((AD7793_GetRegisterValue(AD7793_REG_STAT, 1, 1) & AD7793_STAT_ERR) == 0x40)
	{
		status = 0x1;
	}

	return(status);
}
/***************************************************************************//**
 * @brief Indicates that channel 3 is being converted by the ADC.
 *
 * @return status: 1 - Channel 3 is being converted by the ADC.
 *                 0 - Channel 3 is not being converted by the ADC..
*******************************************************************************/
unsigned char AD7793_Channel3(void)
{
	unsigned char status = 0x0;

    if((AD7793_GetRegisterValue(AD7793_REG_STAT, 1, 1) & AD7793_STAT_CH3) == 0x04)
	{
		status = 0x1;
	}

	return(status);
}
/***************************************************************************//**
 * @brief Indicates that channel 2 is being converted by the ADC.
 *
 * @return status: 1 - Channel 2 is being converted by the ADC.
 *                 0 - Channel 2 is not being converted by the ADC..
*******************************************************************************/
unsigned char AD7793_Channel2(void)
{
	unsigned char status = 0x0;

    if((AD7793_GetRegisterValue(AD7793_REG_STAT, 1, 1) & AD7793_STAT_CH2) == 0x02)
	{
		status = 0x1;
	}

	return(status);
}
/***************************************************************************//**
 * @brief Indicates that channel 1 is being converted by the ADC.
 *
 * @return status: 1 - Channel 1 is being converted by the ADC.
 *                 0 - Channel 1 is not being converted by the ADC..
*******************************************************************************/
unsigned char AD7793_Channel1(void)
{
	unsigned char status = 0x0;

    if((AD7793_GetRegisterValue(AD7793_REG_STAT, 1, 1) & AD7793_STAT_CH1) == 0x01)
	{
		status = 0x1;
	}

	return(status);
}
/***************************************************************************//**
 * @brief Reads the value of the selected register
 *
 * @param regAddress - The address of the register to read.
 * @param size - The size of the register to read.
 *
 * @return data - The value of the selected register register.
*******************************************************************************/
unsigned long AD7793_GetRegisterValue(unsigned char regAddress,
                                      unsigned char size,
                                      unsigned char modifyCS)
{
	unsigned char data[5]      = {0x00, 0x00, 0x00, 0x00, 0x00};
	unsigned long receivedData = 0x00;
    unsigned char i            = 0x00;

	data[0] = 0x01 * modifyCS;
	data[1] = AD7793_COMM_READ |  AD7793_COMM_ADDR(regAddress);
	SPI_Read(data,(1 + size));
	for(i = 1 ;i < size +1 ; i ++)
    {
        receivedData = (receivedData << 8) + data[i];

    }

    return (receivedData);
}
/***************************************************************************//**
 * @brief Writes the value to the register
 *
 * @param -  regAddress - The address of the register to write to.
 * @param -  regValue - The value to write to the register.
 * @param -  size - The size of the register to write.
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetRegisterValue(unsigned char regAddress,
                             unsigned long regValue,
                             unsigned char size,
                             unsigned char modifyCS)
{
	unsigned char data[5]      = {0x00, 0x00, 0x00, 0x00, 0x00};
	unsigned char* dataPointer = (unsigned char*)&regValue;
    unsigned char bytesNr      = size + 1;

    data[0] = 0x01 * modifyCS;
    data[1] = AD7793_COMM_WRITE |  AD7793_COMM_ADDR(regAddress);
    while(bytesNr > 1)
    {
        data[bytesNr] = *dataPointer;
        dataPointer ++;
        bytesNr --;
    }
	SPI_Write(data,(1 + size));
}
/***************************************************************************//**
 * @brief  Waits for RDY pin to go low.
 *
 * @return None.
*******************************************************************************/
void AD7793_WaitRdyGoLow(void)
{
    while( AD7793_RDY_STATE )
    {
        ;
    }
}

/***************************************************************************//**
 * @brief Sets the operating mode of AD7793.
 *
 * @param mode - Mode of operation.
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetMode(unsigned long mode)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_MODE,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_MODE_SEL(0xFF);
    command |= AD7793_MODE_SEL(mode);
    AD7793_SetRegisterValue(
            AD7793_REG_MODE,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}

/***************************************************************************//**
 * @brief Sets the ADC clock source of AD7793.
 *
 * @param mode - Clock source.
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetClockSource(unsigned long clockSource)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_MODE,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_MODE_CLKSRC(0xFF);
    command |= AD7793_MODE_CLKSRC(clockSource);
    AD7793_SetRegisterValue(
            AD7793_REG_MODE,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}

/***************************************************************************//**
 * @brief Sets the filter update rate of AD7793.
 *
 * @param mode - Filter update rate (Hz).
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetFilterUpdateRate(unsigned long filterRate)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_MODE,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_MODE_RATE(0xFF);
    command |= AD7793_MODE_RATE(filterRate);
    AD7793_SetRegisterValue(
            AD7793_REG_MODE,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}

/***************************************************************************//**
 * @brief Sets the direction of the internal current source.

 * @param  Current source direction.
 *
 * @return  None.
*******************************************************************************/

void AD7793_SetExcitDirection(unsigned long direction)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_IO,
                                      1,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_IEXCDIR(0xF);
    command |= AD7793_IEXCDIR(direction);
    AD7793_SetRegisterValue(
            AD7793_REG_IO,
            command,
            1,
            1); // CS is modified by SPI read/write functions.
}

/***************************************************************************//**
 * @brief Sets the current of the internal current source

 * @param  Current source value.
 *
 * @return  None.
*******************************************************************************/

void AD7793_SetExcitCurrent(unsigned long current)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_IO,
                                      1,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_IEXCEN(0xF);
    command |= AD7793_IEXCEN(current);
    AD7793_SetRegisterValue(
            AD7793_REG_IO,
            command,
            1,
            1); // CS is modified by SPI read/write functions.
}

/***************************************************************************//**
 * @brief Enable bias voltage generator of AD7793.
 *
 * @param  Bias voltage.
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetBiasVoltage(unsigned long voltage)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_VBIAS(0xFF);
    command |= AD7793_CONF_VBIAS(voltage);
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 *
 * @param  Enable burnout current of AD7793.
 *
 * @return  None.
*******************************************************************************/
void AD7793_EnableBurnoutCurr(void)

{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_BO_EN;
    command |= AD7793_CONF_BO_EN;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}

/***************************************************************************//**
 * @brief Disable burnout current of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_DisableBurnoutCurr(void)

{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_BO_EN;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Enable unipolar coding of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_EnableUnipolar(void)

{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_UNIPOLAR;
    command |= AD7793_CONF_UNIPOLAR;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Enable bipolar coding of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_DisableBipolar(void)

{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_UNIPOLAR;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Enable bias voltage generator current boost of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_EnableCurrBoost(void)

{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_BOOST;
    command |= AD7793_CONF_BOOST;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Disable bias voltage generator current boost of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_DisableCurrBoost(void)

{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_BOOST;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief  Set the gain of the In-amp.
 *
 * @param  gain - Gain.
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetGain(unsigned long gain)
	{
		unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_GAIN(0xFF);
    command |= AD7793_CONF_GAIN(gain);
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Set the reference voltage source for the ADC.
 *
 * @param type - Type of the reference.
 *               Example: AD7793_REFSEL_EXT	- External Reference Selected
 *                        AD7793_REFSEL_INT	- Internal Reference Selected.
 *
 * @return None.
*******************************************************************************/
void AD7793_SetIntReference(unsigned char type)
{
    unsigned long command = 0;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_REFSEL(AD7793_REFSEL_INT);
    command |= AD7793_CONF_REFSEL(type);
    AD7793_SetRegisterValue(AD7793_REG_CONF,
							command,
							2,
                            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Enable buffered mode of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_EnableBufMode(void)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_BUF;
    command |= AD7793_CONF_BUF;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Disable buffered mode of AD7793.
 *
 * @param  None.
 *
 * @return  None.
*******************************************************************************/
void AD7793_DisableBufMode(void)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_BUF;
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Selects the channel of AD7793.
 *
 * @param  channel - ADC channel selection.
 *
 * @return  None.
*******************************************************************************/
void AD7793_SetChannel(unsigned long channel)
{
    unsigned long command;

    command = AD7793_GetRegisterValue(AD7793_REG_CONF,
                                      2,
                                      1); // CS is modified by SPI read/write functions.
    command &= ~AD7793_CONF_CHAN(0xFF);
    command |= AD7793_CONF_CHAN(channel);
    AD7793_SetRegisterValue(
            AD7793_REG_CONF,
            command,
            2,
            1); // CS is modified by SPI read/write functions.
}
/***************************************************************************//**
 * @brief Performs the given calibration to the specified channel.
 *
 * @param mode - Calibration type.
 * @param channel - Channel to be calibrated.
 *
 * @return none.
*******************************************************************************/
void AD7793_Calibrate(unsigned char mode, unsigned char channel)
{
    //unsigned short oldRegValue = 0x0;  //J'ai remplacé short par long	????
    //unsigned short newRegValue = 0x0;

    unsigned long oldRegValue = 0x0;
    unsigned long newRegValue = 0x0;

    AD7793_SetChannel(channel);
    oldRegValue = AD7793_GetRegisterValue(AD7793_REG_MODE, 2, 1); // CS is modified by SPI read/write functions.
    oldRegValue &= ~AD7793_MODE_SEL(0x7);
    newRegValue = oldRegValue | AD7793_MODE_SEL(mode);
    AD7793_SetRegisterValue(AD7793_REG_MODE,
    						newRegValue,
    						2,
    						0); // CS is not modified by SPI read/write functions.
	AD7793_WaitRdyGoLow();
    ADI_PART_CS_HIGH;
}

/***************************************************************************//**
 * @brief Returns the result of a single conversion.
 *
 * @return regData - Result of a single analog-to-digital conversion.
*******************************************************************************/
unsigned long AD7793_SingleConversion(void)
{
    unsigned long command = 0x0;
    unsigned long regData = 0x0;

    command  = AD7793_MODE_SEL(AD7793_MODE_SINGLE);
    AD7793_SetRegisterValue(AD7793_REG_MODE,
                            command,
                            2,
                            0);// CS is not modified by SPI read/write functions.
    AD7793_WaitRdyGoLow();
    regData = AD7793_GetRegisterValue(AD7793_REG_DATA, 3, 0); // CS is not modified by SPI read/write functions.
    ADI_PART_CS_HIGH;

    return(regData);
}

/***************************************************************************//**
 * @brief Returns the average of several conversion results.
 *
 * @return samplesAverage - The average of the conversion results.
*******************************************************************************/
unsigned long AD7793_ContinuousReadAvg(unsigned char sampleNumber)
{
    unsigned long samplesAverage = 0x0;
    unsigned long command        = 0x0;
    unsigned char count          = 0x0;

    command = AD7793_MODE_SEL(AD7793_MODE_CONT);
    AD7793_SetRegisterValue(AD7793_REG_MODE,
                            command,
                            2,
                            0);// CS is not modified by SPI read/write functions.
    for(count = 0;count < sampleNumber;count ++)
    {
        AD7793_WaitRdyGoLow();
        samplesAverage += AD7793_GetRegisterValue(AD7793_REG_DATA, 3, 0);  // CS is not modified by SPI read/write functions.
    }
    ADI_PART_CS_HIGH;
    samplesAverage = samplesAverage / sampleNumber;
    return(samplesAverage);
}

/***************************************************************************//**
 * @brief Returns a single measurement, provided continuous mesurement mode has been set up.
 *
 * @return samplesAverage - Result of a single analog-to-digital conversion.
*******************************************************************************/
unsigned long AD7793_ContinuousSingleRead()
{
    unsigned long regData = 0x0;

    AD7793_WaitRdyGoLow();
    regData = AD7793_GetRegisterValue(AD7793_REG_DATA, 3, 1);  // CS is modified by SPI read/write functions.
    ADI_PART_CS_HIGH;
    return(regData);
}

AD7793.h

C/C++
/***************************************************************************//**
 *   @file   AD7793.h
 *   @brief  Header file of AD7793 Driver.
 *   @author Bancisor Mihai
********************************************************************************
 * Copyright 2012(c) Analog Devices, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *  - Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  - Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  - Neither the name of Analog Devices, Inc. nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *  - The use of this software may or may not infringe the patent rights
 *    of one or more patent holders.  This license does not release you
 *    from the requirement that you obtain separate licenses from these
 *    patent holders to use this software.
 *  - Use of the software either in source or binary form, must be run
 *    on or directly connected to an Analog Devices Inc. component.
 *
 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ANALOG DEVICES BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, INTELLECTUAL PROPERTY RIGHTS, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
********************************************************************************
 *   SVN Revision: 500
*******************************************************************************

********************************************************************************
 *   Modified and adapted for Arduino by Ph. Sonnet.  March 27, 2019, Version 1.1
*******************************************************************************/

#ifndef __AD7793_H__
#define __AD7793_H__

/******************************************************************************/
/* AD7793                                                                   */
/******************************************************************************/

/* AD7793 GPIO */
#define AD7793_RDY_STATE       GPIO1_STATE

/*AD7793 Registers*/
#define AD7793_REG_COMM		0 /* Communications Register(WO, 8-bit) */
#define AD7793_REG_STAT	    0 /* Status Register	    (RO, 8-bit) */
#define AD7793_REG_MODE	    1 /* Mode Register	     	(RW, 16-bit */
#define AD7793_REG_CONF	    2 /* Configuration Register (RW, 16-bit)*/
#define AD7793_REG_DATA	    3 /* Data Register	     	(RO, 16-/24-bit) */
#define AD7793_REG_ID	    4 /* ID Register	     	(RO, 8-bit) */
#define AD7793_REG_IO	    5 /* IO Register	     	(RO, 8-bit) */
#define AD7793_REG_OFFSET   6 /* Offset Register	    (RW, 24-bit */
#define AD7793_REG_FULLSCAL	7 /* Full-Scale Register	(RW, 24-bit */

/* Communications Register Bit Designations (AD7793_REG_COMM) */
#define AD7793_COMM_WEN		(1 << 7) 			/* Write Enable */
#define AD7793_COMM_WRITE	(0 << 6) 			/* Write Operation */
#define AD7793_COMM_READ    (1 << 6) 			/* Read Operation */
#define AD7793_COMM_ADDR(x)	(((x) & 0x7) << 3)	/* Register Address */
#define AD7793_COMM_CREAD	(1 << 2) 			/* Continuous Read of Data Register */

/* Status Register Bit Designation masks(AD7793_REG_STAT) */
#define AD7793_STAT_RDY		(1 << 7) /* Ready */
#define AD7793_STAT_ERR		(1 << 6) /* Error (Overrange, Underrange) */
#define AD7793_STAT_CH3		(1 << 2) /* Channel 3 */
#define AD7793_STAT_CH2		(1 << 1) /* Channel 2 */
#define AD7793_STAT_CH1		(1 << 0) /* Channel 1 */

/* Mode Register Bit Designations (AD7793_REG_MODE) */
#define AD7793_MODE_SEL(x)		(((x) & 0x7) << 13)	/* Operation Mode Select */
#define AD7793_MODE_CLKSRC(x)	(((x) & 0x3) << 6) 	/* ADC Clock Source Select */
#define AD7793_MODE_RATE(x)		((x) & 0xF) 		/* Filter Update Rate Select */

/* AD7793_MODE_SEL(x) options */
#define AD7793_MODE_CONT		 0 /* Continuous Conversion Mode */
#define AD7793_MODE_SINGLE		 1 /* Single Conversion Mode */
#define AD7793_MODE_IDLE		 2 /* Idle Mode */
#define AD7793_MODE_PWRDN		 3 /* Power-Down Mode */
#define AD7793_MODE_CAL_INT_ZERO 4 /* Internal Zero-Scale Calibration */
#define AD7793_MODE_CAL_INT_FULL 5 /* Internal Full-Scale Calibration */
#define AD7793_MODE_CAL_SYS_ZERO 6 /* System Zero-Scale Calibration */
#define AD7793_MODE_CAL_SYS_FULL 7 /* System Full-Scale Calibration */

/* AD7793_MODE_CLKSRC(x) options */
#define AD7793_CLK_INT		0 /* Internal 64 kHz Clk not available at the CLK pin */
#define AD7793_CLK_INT_CO	1 /* Internal 64 kHz Clk available at the CLK pin */
#define AD7793_CLK_EXT		2 /* External 64 kHz Clock */
#define AD7793_CLK_EXT_DIV2	3 /* External Clock divided by 2 */

/* AD7793_MODE_RATE(x) options */
#define AD7793_RATE_NIL    		0
#define AD7793_RATE_470    		1
#define AD7793_RATE_242    		2
#define AD7793_RATE_123    		3
#define AD7793_RATE_62    		4
#define AD7793_RATE_50  		5
#define AD7793_RATE_39			6
#define AD7793_RATE_33_2		7
#define AD7793_RATE_19_6		8 	/* 60 Hz only  */
#define AD7793_RATE_16_7_50		9 	/* 50 Hz only  */
#define AD7793_RATE_16_7_50_60  10	/* 50 and 60 Hz */
#define AD7793_RATE_12_5  		11 	/* 50 and 60 Hz */
#define AD7793_RATE_10    	12 	/* 50 and 60 Hz */
#define AD7793_RATE_8_33  		13 	/* 50 and 60 Hz */
#define AD7793_RATE_6_25  		14 	/* 50 and 60 Hz */
#define AD7793_RATE_4_17  		15 	/* 50 and 60 Hz */

/* Configuration Register Bit Designations (AD7793_REG_CONF) */
#define AD7793_CONF_VBIAS(x)  (((x) & 0x3) << 14) 	/* Bias Voltage Generator Enable */
#define AD7793_CONF_BO_EN	  (1 << 13) 			/* Burnout Current Enable */
#define AD7793_CONF_UNIPOLAR  (1 << 12) 			/* Unipolar/Bipolar Enable */
#define AD7793_CONF_BOOST	  (1 << 11) 			/* Boost Enable */
#define AD7793_CONF_GAIN(x)	  (((x) & 0x7) << 8) 	/* Gain Select */
#define AD7793_CONF_REFSEL(x) (((x) & 0x1) << 7) 	/* INT/EXT Reference Select */
#define AD7793_CONF_BUF		  (1 << 4) 				/* Buffered Mode Enable */
#define AD7793_CONF_CHAN(x)	  ((x) & 0x7) 			/* Channel select */

/* AD7793_CONF_VBIAS(x) options */
#define AD7793_VBIAS_GEN_DISABL    	0	/* Bias voltage generator disabled */
#define AD7793_VBIAS_AIN1_NEG    	1 	/* Bias voltage generator to AIN1(-) */
#define AD7793_VBIAS_AIN2_NEG    	2 	/* Bias voltage generator to AIN2(-) */

/* AD7793_CONF_GAIN(x) options  Gain and ADC input range (2.5V reference)*/
#define AD7793_GAIN_1       0	/* 1X (In-amp nor used)	2.5 */
#define AD7793_GAIN_2       1	/* 2X (In-amp nor used)	1.25 */
#define AD7793_GAIN_4       2	/* 4X 					625mV */
#define AD7793_GAIN_8       3	/* 8X 					312.5 mV*/
#define AD7793_GAIN_16      4	/* 16X					156.2 mV*/
#define AD7793_GAIN_32      5	/* 32X 					78.125 mV */
#define AD7793_GAIN_64      6	/* 64X					39.06 mV  */
#define AD7793_GAIN_128     7	/* 128X					19.53 mV */

/* AD7793_CONF_REFSEL(x) options */
#define AD7793_REFSEL_INT   1	/* Internal reference selected. */
#define AD7793_REFSEL_EXT   0	/* External reference applied between REFIN(+) and REFIN(–). */

/* AD7793_CONF_CHAN(x) options */
#define AD7793_CH_AIN1P_AIN1M	0 /* Select channel AIN1(+) - AIN1(-) */
#define AD7793_CH_AIN2P_AIN2M	1 /* Select channel AIN2(+) - AIN2(-) */
#define AD7793_CH_AIN3P_AIN3M	2 /* Select channel AIN3(+) - AIN3(-) */
#define AD7793_CH_AIN1M_AIN1M	3 /* Select channel AIN1(-) - AIN1(-) */
#define AD7793_CH_TEMP			6 /* Temp Sensor, gain 1, Internal reference */
#define AD7793_CH_AVDD_MONITOR	7 /* AVDD voltage Monitor, gain 1/6, Internal 1.17V reference */

/* ID Register Bit Designations (AD7793_REG_ID) */
#define AD7793_ID			0xB
#define AD7793_ID_MASK		0xF

/* IO (Excitation Current Sources) Register Bit Designations (AD7793_REG_IO) */
#define AD7793_IEXCDIR(x)	(((x) & 0x3) << 2)
#define AD7793_IEXCEN(x)	(((x) & 0x3) << 0)

/* AD7793_IEXCDIR(x) options*/
#define AD7793_DIR_IEXC1_IOUT1_IEXC2_IOUT2	0  /* IEXC1 connect to IOUT1, IEXC2 connect to IOUT2 */
#define AD7793_DIR_IEXC1_IOUT2_IEXC2_IOUT1	1  /* IEXC1 connect to IOUT2, IEXC2 connect to IOUT1 */
#define AD7793_DIR_IEXC1_IEXC2_IOUT1		2  /* Both current sources IEXC1,2 connect to IOUT1  */
#define AD7793_DIR_IEXC1_IEXC2_IOUT2		3  /* Both current sources IEXC1,2 connect to IOUT2 */

/* AD7793_IEXCEN(x) options*/
#define AD7793_EN_IXCEN_DISABLE				0  /* Disable excitation current*/
#define AD7793_EN_IXCEN_10uA				1  /* Excitation Current 10uA */
#define AD7793_EN_IXCEN_210uA				2  /* Excitation Current 210uA */
#define AD7793_EN_IXCEN_1mA					3  /* Excitation Current 1mA */

/******************************************************************************/
/* Functions Prototypes                                                       */
/******************************************************************************/

/* Initialize AD7793 and check if the device is present*/
unsigned char AD7793_Init(void);

/* Sends 32 consecutive 1's on SPI in order to reset the part. */
void AD7793_Reset(void);

/* Reads the Ready Bit for ADC */
unsigned char AD7793_Ready();

/* Reads the ADC Error Bit */
unsigned char AD7793_Error();

/* Indicates that channel 3 is being converted by the ADC */
unsigned char AD7793_Channel3();

/* Indicates that channel 2 is being converted by the ADC */
unsigned char AD7793_Channel2();

/* Indicates that channel 1 is being converted by the ADC */
unsigned char AD7793_Channel1();


/* Reads the value of the selected register. */
unsigned long AD7793_GetRegisterValue(unsigned char regAddress,
									  unsigned char size,
                                      unsigned char modifyCS);

/* Writes a value to the register. */
void AD7793_SetRegisterValue(unsigned char regAddress,
							 unsigned long regValue,
							 unsigned char size,
                             unsigned char modifyCS);

/* Waits for RDY pin to go low. */
void AD7793_WaitRdyGoLow(void);

/* Sets the operating mode of AD7793 */
void AD7793_SetMode(unsigned long mode);

/* Sets the ADC clock source of AD7793 */
void AD7793_SetClockSource(unsigned long clockSource);

/* Sets the filter update rate of AD7793 */
void AD7793_SetFilterUpdateRate(unsigned long filterRate);

/* Sets the direction of the internal excitation current source */
void AD7793_SetExcitDirection(unsigned long direction);

/* Sets the current of the internal excitation current source */
void AD7793_SetExcitCurrent(unsigned long current);

/* Bias voltage generator enable */
void AD7793_SetBiasVoltage(unsigned long voltage);

/* Enable burnout current */
void AD7793_EnableBurnoutCurr(void);

/* Disable burnout current of AD7793 */
void AD7793_DisableBurnoutCurr(void);

/* Enable unipolar coding of AD7793 */
void AD7793_EnableUnipolar(void);

/* Disable bipolar coding of AD7793 */
void AD7793_DisableBipolar(void);

/* Enable bias voltage generator current boost of AD7793 */
void AD7793_EnableCurrBoost(void);

/* Disable bias voltage generator current boost of AD7793 */
void AD7793_DisableCurrBoost(void);

/* Sets the gain of the In-Amp */
void AD7793_SetGain(unsigned long gain);

/* Sets the reference source for the ADC */
void AD7793_SetIntReference(unsigned char type);

/* Enable buffered mode of AD7793*/
void AD7793_EnableBufMode(void);

/* Disable buffered mode of AD7793 */
void AD7793_DisableBufMode(void);

/* Selects the channel of AD7793 */
void AD7793_SetChannel(unsigned long channel);

/* Performs the given calibration to the specified channel. */
void AD7793_Calibrate(unsigned char mode, unsigned char channel);

/* Returns the result of a single conversion. */
unsigned long AD7793_SingleConversion(void);

/* Returns the average of several conversion results. */
unsigned long AD7793_ContinuousReadAvg(unsigned char sampleNumber);

/* Returns a single measurement, provided continuous mesurement mode has been set up. */
unsigned long AD7793_ContinuousSingleRead();

#endif	// _AD7793_H_

Credits

iamsolar

iamsolar

0 projects • 4 followers

Comments