AD7124 no-OS library files
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
diff -r d18c9afa4bcb -r 22ed45e195a9 AD7124_no_OS.cpp
diff -r d18c9afa4bcb -r 22ed45e195a9 AD7124_no_OS.h
diff -r d18c9afa4bcb -r 22ed45e195a9 ad7124.cpp --- /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
diff -r d18c9afa4bcb -r 22ed45e195a9 ad7124.h --- /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
diff -r d18c9afa4bcb -r 22ed45e195a9 ad7124_regs.cpp --- /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
diff -r d18c9afa4bcb -r 22ed45e195a9 ad7124_regs.h --- /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