Analog Devices AD7124-8 - 8-Channel, Low Noise, Low Power, 24-Bit, Sigma-Delta ADC with PGA and Reference

Dependents:   CN0398 CN0391 CN0398_arduino

Files at this revision

API Documentation at this revision

Comitter:
adisuciu
Date:
Mon Oct 24 15:25:58 2016 +0000
Child:
1:4a4194a5a8ed
Commit message:
Initial revision

Changed in this revision

AD7124.cpp Show annotated file Show diff for this revision Revisions of this file
AD7124.h Show annotated file Show diff for this revision Revisions of this file
AD7124_regs.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD7124.cpp	Mon Oct 24 15:25:58 2016 +0000
@@ -0,0 +1,597 @@
+/**
+*   @file     AD7124.cpp
+*   @brief    Source file for AD7124 ADC
+*   @author   Analog Devices Inc.
+*
+* For support please go to:
+* Github: https://github.com/analogdevicesinc/mbed-adi
+* Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
+* Product: http://www.analog.com/ad7124
+* More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
+
+********************************************************************************
+* Copyright 2016(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.
+*
+********************************************************************************/
+
+#include <stdint.h>
+#include "mbed.h"
+#include "AD7124.h"
+
+/**
+ * @brief AD7790 constructor, sets CS pin and SPI format
+ * @param CS - (optional)chip select of the AD7790
+ * @param MOSI - (optional)pin of the SPI interface
+ * @param MISO - (optional)pin of the SPI interface
+ * @param SCK  - (optional)pin of the SPI interface
+ */
+AD7124::AD7124(PinName CS,
+               PinName MOSI,
+               PinName MISO,
+               PinName SCK) :
+    miso(MISO), ad7124(MOSI, MISO, SCK), cs(CS)
+{
+    cs = true; // cs is active low
+    ad7124.format(8, _SPI_MODE);
+    this->regs = ad7124_regs;
+    this->useCRC = false;
+}
+
+/**
+ * @brief Set AD7790 SPI frequency
+ * @param hz - SPI bus frequency in hz
+ * @return none
+ */
+void AD7124::frequency(int hz)
+{
+    ad7124.frequency(hz);
+}
+
+/**
+ * @brief Resets the AD7790
+ * @return none
+ */
+/*void AD7124::reset()
+{
+    ad7124.format(8, _SPI_MODE);
+    cs = false;
+    wait_us(_DELAY_TIMING);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    ad7124.write(_RESET);
+    wait_us(_DELAY_TIMING);
+    cs = true;
+    //_continous_conversion = true;
+}*/
+/**
+ * @brief Reads a register of the AD7790
+ * @param  address - address of the register
+ * @return value of the register
+ */
+uint16_t AD7124::read_reg(uint8_t address)
+{
+    uint16_t data = address << 8;
+    data |= _DUMMY_BYTE;
+    data |= _READ_FLAG;
+    return	write_spi(data);
+}
+
+/**
+ * @brief Writes a register of the AD7790
+ * @param address - address of the register
+ * @param reg_val - value to be written
+ * @return none
+ *
+ */
+void AD7124::write_reg(uint8_t address, uint8_t reg_val)
+{
+    uint16_t spi_data = address << 8;
+    spi_data |= reg_val;
+    write_spi(spi_data);
+}
+
+/**
+ * @brief Writes 16bit data to the AD7790 SPI interface
+ * @param reg_val to be written
+ * @return data returned by the AD7790
+ */
+uint16_t AD7124::write_spi(uint16_t reg_val)
+{
+    uint16_t data_result;
+    uint8_t upper_byte = (reg_val >> 8) & 0xFF;
+    uint8_t lower_byte = reg_val & 0xFF;
+    ad7124.format(8, _SPI_MODE);
+    cs = false;
+    data_result  =  (ad7124.write(upper_byte) << 8);
+    data_result |=   ad7124.write(lower_byte);
+    cs = true;
+    return data_result;
+}
+
+
+
+/***************************************************************************//**
+* @brief Reads the value of the specified register without checking if the
+*        device is ready to accept user requests.
+*
+* @param device - The handler of the instance of the driver.
+* @param pReg - Pointer to the register structure holding info about the
+*               register to be read. The read value is stored inside the
+*               register structure.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::NoCheckReadRegister(ad7124_st_reg* pReg)
+{
+    int32_t ret       = 0;
+    uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    uint8_t i         = 0;
+    uint8_t check8    = 0;
+    uint8_t msgBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+
+    check8 = useCRC;
+
+    /* Build the Command word */
+    buffer[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+                AD7124_COMM_REG_RA(pReg->addr);
+
+    /* Read data from the device */
+    ret = SPI_Read(buffer,
+                   ((useCRC != AD7124_DISABLE_CRC) ? pReg->size + 1
+                    : pReg->size) + 1);
+    if(ret < 0)
+        return ret;
+
+    /* Check the CRC */
+    if(check8 == AD7124_USE_CRC) {
+        msgBuf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+                    AD7124_COMM_REG_RA(pReg->addr);
+        for(i = 1; i < pReg->size + 2; ++i) {
+            msgBuf[i] = buffer[i];
+        }
+        check8 = ComputeCRC8(msgBuf, pReg->size + 2);
+    }
+
+    if(check8 != 0) {
+        /* ReadRegister checksum failed. */
+        return COMM_ERR;
+    }
+
+    /* Build the result */
+    pReg->value = 0;
+    for(i = 1; i < pReg->size + 1; i++) {
+        pReg->value <<= 8;
+        pReg->value += buffer[i];
+    }
+
+    return ret;
+}
+
+/***************************************************************************//**
+* @brief Writes the value of the specified register without checking if the
+*        device is ready to accept user requests.
+*
+* @param device - The handler of the instance of the driver.
+* @param reg - Register structure holding info about the register to be written
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::NoCheckWriteRegister(ad7124_st_reg reg)
+{
+    int32_t ret      = 0;
+    int32_t regValue = 0;
+    uint8_t wrBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    uint8_t i        = 0;
+    uint8_t crc8     = 0;
+
+
+    /* Build the Command word */
+    wrBuf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR |
+               AD7124_COMM_REG_RA(reg.addr);
+
+    /* Fill the write buffer */
+    regValue = reg.value;
+    for(i = 0; i < reg.size; i++) {
+        wrBuf[reg.size - i] = regValue & 0xFF;
+        regValue >>= 8;
+    }
+
+    /* Compute the CRC */
+    if(useCRC != AD7124_DISABLE_CRC) {
+        crc8 = ComputeCRC8(wrBuf, reg.size + 1);
+        wrBuf[reg.size + 1] = crc8;
+    }
+
+    /* Write data to the device */
+    ret = SPI_Write(wrBuf,
+                    (useCRC != AD7124_DISABLE_CRC) ? reg.size + 2
+                    : reg.size + 1);
+
+    return ret;
+}
+
+/***************************************************************************//**
+* @brief Reads the value of the specified register only when the device is ready
+*        to accept user requests. If the device ready flag is deactivated the
+*        read operation will be executed without checking the device state.
+*
+* @param device - The handler of the instance of the driver.
+* @param pReg - Pointer to the register structure holding info about the
+*               register to be read. The read value is stored inside the
+*               register structure.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::ReadRegister(ad7124_st_reg* pReg)
+{
+    int32_t ret;
+
+    if (pReg->addr != ERR_REG && check_ready) {
+        ret = WaitForSpiReady(spi_rdy_poll_cnt);
+        if (ret < 0)
+            return ret;
+    }
+    ret = NoCheckReadRegister(pReg);
+
+    return ret;
+}
+
+/***************************************************************************//**
+* @brief Writes the value of the specified register only when the device is
+*        ready to accept user requests. If the device ready flag is deactivated
+*        the write operation will be executed without checking the device state.
+*
+* @param device - The handler of the instance of the driver.
+* @param reg - Register structure holding info about the register to be written
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::WriteRegister(ad7124_st_reg pReg)
+{
+    int32_t ret;
+
+    if (check_ready) {
+        ret = WaitForSpiReady(spi_rdy_poll_cnt);
+        if (ret < 0)
+            return ret;
+    }
+    ret = NoCheckWriteRegister(pReg);
+
+    return ret;
+}
+
+/***************************************************************************//**
+* @brief Reads and returns the value of a device register. The read value is
+*        also stored in software register list of the device.
+*
+* @param device - The handler of the instance of the driver.
+* @param reg - Which register to read from.
+* @param pError - Pointer to the location where to store the error code if an
+*                 error occurs. Stores 0 for success or negative error code.
+*                 Does not store anything if pErorr = NULL;
+*
+* @return Returns the value read from the specified register.
+*******************************************************************************/
+uint32_t AD7124::ReadDeviceRegister(enum ad7124_registers reg)
+{
+    ReadRegister(&regs[reg]);
+    return (regs[reg].value);
+}
+
+/***************************************************************************//**
+* @brief Writes the specified value to a device register. The value to be
+*        written is also stored in the software register list of the device.
+*
+* @param device - The handler of the instance of the driver.
+* @param reg - Which register to write to.
+* @param value - The value to be written to the reigster of the device.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::WriteDeviceRegister(enum ad7124_registers reg, uint32_t value)
+{
+    regs[reg].value = value;
+    return(WriteRegister(regs[reg]));
+}
+
+/***************************************************************************//**
+* @brief Resets the device.
+*
+* @param device - The handler of the instance of the driver.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::Reset()
+{
+    int32_t ret = 0;
+    uint8_t wrBuf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+    ret = SPI_Write( wrBuf, 8);
+
+
+    return ret;
+}
+
+/***************************************************************************//**
+* @brief Waits until the device can accept read and write user actions.
+*
+* @param device - The handler of the instance of the driver.
+* @param timeout - Count representing the number of polls to be done until the
+*                  function returns.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::WaitForSpiReady(uint32_t timeout)
+{
+    ad7124_st_reg *regs;
+    int32_t ret;
+    int8_t ready = 0;
+
+    regs = this->regs;
+
+    while(!ready && --timeout) {
+        /* Read the value of the Error Register */
+        ret = ReadRegister(&regs[AD7124_Error]);
+        if(ret < 0)
+            return ret;
+
+        /* Check the SPI IGNORE Error bit in the Error Register */
+        ready = (regs[AD7124_Error].value &
+                 AD7124_ERR_REG_SPI_IGNORE_ERR) == 0;
+    }
+
+    return timeout ? 0 : TIMEOUT;
+}
+
+/***************************************************************************//**
+* @brief Waits until a new conversion result is available.
+*
+* @param device - The handler of the instance of the driver.
+* @param timeout - Count representing the number of polls to be done until the
+*                  function returns if no new data is available.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::WaitForConvReady(uint32_t timeout)
+{
+    ad7124_st_reg *regs;
+    int32_t ret;
+    int8_t ready = 0;
+
+    regs = this->regs;
+
+    while(!ready && --timeout) {
+        /* Read the value of the Status Register */
+        ret = ReadRegister(&regs[AD7124_Status]);
+        if(ret < 0)
+            return ret;
+
+        /* Check the RDY bit in the Status Register */
+        ready = (regs[AD7124_Status].value &
+                 AD7124_STATUS_REG_RDY) == 0;
+        wait_ms(1);
+    }
+
+    return timeout ? 0 : TIMEOUT;
+}
+
+bool AD7124::get_miso()
+{
+    return miso.read();
+}
+
+/***************************************************************************//**
+* @brief Reads the conversion result from the device.
+*
+* @param device - The handler of the instance of the driver.
+* @param pData - Pointer to store the read data.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::ReadData( int32_t* pData)
+{
+    int32_t ret       = 0;
+    uint8_t check8    = 0;
+    uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    uint8_t i         = 0;
+    uint8_t msgBuf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+    ad7124_st_reg *pReg;
+
+    if( !pData)
+        return INVALID_VAL;
+
+    pReg = &regs[AD7124_Data];
+
+    /* Build the Command word */
+    buffer[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+                AD7124_COMM_REG_RA(pReg->addr);
+
+
+    /* Read data from the device */
+    ret = SPI_Read(buffer,
+                   ((useCRC != AD7124_DISABLE_CRC) ? pReg->size + 1
+                    : pReg->size) + 2);
+
+    if(ret < 0)
+        return ret;
+
+    /* Check the CRC */
+    if(check8 == AD7124_USE_CRC) {
+        msgBuf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+                    AD7124_COMM_REG_RA(pReg->addr);
+        for(i = 1; i < pReg->size + 2; ++i) {
+            msgBuf[i] = buffer[i];
+        }
+        check8 = ComputeCRC8(msgBuf, pReg->size + 3);
+    }
+
+    if(check8 != 0) {
+        /* ReadRegister checksum failed. */
+        return COMM_ERR;
+    }
+
+    /* Build the result */
+    *pData = 0;
+    for(i = 1; i < pReg->size + 2; i++) {
+        *pData <<= 8;
+        *pData += buffer[i];
+    }
+    wait_ms(500);
+    return ret;
+}
+
+/***************************************************************************//**
+* @brief Computes the CRC checksum for a data buffer.
+*
+* @param pBuf - Data buffer
+* @param bufSize - Data buffer size in bytes
+*
+* @return Returns the computed CRC checksum.
+*******************************************************************************/
+uint8_t AD7124::ComputeCRC8(uint8_t * pBuf, uint8_t bufSize)
+{
+    uint8_t i   = 0;
+    uint8_t crc = 0;
+
+    while(bufSize) {
+        for(i = 0x80; i != 0; i >>= 1) {
+            if(((crc & 0x80) != 0) != ((*pBuf & i) != 0)) { /* MSB of CRC register XOR input Bit from Data */
+                crc <<= 1;
+                crc ^= AD7124_CRC8_POLYNOMIAL_REPRESENTATION;
+            } else {
+                crc <<= 1;
+            }
+        }
+        pBuf++;
+        bufSize--;
+    }
+    return crc;
+}
+
+
+/***************************************************************************//**
+* @brief Updates the device SPI interface settings.
+*
+* @param device - The handler of the instance of the driver.
+*
+* @return None.
+*******************************************************************************/
+void AD7124::UpdateDevSpiSettings()
+{
+    ad7124_st_reg *regs;
+
+    regs = this->regs;
+
+    if (regs[AD7124_Error_En].value & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN) {
+        check_ready = 1;
+    } else {
+        check_ready = 0;
+    }
+}
+
+/***************************************************************************//**
+* @brief Initializes the AD7124.
+*
+* @param device - The handler of the instance of the driver.
+* @param slave_select - The Slave Chip Select Id to be passed to the SPI calls.
+* @param regs - The list of registers of the device (initialized or not) to be
+*               added to the instance of the driver.
+*
+* @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t AD7124::Setup()
+{
+    int32_t ret;
+    uint8_t regNr;
+
+
+    spi_rdy_poll_cnt = 25000;
+
+    /* Initialize the SPI communication. */
+    /*ret = SPI_Init(0, 2500000, 1, 0);
+    if (ret < 0)
+        return ret;*/
+
+    /*  Reset the device interface.*/
+    ret = Reset();
+    if (ret < 0)
+        return ret;
+
+    check_ready = 1;
+
+    /* Initialize registers AD7124_ADC_Control through AD7124_Filter_7. */
+    for(regNr = static_cast<uint8_t>(AD7124_Status); (regNr < static_cast<uint8_t>(AD7124_Offset_0)) && !(ret < 0);
+            regNr++) {
+        if (regs[regNr].rw == AD7124_RW) {
+            ret = WriteRegister(regs[regNr]);
+            if (ret < 0)
+                break;
+        }
+
+        /* Get CRC State and device SPI interface settings */
+        if (regNr == AD7124_Error_En) {
+            UpdateDevSpiSettings();
+        }
+    }
+
+    return ret;
+}
+
+uint8_t AD7124::SPI_Read(uint8_t *data, uint8_t bytes_number)
+{
+    cs = false;
+    for(uint8_t byte = 0; byte < bytes_number; byte++) {
+        data[byte] = ad7124.write(data[byte]);
+    }
+    cs = true;
+    return bytes_number;
+}
+
+uint8_t AD7124::SPI_Write(uint8_t *data, uint8_t bytes_number)
+{
+    cs = false;
+    for(uint8_t byte = 0; byte < bytes_number; byte++) {
+        ad7124.write(data[byte]);
+    }
+
+    cs = true;
+    return bytes_number;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD7124.h	Mon Oct 24 15:25:58 2016 +0000
@@ -0,0 +1,492 @@
+/**
+*   @file     AD7124.h
+*   @brief    Header file for AD7790 ADC
+*   @author   Analog Devices Inc.
+*
+* For support please go to:
+* Github: https://github.com/analogdevicesinc/mbed-adi
+* Support: https://ez.analog.com/community/linux-device-drivers/microcontroller-no-os-drivers
+* Product: http://www.analog.com/AD7124
+* More: https://wiki.analog.com/resources/tools-software/mbed-drivers-all
+
+********************************************************************************
+* Copyright 2016(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.
+*
+********************************************************************************/
+
+#ifndef AD7790_H
+#define AD7790_H
+
+#include "mbed.h"
+#include "AD7124_regs.h"
+
+/**
+ * Comment this line if you want to turn off the debug mode.
+ * The debug mode will send a message if an exception occurs within AD7790 driver
+ */
+
+#define AD7124_DEBUG_MODE
+
+/**
+ * @brief Analog Devices AD7790 SPI 16-bit Buffered Sigma-Delta ADC
+ */
+class AD7124
+{
+public:
+    enum ad7124_registers {
+        AD7124_Status = 0x00,
+        AD7124_ADC_Control,
+        AD7124_Data,
+        AD7124_IOCon1,
+        AD7124_IOCon2,
+        AD7124_ID,
+        AD7124_Error,
+        AD7124_Error_En,
+        AD7124_Mclk_Count,
+        AD7124_Channel_0,
+        AD7124_Channel_1,
+        AD7124_Channel_2,
+        AD7124_Channel_3,
+        AD7124_Channel_4,
+        AD7124_Channel_5,
+        AD7124_Channel_6,
+        AD7124_Channel_7,
+        AD7124_Channel_8,
+        AD7124_Channel_9,
+        AD7124_Channel_10,
+        AD7124_Channel_11,
+        AD7124_Channel_12,
+        AD7124_Channel_13,
+        AD7124_Channel_14,
+        AD7124_Channel_15,
+        AD7124_Config_0,
+        AD7124_Config_1,
+        AD7124_Config_2,
+        AD7124_Config_3,
+        AD7124_Config_4,
+        AD7124_Config_5,
+        AD7124_Config_6,
+        AD7124_Config_7,
+        AD7124_Filter_0,
+        AD7124_Filter_1,
+        AD7124_Filter_2,
+        AD7124_Filter_3,
+        AD7124_Filter_4,
+        AD7124_Filter_5,
+        AD7124_Filter_6,
+        AD7124_Filter_7,
+        AD7124_Offset_0,
+        AD7124_Offset_1,
+        AD7124_Offset_2,
+        AD7124_Offset_3,
+        AD7124_Offset_4,
+        AD7124_Offset_5,
+        AD7124_Offset_6,
+        AD7124_Offset_7,
+        AD7124_Gain_0,
+        AD7124_Gain_1,
+        AD7124_Gain_2,
+        AD7124_Gain_3,
+        AD7124_Gain_4,
+        AD7124_Gain_5,
+        AD7124_Gain_6,
+        AD7124_Gain_7,
+        AD7124_REG_NO
+    };
+private:
+    enum {
+        AD7124_RW = 1,   /* Read and Write */
+        AD7124_R  = 2,   /* Read only */
+        AD7124_W  = 3,   /* Write only */
+    } ad7124_reg_access;
+
+    /*! Device register info */
+    typedef struct _ad7124_st_reg {
+        int32_t addr;
+        int32_t value;
+        int32_t size;
+        int32_t rw;
+    } ad7124_st_reg;
+
+
+    /*! Array holding the info for the ad7124 registers - address, initial value,
+    size and access type. */
+    ad7124_st_reg ad7124_regs[57] = {
+        {0x00, 0x00,   1, 2}, /* AD7124_Status */
+        {0x01, 0x0000, 2, 1}, /* AD7124_ADC_Control */
+        {0x02, 0x0000, 3, 2}, /* AD7124_Data */
+        {0x03, 0x0000, 3, 1}, /* AD7124_IOCon1 */
+        {0x04, 0x0000, 2, 1}, /* AD7124_IOCon2 */
+        {0x05, 0x12,   1, 2}, /* AD7124_ID */
+        {0x06, 0x0000, 3, 2}, /* AD7124_Error */
+        {0x07, 0x0400, 3, 1}, /* AD7124_Error_En */
+        {0x08, 0x00,   1, 2}, /* AD7124_Mclk_Count */
+        {0x09, 0x8001, 2, 1}, /* AD7124_Channel_0 */
+        {0x0A, 0x0001, 2, 1}, /* AD7124_Channel_1 */
+        {0x0B, 0x0001, 2, 1}, /* AD7124_Channel_2 */
+        {0x0C, 0x0001, 2, 1}, /* AD7124_Channel_3 */
+        {0x0D, 0x0001, 2, 1}, /* AD7124_Channel_4 */
+        {0x0E, 0x0001, 2, 1}, /* AD7124_Channel_5 */
+        {0x0F, 0x0001, 2, 1}, /* AD7124_Channel_6 */
+        {0x10, 0x0001, 2, 1}, /* AD7124_Channel_7 */
+        {0x11, 0x0001, 2, 1}, /* AD7124_Channel_8 */
+        {0x12, 0x0001, 2, 1}, /* AD7124_Channel_9 */
+        {0x13, 0x0001, 2, 1}, /* AD7124_Channel_10 */
+        {0x14, 0x0001, 2, 1}, /* AD7124_Channel_11 */
+        {0x15, 0x0001, 2, 1}, /* AD7124_Channel_12 */
+        {0x16, 0x0001, 2, 1}, /* AD7124_Channel_13 */
+        {0x17, 0x0001, 2, 1}, /* AD7124_Channel_14 */
+        {0x18, 0x0001, 2, 1}, /* AD7124_Channel_15 */
+        {0x19, 0x0860, 2, 1}, /* AD7124_Config_0 */
+        {0x1A, 0x0860, 2, 1}, /* AD7124_Config_1 */
+        {0x1B, 0x0860, 2, 1}, /* AD7124_Config_2 */
+        {0x1C, 0x0860, 2, 1}, /* AD7124_Config_3 */
+        {0x1D, 0x0860, 2, 1}, /* AD7124_Config_4 */
+        {0x1E, 0x0860, 2, 1}, /* AD7124_Config_5 */
+        {0x1F, 0x0860, 2, 1}, /* AD7124_Config_6 */
+        {0x20, 0x0860, 2, 1}, /* AD7124_Config_7 */
+        {0x21, 0x060180, 3, 1}, /* AD7124_Filter_0 */
+        {0x22, 0x060180, 3, 1}, /* AD7124_Filter_1 */
+        {0x23, 0x060180, 3, 1}, /* AD7124_Filter_2 */
+        {0x24, 0x060180, 3, 1}, /* AD7124_Filter_3 */
+        {0x25, 0x060180, 3, 1}, /* AD7124_Filter_4 */
+        {0x26, 0x060180, 3, 1}, /* AD7124_Filter_5 */
+        {0x27, 0x060180, 3, 1}, /* AD7124_Filter_6 */
+        {0x28, 0x060180, 3, 1}, /* AD7124_Filter_7 */
+        {0x29, 0x800000, 3, 1}, /* AD7124_Offset_0 */
+        {0x2A, 0x800000, 3, 1}, /* AD7124_Offset_1 */
+        {0x2B, 0x800000, 3, 1}, /* AD7124_Offset_2 */
+        {0x2C, 0x800000, 3, 1}, /* AD7124_Offset_3 */
+        {0x2D, 0x800000, 3, 1}, /* AD7124_Offset_4 */
+        {0x2E, 0x800000, 3, 1}, /* AD7124_Offset_5 */
+        {0x2F, 0x800000, 3, 1}, /* AD7124_Offset_6 */
+        {0x30, 0x800000, 3, 1}, /* AD7124_Offset_7 */
+        {0x31, 0x500000, 3, 1}, /* AD7124_Gain_0 */
+        {0x32, 0x500000, 3, 1}, /* AD7124_Gain_1 */
+        {0x33, 0x500000, 3, 1}, /* AD7124_Gain_2 */
+        {0x34, 0x500000, 3, 1}, /* AD7124_Gain_3 */
+        {0x35, 0x500000, 3, 1}, /* AD7124_Gain_4 */
+        {0x36, 0x500000, 3, 1}, /* AD7124_Gain_5 */
+        {0x37, 0x500000, 3, 1}, /* AD7124_Gain_6 */
+        {0x38, 0x500000, 3, 1}, /* AD7124_Gain_7 */
+    };
+
+
+    /* AD7124 Register Map */
+    enum AD7124_reg_map  {
+        COMM_REG     = 0x00,
+        STATUS_REG   = 0x00,
+        ADC_CTRL_REG = 0x01,
+        DATA_REG     = 0x02,
+        IO_CTRL1_REG = 0x03,
+        IO_CTRL2_REG = 0x04,
+        ID_REG       = 0x05,
+        ERR_REG      = 0x06,
+        ERREN_REG    = 0x07,
+        CH0_MAP_REG  = 0x09,
+        CH1_MAP_REG  = 0x0A,
+        CH2_MAP_REG  = 0x0B,
+        CH3_MAP_REG  = 0x0C,
+        CH4_MAP_REG  = 0x0D,
+        CH5_MAP_REG  = 0x0E,
+        CH6_MAP_REG  = 0x0F,
+        CH7_MAP_REG  = 0x10,
+        CH8_MAP_REG  = 0x11,
+        CH9_MAP_REG  = 0x12,
+        CH10_MAP_REG = 0x13,
+        CH11_MAP_REG = 0x14,
+        CH12_MAP_REG = 0x15,
+        CH13_MAP_REG = 0x16,
+        CH14_MAP_REG = 0x17,
+        CH15_MAP_REG = 0x18,
+        CFG0_REG     = 0x19,
+        CFG1_REG     = 0x1A,
+        CFG2_REG     = 0x1B,
+        CFG3_REG     = 0x1C,
+        CFG4_REG     = 0x1D,
+        CFG5_REG     = 0x1E,
+        CFG6_REG     = 0x1F,
+        CFG7_REG     = 0x20,
+        FILT0_REG    = 0x21,
+        FILT1_REG    = 0x22,
+        FILT2_REG    = 0x23,
+        FILT3_REG    = 0x24,
+        FILT4_REG    = 0x25,
+        FILT5_REG    = 0x26,
+        FILT6_REG    = 0x27,
+        FILT7_REG    = 0x28,
+        OFFS0_REG    = 0x29,
+        OFFS1_REG    = 0x2A,
+        OFFS2_REG    = 0x2B,
+        OFFS3_REG    = 0x2C,
+        OFFS4_REG    = 0x2D,
+        OFFS5_REG    = 0x2E,
+        OFFS6_REG    = 0x2F,
+        OFFS7_REG    = 0x30,
+        GAIN0_REG    = 0x31,
+        GAIN1_REG    = 0x32,
+        GAIN2_REG    = 0x33,
+        GAIN3_REG    = 0x34,
+        GAIN4_REG    = 0x35,
+        GAIN5_REG    = 0x36,
+        GAIN6_REG    = 0x37,
+        GAIN7_REG    = 0x38,
+    };
+
+    /* Communication Register bits */
+#define AD7124_COMM_REG_WEN    (0 << 7)
+#define AD7124_COMM_REG_WR     (0 << 6)
+#define AD7124_COMM_REG_RD     (1 << 6)
+#define AD7124_COMM_REG_RA(x)  ((x) & 0x3F)
+
+    /* Status Register bits */
+#define AD7124_STATUS_REG_RDY          (1 << 7)
+#define AD7124_STATUS_REG_ERROR_FLAG   (1 << 6)
+#define AD7124_STATUS_REG_POR_FLAG     (1 << 4)
+#define AD7124_STATUS_REG_CH_ACTIVE(x) ((x) & 0xF)
+
+    /* ADC_Control Register bits */
+#define AD7124_ADC_CTRL_REG_DOUT_RDY_DEL   (1 << 12)
+#define AD7124_ADC_CTRL_REG_CONT_READ      (1 << 11)
+#define AD7124_ADC_CTRL_REG_DATA_STATUS    (1 << 10)
+#define AD7124_ADC_CTRL_REG_CS_EN          (1 << 9)
+#define AD7124_ADC_CTRL_REG_REF_EN         (1 << 8)
+#define AD7124_ADC_CTRL_REG_POWER_MODE(x)  (((x) & 0x3) << 6)
+#define AD7124_ADC_CTRL_REG_MODE(x)        (((x) & 0xF) << 2)
+#define AD7124_ADC_CTRL_REG_CLK_SEL(x)    (((x) & 0x3) << 0)
+
+    /* IO_Control_1 Register bits */
+#define AD7124_IO_CTRL1_REG_GPIO_DAT2     (1 << 23)
+#define AD7124_IO_CTRL1_REG_GPIO_DAT1     (1 << 22)
+#define AD7124_IO_CTRL1_REG_GPIO_CTRL2    (1 << 19)
+#define AD7124_IO_CTRL1_REG_GPIO_CTRL1    (1 << 18)
+#define AD7124_IO_CTRL1_REG_PDSW          (1 << 15)
+#define AD7124_IO_CTRL1_REG_IOUT1(x)      (((x) & 0x7) << 11)
+#define AD7124_IO_CTRL1_REG_IOUT0(x)      (((x) & 0x7) << 8)
+#define AD7124_IO_CTRL1_REG_IOUT_CH1(x)   (((x) & 0xF) << 4)
+#define AD7124_IO_CTRL1_REG_IOUT_CH0(x)   (((x) & 0xF) << 0)
+
+    /*IO_Control_1 AD7124-8 specific bits */
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT4     (1 << 23)
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT3     (1 << 22)
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT2     (1 << 21)
+#define AD7124_8_IO_CTRL1_REG_GPIO_DAT1     (1 << 20)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL4    (1 << 19)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL3    (1 << 18)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL2    (1 << 17)
+#define AD7124_8_IO_CTRL1_REG_GPIO_CTRL1    (1 << 16)
+
+    /* IO_Control_2 Register bits */
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS7   (1 << 15)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS6   (1 << 14)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS5   (1 << 11)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS4   (1 << 10)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS3   (1 << 5)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS2   (1 << 4)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS1   (1 << 1)
+#define AD7124_IO_CTRL2_REG_GPIO_VBIAS0   (1)
+
+    /*IO_Control_2 AD7124-8 specific bits */
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS15  (1 << 15)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS14  (1 << 14)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS13  (1 << 13)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS12  (1 << 12)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS11  (1 << 11)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS10  (1 << 10)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS9   (1 << 9)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS8   (1 << 8)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS7   (1 << 7)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS6   (1 << 6)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS5   (1 << 5)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS4   (1 << 4)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS3   (1 << 3)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS2   (1 << 2)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS1   (1 << 1)
+#define AD7124_8_IO_CTRL2_REG_GPIO_VBIAS0   (1 << 0)
+
+    /* ID Register bits */
+#define AD7124_ID_REG_DEVICE_ID(x)   (((x) & 0xF) << 4)
+#define AD7124_ID_REG_SILICON_REV(x) (((x) & 0xF) << 0)
+
+    /* Error Register bits */
+#define AD7124_ERR_REG_LDO_CAP_ERR        (1 << 19)
+#define AD7124_ERR_REG_ADC_CAL_ERR        (1 << 18)
+#define AD7124_ERR_REG_ADC_CONV_ERR       (1 << 17)
+#define AD7124_ERR_REG_ADC_SAT_ERR        (1 << 16)
+#define AD7124_ERR_REG_AINP_OV_ERR        (1 << 15)
+#define AD7124_ERR_REG_AINP_UV_ERR        (1 << 14)
+#define AD7124_ERR_REG_AINM_OV_ERR        (1 << 13)
+#define AD7124_ERR_REG_AINM_UV_ERR        (1 << 12)
+#define AD7124_ERR_REG_REF_DET_ERR        (1 << 11)
+#define AD7124_ERR_REG_DLDO_PSM_ERR       (1 << 9)
+#define AD7124_ERR_REG_ALDO_PSM_ERR       (1 << 7)
+#define AD7124_ERR_REG_SPI_IGNORE_ERR     (1 << 6)
+#define AD7124_ERR_REG_SPI_SLCK_CNT_ERR   (1 << 5)
+#define AD7124_ERR_REG_SPI_READ_ERR       (1 << 4)
+#define AD7124_ERR_REG_SPI_WRITE_ERR      (1 << 3)
+#define AD7124_ERR_REG_SPI_CRC_ERR        (1 << 2)
+#define AD7124_ERR_REG_MM_CRC_ERR         (1 << 1)
+
+    /* Error_En Register bits */
+#define AD7124_ERREN_REG_MCLK_CNT_EN           (1 << 22)
+#define AD7124_ERREN_REG_LDO_CAP_CHK_TEST_EN   (1 << 21)
+#define AD7124_ERREN_REG_LDO_CAP_CHK(x)        (((x) & 0x3) << 19)
+#define AD7124_ERREN_REG_ADC_CAL_ERR_EN        (1 << 18)
+#define AD7124_ERREN_REG_ADC_CONV_ERR_EN       (1 << 17)
+#define AD7124_ERREN_REG_ADC_SAT_ERR_EN        (1 << 16)
+#define AD7124_ERREN_REG_AINP_OV_ERR_EN        (1 << 15)
+#define AD7124_ERREN_REG_AINP_UV_ERR_EN        (1 << 14)
+#define AD7124_ERREN_REG_AINM_OV_ERR_EN        (1 << 13)
+#define AD7124_ERREN_REG_AINM_UV_ERR_EN        (1 << 12)
+#define AD7124_ERREN_REG_REF_DET_ERR_EN        (1 << 11)
+#define AD7124_ERREN_REG_DLDO_PSM_TRIP_TEST_EN (1 << 10)
+#define AD7124_ERREN_REG_DLDO_PSM_ERR_ERR      (1 << 9)
+#define AD7124_ERREN_REG_ALDO_PSM_TRIP_TEST_EN (1 << 8)
+#define AD7124_ERREN_REG_ALDO_PSM_ERR_EN       (1 << 7)
+#define AD7124_ERREN_REG_SPI_IGNORE_ERR_EN     (1 << 6)
+#define AD7124_ERREN_REG_SPI_SCLK_CNT_ERR_EN   (1 << 5)
+#define AD7124_ERREN_REG_SPI_READ_ERR_EN       (1 << 4)
+#define AD7124_ERREN_REG_SPI_WRITE_ERR_EN      (1 << 3)
+#define AD7124_ERREN_REG_SPI_CRC_ERR_EN        (1 << 2)
+#define AD7124_ERREN_REG_MM_CRC_ERR_EN         (1 << 1)
+
+    /* Channel Registers 0-15 bits */
+#define AD7124_CH_MAP_REG_CH_ENABLE    (1 << 15)
+#define AD7124_CH_MAP_REG_SETUP(x)     (((x) & 0x7) << 12)
+#define AD7124_CH_MAP_REG_AINP(x)      (((x) & 0x1F) << 5)
+#define AD7124_CH_MAP_REG_AINM(x)      (((x) & 0x1F) << 0)
+
+    /* Configuration Registers 0-7 bits */
+#define AD7124_CFG_REG_BIPOLAR     (1 << 11)
+#define AD7124_CFG_REG_BURNOUT(x)  (((x) & 0x3) << 9)
+#define AD7124_CFG_REG_REF_BUFP    (1 << 8)
+#define AD7124_CFG_REG_REF_BUFM    (1 << 7)
+#define AD7124_CFG_REG_AIN_BUFP    (1 << 6)
+#define AD7124_CFG_REG_AINN_BUFM   (1 << 5)
+#define AD7124_CFG_REG_REF_SEL(x)  ((x) & 0x3) << 3
+#define AD7124_CFG_REG_PGA(x)      (((x) & 0x7) << 0)
+
+    /* Filter Register 0-7 bits */
+#define AD7124_FILT_REG_FILTER(x)        ((uint32_t)((x) & 0x7) << 21)
+#define AD7124_FILT_REG_REJ60             ((uint32_t)1 << 20)
+#define AD7124_FILT_REG_POST_FILTER(x)    ((uint32_t)((x) & 0x7) << 17)
+#define AD7124_FILT_REG_SINGLE_CYCLE      ((uint32_t)1 << 16)
+#define AD7124_FILT_REG_FS(x)             ((uint32_t)((x) & 0x7FF) << 0)
+
+public:
+
+    /** SPI configuration & constructor */
+    AD7124( PinName CS = SPI_CS, PinName MOSI = SPI_MOSI, PinName MISO = SPI_MISO, PinName SCK = SPI_SCK);
+    void frequency(int hz);
+
+    /** Low level SPI bus comm methods */
+    void reset(void);
+
+    void write_reg(uint8_t regAddress, uint8_t regValue);
+    uint16_t write_spi(uint16_t data);
+    uint16_t read_reg (uint8_t regAddress);
+    bool get_miso();
+
+
+    int32_t Reset();
+    /* Reads and returns the value of a device register. */
+    uint32_t ReadDeviceRegister(enum ad7124_registers reg);
+
+    /* Writes the specified value to a device register. */
+    int32_t WriteDeviceRegister(enum ad7124_registers reg, uint32_t value);
+
+    /*! Reads the value of the specified register. */
+    int32_t ReadRegister(ad7124_st_reg* pReg);
+
+    /*! Writes the value of the specified register. */
+    int32_t WriteRegister(ad7124_st_reg reg);
+
+    /*! Reads the value of the specified register without a device state check. */
+    int32_t NoCheckReadRegister(ad7124_st_reg* pReg);
+
+    /*! Writes the value of the specified register without a device state check. */
+    int32_t NoCheckWriteRegister(ad7124_st_reg reg);
+
+    /*! Waits until the device can accept read and write user actions. */
+    int32_t WaitForSpiReady(uint32_t timeout);
+
+    /*! Waits until a new conversion result is available. */
+    int32_t WaitForConvReady(uint32_t timeout);
+
+    /*! Reads the conversion result from the device. */
+    int32_t ReadData(int32_t* pData);
+
+    /*! Computes the CRC checksum for a data buffer. */
+    uint8_t ComputeCRC8(uint8_t* pBuf, uint8_t bufSize);
+
+    /*! Updates the device SPI interface settings. */
+    void UpdateDevSpiSettings();
+
+    /*! Initializes the AD7124. */
+    int32_t Setup();
+
+    uint8_t SPI_Read(uint8_t *data, uint8_t bytes_number);
+    uint8_t SPI_Write(uint8_t *data, uint8_t bytes_number);
+
+    DigitalIn miso;///< DigitalIn must be initialized before SPI to prevent pin MUX overwrite
+    SPI ad7124;    ///< SPI instance of the AD7790
+    DigitalOut cs; ///< DigitalOut instance for the chipselect of the AD7790
+
+private:
+
+
+    ad7124_st_reg *regs; // reg map 38 bytes ?
+    uint8_t useCRC; // boolean ?
+    int check_ready; // ?
+    int spi_rdy_poll_cnt; // timer ?
+
+    const static uint8_t _SPI_MODE = 0x03;
+    const static uint8_t _RESET = 0xFF;
+    const static uint8_t _DUMMY_BYTE = 0xFF;
+    const static uint16_t _READ_FLAG = 0x4000;
+    const static uint8_t _DELAY_TIMING = 0x02;
+
+#define AD7124_CRC8_POLYNOMIAL_REPRESENTATION 0x07 /* x8 + x2 + x + 1 */
+#define AD7124_DISABLE_CRC 0
+#define AD7124_USE_CRC 1
+#define AD7124_READ_DATA 2
+
+#define INVALID_VAL -1 /* Invalid argument */
+#define COMM_ERR    -2 /* Communication error on receive */
+#define TIMEOUT     -3 /* A timeout has occured */
+
+};
+#endif
+
+