Forked repository for pushing changes to EVAL-AD4696
Dependencies: platform_drivers
Diff: app/ad469x.h
- Revision:
- 1:8792acb5a039
diff -r 721af8bb4b69 -r 8792acb5a039 app/ad469x.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad469x.h Thu Sep 30 11:01:05 2021 +0530 @@ -0,0 +1,370 @@ +/***************************************************************************//** + * @file ad469x.h + * @brief Header file for ad469x Driver. + * @author Cristian Pop (cristian.pop@analog.com) +******************************************************************************** + * Copyright 2021(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 SRC_AD469X_H_ +#define SRC_AD469X_H_ + +// **** Note for User: SPI Standard/Engine selection **** // +/* By default the Standard SPI protocol is used for communicating with eval board. + * Uncomment the "ENABLE_SPI_ENGINE" macro to enable the SPI engine controller + * framework. + * */ +//#define ENABLE_SPI_ENGINE + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include <stdlib.h> +#include <stdbool.h> + +#if defined(ENABLE_SPI_ENGINE) +#include "spi_engine.h" +#include "clk_axi_clkgen.h" +#include "pwm.h" +#else +#include "spi.h" +#endif + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ +/* AD469x registers */ +#define AD469x_REG_IF_CONFIG_A 0x000 +#define AD469x_REG_IF_CONFIG_B 0x001 +#define AD469x_REG_DEVICE_TYPE 0x003 +#define AD469x_REG_DEVICE_ID_L 0x004 +#define AD469x_REG_DEVICE_ID_H 0x005 +#define AD469x_REG_SCRATCH_PAD 0x00A +#define AD469x_REG_VENDOR_L 0x00C +#define AD469x_REG_VENDOR_H 0x00D +#define AD469x_REG_LOOP_MODE 0x00E +#define AD469x_REG_IF_CONFIG_C 0x010 +#define AD469x_REG_IF_STATUS 0x011 +#define AD469x_REG_STATUS 0x014 +#define AD469x_REG_ALERT_STATUS1 0x015 +#define AD469x_REG_ALERT_STATUS2 0x016 +#define AD469x_REG_ALERT_STATUS3 0x017 +#define AD469x_REG_ALERT_STATUS4 0x018 +#define AD469x_REG_CLAMP_STATUS1 0x01A +#define AD469x_REG_CLAMP_STATUS2 0x01B +#define AD469x_REG_SETUP 0x020 +#define AD469x_REG_REF_CTRL 0x021 +#define AD469x_REG_SEQ_CTRL 0x022 +#define AD469x_REG_AC_CTRL 0x023 +#define AD469x_REG_STD_SEQ_CONFIG 0x024 +#define AD469x_REG_GPIO_CTRL 0x026 +#define AD469x_REG_GP_MODE 0x027 +#define AD469x_REG_GPIO_STATE 0x028 +#define AD469x_REG_TEMP_CTRL 0x029 +#define AD469x_REG_CONFIG_IN(x) ((x & 0x0F) | 0x30) +#define AD469x_REG_AS_SLOT(x) ((x & 0x7F) | 0x100) + +/* 5-bit SDI Conversion Mode Commands */ +#define AD469x_CMD_REG_CONFIG_MODE (0x0A << 3) +#define AD469x_CMD_SEL_TEMP_SNSOR_CH (0x0F << 3) +#define AD469x_CMD_CONFIG_CH_SEL(x) ((0x10 | (0x0F & x)) << 3) + +/* AD469x_REG_SETUP */ +#define AD469x_SETUP_IF_MODE_MASK (0x01 << 2) +#define AD469x_SETUP_IF_MODE_CONV (0x01 << 2) +#define AD469x_SETUP_CYC_CTRL_MASK (0x01 << 1) +#define AD469x_SETUP_CYC_CTRL_SINGLE(x) ((x & 0x01) << 1) +//Changed +#define AD469x_SETUP_STATUSBIT_MODE_MASK (0x01 << 5) +#define AD469x_SETUP_STATUSBIT_MODE_CONV (0x01 << 5) + +/* AD469x_REG_GP_MODE */ +#define AD469x_GP_MODE_BUSY_GP_EN_MASK (0x01 << 1) +#define AD469x_GP_MODE_BUSY_GP_EN(x) ((x & 0x01) << 1) +#define AD469x_GP_MODE_BUSY_GP_SEL_MASK (0x01 << 4) +#define AD469x_GP_MODE_BUSY_GP_SEL(x) ((x & 0x01) << 4) + +/* AD469x_REG_SEQ_CTRL */ +#define AD469x_SEQ_CTRL_STD_SEQ_EN_MASK (0x01 << 7) +#define AD469x_SEQ_CTRL_STD_SEQ_EN(x) ((x & 0x01) << 7) +#define AD469x_SEQ_CTRL_NUM_SLOTS_AS_MASK (0x7f << 0) +#define AD469x_SEQ_CTRL_NUM_SLOTS_AS(x) ((x & 0x7f) << 0) + +/* AD469x_REG_TEMP_CTRL */ +#define AD469x_REG_TEMP_CTRL_TEMP_EN_MASK (0x01 << 0) +#define AD469x_REG_TEMP_CTRL_TEMP_EN(x) ((x & 0x01) << 0) + +/* AD469x_REG_AS_SLOT */ +#define AD469x_REG_AS_SLOT_INX(x) ((x & 0x0f) << 0) + +/* AD469x_REG_IF_CONFIG_C */ +#define AD469x_REG_IF_CONFIG_C_MB_STRICT_MASK (0x01 << 5) +#define AD469x_REG_IF_CONFIG_C_MB_STRICT(x) ((x & 0x01) << 5) + +/* AD469x_REG_CONFIG_INn */ +#define AD469x_REG_CONFIG_IN_OSR_MASK (0x03 << 0) +#define AD469x_REG_CONFIG_IN_OSR(x) ((x & 0x03) << 0) +#define AD469x_REG_CONFIG_IN_HIZ_EN_MASK (0x01 << 3) +#define AD469x_REG_CONFIG_IN_HIZ_EN(x) ((x & 0x01) << 3) +#define AD469x_REG_CONFIG_IN_PAIR_MASK (0x03 << 4) +#define AD469x_REG_CONFIG_IN_PAIR(x) ((x & 0x03) << 4) +#define AD469x_REG_CONFIG_IN_MODE_MASK (0x01 << 6) +#define AD469x_REG_CONFIG_IN_MODE(x) ((x & 0x01) << 6) +#define AD469x_REG_CONFIG_IN_TD_EN_MASK (0x01 << 7) +#define AD469x_REG_CONFIG_IN_TD_EN(x) ((x & 0x01) << 7) + +#define AD469x_CHANNEL(x) (BIT(x) & 0xFFFF) +#define AD469x_CHANNEL_NO 16 +#define AD469x_SLOTS_NO 0x80 +#define AD469x_CHANNEL_TEMP 16 + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ +/** + * @enum ad469x_channel_sequencing + * @brief Channel sequencing modes + */ +enum ad469x_channel_sequencing { + /** Single cycle read */ + AD469x_single_cycle, + /** Two cycle read */ + AD469x_two_cycle, + /** Sequence trough channels, standard mode */ + AD469x_standard_seq, + /** Sequence trough channels, advanced mode */ + AD469x_advanced_seq, +}; + +/** + * @enum ad469x_busy_gp_sel + * @brief Busy state, possible general purpose pin selections + */ +enum ad469x_busy_gp_sel { + /** Busy on gp0 */ + AD469x_busy_gp0 = 0, + /** Busy on gp3 */ + AD469x_busy_gp3 = 1, +}; + +/** + * @enum ad469x_reg_access + * @brief Register access modes + */ +enum ad469x_reg_access { + AD469x_BYTE_ACCESS, + AD469x_WORD_ACCESS, +}; + +/** + * @enum ad469x_supported_dev_ids + * @brief Supported devices + */ +enum ad469x_supported_dev_ids { + ID_AD4695, + ID_AD4696, + ID_AD4697, +}; + +/** + * @enum ad469x_osr_ratios + * @brief Supported oversampling ratios + */ +enum ad469x_osr_ratios { + AD469x_OSR_1, + AD469x_OSR_4, + AD469x_OSR_16, + AD469x_OSR_64 +}; + +/** + * @struct ad469x_init_param + * @brief Structure containing the init parameters needed by the ad469x device + */ +struct ad469x_init_param { + /* SPI */ + spi_init_param *spi_init; + /* SPI module offload init */ + struct spi_engine_offload_init_param *offload_init_param; + /* PWM generator init structure */ + struct pwm_init_param *trigger_pwm_init; + /** RESET GPIO initialization structure. */ + struct gpio_init_param *gpio_resetn; + //gpio_init_param * gpio_resetn; + /** CONVST GPIO initialization parameters */ + struct gpio_init_param *gpio_convst; + /** BUSY GPIO initialization parameters */ + struct gpio_init_param *gpio_busy; + /* Clock gen for hdl design init structure */ + struct axi_clkgen_init *clkgen_init; + /* Clock generator rate */ + uint32_t axi_clkgen_rate; + /* Register access speed */ + uint32_t reg_access_speed; + /* Register data width */ + uint8_t reg_data_width; + /* Capture data width */ + uint8_t capture_data_width; + /* Device Settings */ + enum ad469x_supported_dev_ids dev_id; + /** Invalidate the Data cache for the given address range */ + void(*dcache_invalidate_range)(uint32_t address, uint32_t bytes_count); +}; + +/** + * @struct ad469x_dev + * @brief Structure representing an ad469x device + */ +struct ad469x_dev { + /* SPI descriptor */ + spi_desc *spi_desc; + /* Clock gen for hdl design structure */ + struct axi_clkgen *clkgen; + /* Trigger conversion PWM generator descriptor */ + struct pwm_desc *trigger_pwm_desc; + /* SPI module offload init */ + struct spi_engine_offload_init_param *offload_init_param; + /* Register access speed */ + uint32_t reg_access_speed; + /* Register data width */ + uint8_t reg_data_width; + /* Capture data width */ + uint8_t capture_data_width; + /* Device Settings */ + enum ad469x_supported_dev_ids dev_id; + /** RESET GPIO handler. */ + struct gpio_desc *gpio_resetn; + /** CONVST GPIO descriptor */ + struct gpio_desc *gpio_convst; + /** BUSY GPIO descriptor */ + struct gpio_desc *gpio_busy; + /** Invalidate the Data cache for the given address range */ + void(*dcache_invalidate_range)(uint32_t address, uint32_t bytes_count); + /** Current channel sequence */ + enum ad469x_channel_sequencing ch_sequence; + /** OSR resolution corresponding to each channel, when advanced + * sequencer is selected. */ + enum ad469x_osr_ratios adv_seq_osr_resol[AD469x_CHANNEL_NO]; + /** Channel slots for advanced sequencer */ + uint8_t ch_slots[AD469x_SLOTS_NO]; + /** Temperature enabled for standard and advanced sequencer if set. */ + bool temp_enabled; + /** Number of active channel slots, for advanced sequencer */ + uint8_t num_slots; + /* Buffer to store the conv result */ + uint8_t data[16]; +}; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ +/* Read device register. */ +int32_t ad469x_spi_reg_read(struct ad469x_dev *dev, + uint16_t reg_addr, + uint8_t *reg_data); + +/* Write device register */ +int32_t ad469x_spi_reg_write(struct ad469x_dev *dev, + uint16_t reg_addr, + uint8_t reg_data); + +/* Read from device using a mask */ +int32_t ad469x_spi_read_mask(struct ad469x_dev *dev, + uint16_t reg_addr, + uint8_t mask, + uint8_t *data); + +/* Write to device using a mask */ +int32_t ad469x_spi_write_mask(struct ad469x_dev *dev, + uint16_t reg_addr, + uint8_t mask, + uint8_t data); + +/* Read data from device */ +int32_t ad469x_read_data(struct ad469x_dev *dev, + uint8_t channel, + uint32_t *buf, + uint16_t samples); + +/* Read from device when converter has the channel sequencer activated */ +int32_t ad469x_seq_read_data(struct ad469x_dev *dev, + uint32_t *buf, + uint16_t samples); + +/* Set channel sequence */ +int32_t ad469x_set_channel_sequence(struct ad469x_dev *dev, + enum ad469x_channel_sequencing seq); + +/* Configure standard sequencer enabled channels */ +int32_t ad469x_std_sequence_ch(struct ad469x_dev *dev, + uint32_t ch_mask); + +/* Configure advanced sequencer number of slots */ +int32_t ad469x_adv_sequence_set_num_slots(struct ad469x_dev *dev, + uint8_t num_slots); + +/* Advanced sequencer, assign channel to a slot */ +int32_t ad469x_adv_sequence_set_slot(struct ad469x_dev *dev, + uint8_t slot, + uint8_t channel); + +/* Enable temperature read at the end of the sequence, for standard and */ +int32_t ad469x_sequence_enable_temp(struct ad469x_dev *dev); + +/* Disable temperature read at the end of the sequence, for standard and */ +int32_t ad469x_sequence_disable_temp(struct ad469x_dev *dev); + +/* Configure over sampling ratio in advanced sequencer mode */ +int32_t ad469x_adv_seq_osr(struct ad469x_dev *dev, + uint16_t ch, + enum ad469x_osr_ratios ratio); + +/* Configure over sampling ratio in standard sequencer mode */ +int32_t ad469x_std_seq_osr(struct ad469x_dev *dev, + enum ad469x_osr_ratios ratio); + +/* Enter conversion mode */ +int32_t ad469x_enter_conversion_mode(struct ad469x_dev *dev); + +/* Exit conversion mode */ +int32_t ad469x_exit_conversion_mode(struct ad469x_dev *dev); + +/* Initialize the device. */ +int32_t ad469x_init(struct ad469x_dev **device, + struct ad469x_init_param *init_param); + +/* Remove the device and release resources. */ +int32_t ad469x_remove(struct ad469x_dev *dev); + +#endif /* SRC_AD469X_H_ */ \ No newline at end of file