Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 1:22ed45e195a9, committed 2019-09-05
- Comitter:
- MitchAD
- Date:
- Thu Sep 05 20:45:41 2019 +0000
- Parent:
- 0:d18c9afa4bcb
- Commit message:
- Initial Commit for the AD7124 no-OS drivers
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ad7124.cpp Thu Sep 05 20:45:41 2019 +0000
@@ -0,0 +1,524 @@
+/***************************************************************************//**
+* @file AD7124.c
+* @brief AD7124 implementation file.
+* @devices AD7124-4, AD7124-8
+*
+********************************************************************************
+* Copyright 2015(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 Files **********************************/
+/******************************************************************************/
+#include <stdlib.h>
+#include "ad7124.h"
+
+/* Error codes */
+#define INVALID_VAL -1 /* Invalid argument */
+#define COMM_ERR -2 /* Communication error on receive */
+#define TIMEOUT -3 /* A timeout has occured */
+
+/***************************************************************************//**
+ * @brief Reads the value of the specified register without checking if the
+ * device is ready to accept user requests.
+ *
+ * @param dev - The handler of the instance of the driver.
+ * @param p_reg - 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_no_check_read_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg* p_reg)
+{
+ 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 msg_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+
+ if(!dev || !p_reg)
+ return INVALID_VAL;
+
+ /* Build the Command word */
+ buffer[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+ AD7124_COMM_REG_RA(p_reg->addr);
+
+ /* Read data from the device */
+ ret = spi_write_and_read(dev->spi_desc,
+ buffer,
+ ((dev->use_crc != AD7124_DISABLE_CRC) ? p_reg->size + 1
+ : p_reg->size) + 1);
+ if(ret < 0)
+ return ret;
+
+ /* Check the CRC */
+ if(dev->use_crc == AD7124_USE_CRC) {
+ msg_buf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_RD |
+ AD7124_COMM_REG_RA(p_reg->addr);
+ for(i = 1; i < p_reg->size + 2; ++i) {
+ msg_buf[i] = buffer[i];
+ }
+ check8 = ad7124_compute_crc8(msg_buf, p_reg->size + 2);
+ }
+
+ if(check8 != 0) {
+ /* ReadRegister checksum failed. */
+ return COMM_ERR;
+ }
+
+ /* Build the result */
+ p_reg->value = 0;
+ for(i = 1; i < p_reg->size + 1; i++) {
+ p_reg->value <<= 8;
+ p_reg->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 dev - 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_no_check_write_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg reg)
+{
+ int32_t ret = 0;
+ int32_t reg_value = 0;
+ uint8_t wr_buf[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+ uint8_t i = 0;
+ uint8_t crc8 = 0;
+
+ if(!dev)
+ return INVALID_VAL;
+
+ /* Build the Command word */
+ wr_buf[0] = AD7124_COMM_REG_WEN | AD7124_COMM_REG_WR |
+ AD7124_COMM_REG_RA(reg.addr);
+
+ /* Fill the write buffer */
+ reg_value = reg.value;
+ for(i = 0; i < reg.size; i++) {
+ wr_buf[reg.size - i] = reg_value & 0xFF;
+ reg_value >>= 8;
+ }
+
+ /* Compute the CRC */
+ if(dev->use_crc != AD7124_DISABLE_CRC) {
+ crc8 = ad7124_compute_crc8(wr_buf, reg.size + 1);
+ wr_buf[reg.size + 1] = crc8;
+ }
+
+ /* Write data to the device */
+ ret = spi_write_and_read(dev->spi_desc,
+ wr_buf,
+ (dev->use_crc != 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 dev - The handler of the instance of the driver.
+ * @param p_reg - 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_read_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg* p_reg)
+{
+ int32_t ret;
+
+ if (p_reg->addr != AD7124_ERR_REG && dev->check_ready) {
+ ret = ad7124_wait_for_spi_ready(dev,
+ dev->spi_rdy_poll_cnt);
+ if (ret < 0)
+ return ret;
+ }
+ ret = ad7124_no_check_read_register(dev,
+ p_reg);
+
+ 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 dev - 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_write_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg p_reg)
+{
+ int32_t ret;
+
+ if (dev->check_ready) {
+ ret = ad7124_wait_for_spi_ready(dev,
+ dev->spi_rdy_poll_cnt);
+ if (ret < 0)
+ return ret;
+ }
+ ret = ad7124_no_check_write_register(dev,
+ p_reg);
+
+ return ret;
+}
+
+/***************************************************************************//**
+ * @brief Resets the device.
+ *
+ * @param dev - The handler of the instance of the driver.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_reset(struct ad7124_dev *dev)
+{
+ int32_t ret = 0;
+ uint8_t wr_buf[8] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+
+ if(!dev)
+ return INVALID_VAL;
+
+ ret = spi_write_and_read(dev->spi_desc,
+ wr_buf,
+ 8);
+
+ /* Wait for the reset to complete */
+ ret = ad7124_wait_to_power_on(dev,
+ dev->spi_rdy_poll_cnt);
+
+ return ret;
+}
+
+/***************************************************************************//**
+ * @brief Waits until the device can accept read and write user actions.
+ *
+ * @param dev - 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_wait_for_spi_ready(struct ad7124_dev *dev,
+ uint32_t timeout)
+{
+ struct ad7124_st_reg *regs;
+ int32_t ret;
+ int8_t ready = 0;
+
+ if(!dev)
+ return INVALID_VAL;
+
+ regs = dev->regs;
+
+ while(!ready && --timeout) {
+ /* Read the value of the Error Register */
+ ret = ad7124_read_register(dev, ®s[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 the device finishes the power-on reset operation.
+ *
+ * @param dev - 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_wait_to_power_on(struct ad7124_dev *dev,
+ uint32_t timeout)
+{
+ struct ad7124_st_reg *regs;
+ int32_t ret;
+ int8_t powered_on = 0;
+
+ if(!dev)
+ return INVALID_VAL;
+
+ regs = dev->regs;
+
+ while(!powered_on && timeout--) {
+ ret = ad7124_read_register(dev,
+ ®s[AD7124_Status]);
+ if(ret < 0)
+ return ret;
+
+ /* Check the POR_FLAG bit in the Status Register */
+ powered_on = (regs[AD7124_Status].value &
+ AD7124_STATUS_REG_POR_FLAG) == 0;
+ }
+
+ return (timeout || powered_on) ? 0 : TIMEOUT;
+}
+
+/***************************************************************************//**
+ * @brief Waits until a new conversion result is available.
+ *
+ * @param dev - 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_wait_for_conv_ready(struct ad7124_dev *dev,
+ uint32_t timeout)
+{
+ struct ad7124_st_reg *regs;
+ int32_t ret;
+ int8_t ready = 0;
+
+ if(!dev)
+ return INVALID_VAL;
+
+ regs = dev->regs;
+
+ while(!ready && --timeout) {
+ /* Read the value of the Status Register */
+ ret = ad7124_read_register(dev, ®s[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;
+ }
+
+ return timeout ? 0 : TIMEOUT;
+}
+
+/***************************************************************************//**
+ * @brief Reads the conversion result from the device.
+ *
+ * @param dev - The handler of the instance of the driver.
+ * @param p_data - Pointer to store the read data.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_read_data(struct ad7124_dev *dev,
+ int32_t* p_data)
+{
+ struct ad7124_st_reg *regs;
+ int32_t ret;
+
+ if(!dev)
+ return INVALID_VAL;
+
+ regs = dev->regs;
+
+ /* Read the value of the Status Register */
+ ret = ad7124_read_register(dev, ®s[AD7124_Data]);
+
+ /* Get the read result */
+ *p_data = regs[AD7124_Data].value;
+
+ return ret;
+}
+
+/***************************************************************************//**
+ * @brief Computes the CRC checksum for a data buffer.
+ *
+ * @param p_buf - Data buffer
+ * @param buf_size - Data buffer size in bytes
+ *
+ * @return Returns the computed CRC checksum.
+*******************************************************************************/
+uint8_t ad7124_compute_crc8(uint8_t * p_buf, uint8_t buf_size)
+{
+ uint8_t i = 0;
+ uint8_t crc = 0;
+
+ while(buf_size) {
+ for(i = 0x80; i != 0; i >>= 1) {
+ bool cmp1 = (crc & 0x80) != 0;
+ bool cmp2 = (*p_buf & i) != 0;
+ if(cmp1 != cmp2) { /* MSB of CRC register XOR input Bit from Data */
+ crc <<= 1;
+ crc ^= AD7124_CRC8_POLYNOMIAL_REPRESENTATION;
+ } else {
+ crc <<= 1;
+ }
+ }
+ p_buf++;
+ buf_size--;
+ }
+ return crc;
+}
+
+/***************************************************************************//**
+ * @brief Updates the CRC settings.
+ *
+ * @param dev - The handler of the instance of the driver.
+ *
+ * @return None.
+*******************************************************************************/
+void ad7124_update_crcsetting(struct ad7124_dev *dev)
+{
+ struct ad7124_st_reg *regs;
+
+ if(!dev)
+ return;
+
+ regs = dev->regs;
+
+ /* Get CRC State. */
+ if (regs[AD7124_Error_En].value & AD7124_ERREN_REG_SPI_CRC_ERR_EN) {
+ dev->use_crc = AD7124_USE_CRC;
+ } else {
+ dev->use_crc = AD7124_DISABLE_CRC;
+ }
+}
+
+/***************************************************************************//**
+ * @brief Updates the device SPI interface settings.
+ *
+ * @param dev - The handler of the instance of the driver.
+ *
+ * @return None.
+*******************************************************************************/
+void ad7124_update_dev_spi_settings(struct ad7124_dev *dev)
+{
+ struct ad7124_st_reg *regs;
+
+ if(!dev)
+ return;
+
+ regs = dev->regs;
+
+ if (regs[AD7124_Error_En].value & AD7124_ERREN_REG_SPI_IGNORE_ERR_EN) {
+ dev->check_ready = 1;
+ } else {
+ dev->check_ready = 0;
+ }
+}
+
+/***************************************************************************//**
+ * @brief Initializes the AD7124.
+ *
+ * @param device - The device structure.
+ * @param init_param - The structure that contains the device initial
+ * parameters.
+ *
+ * @return Returns 0 for success or negative error code.
+*******************************************************************************/
+int32_t ad7124_setup(struct ad7124_dev **device,
+ struct ad7124_init_param init_param)
+{
+ int32_t ret;
+ int reg_nr;
+ struct ad7124_dev *dev;
+
+ dev = (struct ad7124_dev *)malloc(sizeof(*dev));
+ if (!dev)
+ return INVALID_VAL;
+
+ dev->regs = init_param.regs;
+ dev->spi_rdy_poll_cnt = init_param.spi_rdy_poll_cnt;
+
+ /* Initialize the SPI communication. */
+ ret = spi_init(&dev->spi_desc, &init_param.spi_init);
+ if (ret < 0)
+ return ret;
+
+ /* Reset the device interface.*/
+ ret = ad7124_reset(dev);
+ if (ret < 0)
+ return ret;
+
+ /* Update the device structure with power-on/reset settings */
+ dev->check_ready = 1;
+
+ /* Initialize registers AD7124_ADC_Control through AD7124_Filter_7. */
+ for(reg_nr = AD7124_Status; (reg_nr < AD7124_Offset_0) && !(ret < 0);
+ reg_nr++) {
+ if (dev->regs[reg_nr].rw == AD7124_RW) {
+ ret = ad7124_write_register(dev, dev->regs[reg_nr]);
+ if (ret < 0)
+ break;
+ }
+
+ /* Get CRC State and device SPI interface settings */
+ if (reg_nr == AD7124_Error_En) {
+ ad7124_update_crcsetting(dev);
+ ad7124_update_dev_spi_settings(dev);
+ }
+ }
+
+ *device = dev;
+
+ return ret;
+}
+
+/***************************************************************************//**
+ * @brief Free the resources allocated by AD7124_Setup().
+ *
+ * @param dev - The device structure.
+ *
+ * @return SUCCESS in case of success, negative error code otherwise.
+*******************************************************************************/
+int32_t ad7124_remove(struct ad7124_dev *dev)
+{
+ int32_t ret;
+
+ ret = spi_remove(dev->spi_desc);
+
+ free(dev);
+
+ return ret;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ad7124.h Thu Sep 05 20:45:41 2019 +0000
@@ -0,0 +1,423 @@
+/***************************************************************************//**
+* @file AD7124.h
+* @brief AD7124 header file.
+* @devices AD7124-4, AD7124-8
+*
+********************************************************************************
+* Copyright 2015(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 __AD7124_H__
+#define __AD7124_H__
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+#include <stdint.h>
+#include "platform_drivers.h"
+
+/******************************************************************************/
+/******************* Register map and register definitions ********************/
+/******************************************************************************/
+
+#define AD7124_RW 1 /* Read and Write */
+#define AD7124_R 2 /* Read only */
+#define AD7124_W 3 /* Write only */
+
+/* AD7124 Register Map */
+#define AD7124_COMM_REG 0x00
+#define AD7124_STATUS_REG 0x00
+#define AD7124_ADC_CTRL_REG 0x01
+#define AD7124_DATA_REG 0x02
+#define AD7124_IO_CTRL1_REG 0x03
+#define AD7124_IO_CTRL2_REG 0x04
+#define AD7124_ID_REG 0x05
+#define AD7124_ERR_REG 0x06
+#define AD7124_ERREN_REG 0x07
+#define AD7124_CH0_MAP_REG 0x09
+#define AD7124_CH1_MAP_REG 0x0A
+#define AD7124_CH2_MAP_REG 0x0B
+#define AD7124_CH3_MAP_REG 0x0C
+#define AD7124_CH4_MAP_REG 0x0D
+#define AD7124_CH5_MAP_REG 0x0E
+#define AD7124_CH6_MAP_REG 0x0F
+#define AD7124_CH7_MAP_REG 0x10
+#define AD7124_CH8_MAP_REG 0x11
+#define AD7124_CH9_MAP_REG 0x12
+#define AD7124_CH10_MAP_REG 0x13
+#define AD7124_CH11_MAP_REG 0x14
+#define AD7124_CH12_MAP_REG 0x15
+#define AD7124_CH13_MAP_REG 0x16
+#define AD7124_CH14_MAP_REG 0x17
+#define AD7124_CH15_MAP_REG 0x18
+#define AD7124_CFG0_REG 0x19
+#define AD7124_CFG1_REG 0x1A
+#define AD7124_CFG2_REG 0x1B
+#define AD7124_CFG3_REG 0x1C
+#define AD7124_CFG4_REG 0x1D
+#define AD7124_CFG5_REG 0x1E
+#define AD7124_CFG6_REG 0x1F
+#define AD7124_CFG7_REG 0x20
+#define AD7124_FILT0_REG 0x21
+#define AD7124_FILT1_REG 0x22
+#define AD7124_FILT2_REG 0x23
+#define AD7124_FILT3_REG 0x24
+#define AD7124_FILT4_REG 0x25
+#define AD7124_FILT5_REG 0x26
+#define AD7124_FILT6_REG 0x27
+#define AD7124_FILT7_REG 0x28
+#define AD7124_OFFS0_REG 0x29
+#define AD7124_OFFS1_REG 0x2A
+#define AD7124_OFFS2_REG 0x2B
+#define AD7124_OFFS3_REG 0x2C
+#define AD7124_OFFS4_REG 0x2D
+#define AD7124_OFFS5_REG 0x2E
+#define AD7124_OFFS6_REG 0x2F
+#define AD7124_OFFS7_REG 0x30
+#define AD7124_GAIN0_REG 0x31
+#define AD7124_GAIN1_REG 0x32
+#define AD7124_GAIN2_REG 0x33
+#define AD7124_GAIN3_REG 0x34
+#define AD7124_GAIN4_REG 0x35
+#define AD7124_GAIN5_REG 0x36
+#define AD7124_GAIN6_REG 0x37
+#define AD7124_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 << 0)
+
+/* 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) (((x) & 0x7) << 21)
+#define AD7124_FILT_REG_REJ60 (1 << 20)
+#define AD7124_FILT_REG_POST_FILTER(x) (((x) & 0x7) << 17)
+#define AD7124_FILT_REG_SINGLE_CYCLE (1 << 16)
+#define AD7124_FILT_REG_FS(x) (((x) & 0x7FF) << 0)
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/*! Device register info */
+struct ad7124_st_reg {
+ int32_t addr;
+ int32_t value;
+ int32_t size;
+ int32_t rw;
+};
+
+/*! AD7124 registers list*/
+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
+};
+
+/*
+ * The structure describes the device and is used with the ad7124 driver.
+ * @spi_desc: A reference to the SPI configuration of the device.
+ * @regs: A reference to the register list of the device that the user must
+ * provide when calling the Setup() function.
+ * @userCRC: Whether to do or not a cyclic redundancy check on SPI transfers.
+ * @check_ready: When enabled all register read and write calls will first wait
+ * until the device is ready to accept user requests.
+ * @spi_rdy_poll_cnt: Number of times the driver should read the Error register
+ * to check if the device is ready to accept user requests,
+ * before a timeout error will be issued.
+ */
+struct ad7124_dev {
+ /* SPI */
+ spi_desc *spi_desc;
+ /* Device Settings */
+ struct ad7124_st_reg *regs;
+ int16_t use_crc;
+ int16_t check_ready;
+ int16_t spi_rdy_poll_cnt;
+};
+
+struct ad7124_init_param {
+ /* SPI */
+ spi_init_param spi_init;
+ /* Device Settings */
+ struct ad7124_st_reg *regs;
+ int16_t spi_rdy_poll_cnt;
+};
+
+/******************************************************************************/
+/******************* AD7124 Constants *****************************************/
+/******************************************************************************/
+#define AD7124_CRC8_POLYNOMIAL_REPRESENTATION 0x07 /* x8 + x2 + x + 1 */
+#define AD7124_DISABLE_CRC 0
+#define AD7124_USE_CRC 1
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/*! Reads the value of the specified register. */
+int32_t ad7124_read_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg* p_reg);
+
+/*! Writes the value of the specified register. */
+int32_t ad7124_write_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg reg);
+
+/*! Reads the value of the specified register without a device state check. */
+int32_t ad7124_no_check_read_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg* p_reg);
+
+/*! Writes the value of the specified register without a device state check. */
+int32_t ad7124_no_check_write_register(struct ad7124_dev *dev,
+ struct ad7124_st_reg reg);
+
+/*! Resets the device. */
+int32_t ad7124_reset(struct ad7124_dev *dev);
+
+/*! Waits until the device can accept read and write user actions. */
+int32_t ad7124_wait_for_spi_ready(struct ad7124_dev *dev,
+ uint32_t timeout);
+
+/*! Waits until the device finishes the power-on reset operation. */
+int32_t ad7124_wait_to_power_on(struct ad7124_dev *dev,
+ uint32_t timeout);
+
+/*! Waits until a new conversion result is available. */
+int32_t ad7124_wait_for_conv_ready(struct ad7124_dev *dev,
+ uint32_t timeout);
+
+/*! Reads the conversion result from the device. */
+int32_t ad7124_read_data(struct ad7124_dev *dev,
+ int32_t* p_data);
+
+/*! Computes the CRC checksum for a data buffer. */
+uint8_t ad7124_compute_crc8(uint8_t* p_buf,
+ uint8_t buf_size);
+
+/*! Updates the CRC settings. */
+void ad7124_update_crcsetting(struct ad7124_dev *dev);
+
+/*! Updates the device SPI interface settings. */
+void ad7124_update_dev_spi_settings(struct ad7124_dev *dev);
+
+/*! Initializes the AD7124. */
+int32_t ad7124_setup(struct ad7124_dev **device,
+ struct ad7124_init_param init_param);
+/*! Free the resources allocated by AD7124_Setup(). */
+int32_t ad7124_remove(struct ad7124_dev *dev);
+
+#endif /* __AD7124_H__ */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/ad7124_regs.cpp Thu Sep 05 20:45:41 2019 +0000
@@ -0,0 +1,61 @@
+#include "ad7124_regs.h"
+
+struct ad7124_st_reg ad7124_regs[AD7124_REG_NO] = {
+ {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, 0x02, 1, 2}, /* AD7124_ID */
+ {0x06, 0x0000, 3, 2}, /* AD7124_Error */
+ {0x07, 0x0040, 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 */
+};
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ad7124_regs.h Thu Sep 05 20:45:41 2019 +0000 @@ -0,0 +1,10 @@ +#ifndef __AD7124_REGS_H__ +#define __AD7124_REGS_H__ + +#include "ad7124.h" + +/*! Array holding the info for the ad7124 registers - address, initial value, + size and access type. */ +extern struct ad7124_st_reg ad7124_regs[AD7124_REG_NO]; + +#endif /* __AD7124_REGS_H__ */ \ No newline at end of file
