Example Program for EVAL-AD7606

Dependencies:   platform_drivers

Committer:
Kjansen
Date:
Tue Aug 03 11:54:49 2021 +0100
Revision:
7:054dbd5e1f45
Parent:
6:32de160dce43
Modified the ADC data capture module to remove dependancy on type of ADC and it's specific operations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mahphalke 1:819ac9aa5667 1 /***************************************************************************//**
mahphalke 1:819ac9aa5667 2 * @file ad7606_data_capture.c
mahphalke 1:819ac9aa5667 3 * @brief Data capture interface for AD7606 IIO application
mahphalke 1:819ac9aa5667 4 * @details This module handles the AD7606 data capturing
mahphalke 1:819ac9aa5667 5 ********************************************************************************
Kjansen 7:054dbd5e1f45 6 * Copyright (c) 2020-2021 Analog Devices, Inc.
mahphalke 1:819ac9aa5667 7 * All rights reserved.
mahphalke 1:819ac9aa5667 8 *
mahphalke 1:819ac9aa5667 9 * This software is proprietary to Analog Devices, Inc. and its licensors.
mahphalke 1:819ac9aa5667 10 * By using this software you agree to the terms of the associated
mahphalke 1:819ac9aa5667 11 * Analog Devices Software License Agreement.
mahphalke 1:819ac9aa5667 12 *******************************************************************************/
mahphalke 1:819ac9aa5667 13
mahphalke 1:819ac9aa5667 14 /******************************************************************************/
mahphalke 1:819ac9aa5667 15 /***************************** Include Files **********************************/
mahphalke 1:819ac9aa5667 16 /******************************************************************************/
mahphalke 1:819ac9aa5667 17
mahphalke 1:819ac9aa5667 18 #include <string.h>
mahphalke 1:819ac9aa5667 19 #include <stdlib.h>
mahphalke 1:819ac9aa5667 20
mahphalke 1:819ac9aa5667 21 #include "app_config.h"
mahphalke 1:819ac9aa5667 22 #include "ad7606_data_capture.h"
Kjansen 7:054dbd5e1f45 23 #include "iio_ad7606.h"
mahphalke 1:819ac9aa5667 24 #include "ad7606_support.h"
Kjansen 7:054dbd5e1f45 25 #include "error.h"
Kjansen 7:054dbd5e1f45 26 #include "adc_data_capture.h"
mahphalke 1:819ac9aa5667 27
mahphalke 1:819ac9aa5667 28 /******************************************************************************/
mahphalke 1:819ac9aa5667 29 /********************** Macros and Constants Definition ***********************/
mahphalke 1:819ac9aa5667 30 /******************************************************************************/
mahphalke 1:819ac9aa5667 31
Kjansen 7:054dbd5e1f45 32 #if (AD7606X_ADC_RESOLUTION == 18)
Kjansen 7:054dbd5e1f45 33 #define SAMPLE_SIZE_IN_BYTE 3
mahphalke 1:819ac9aa5667 34 #else
Kjansen 7:054dbd5e1f45 35 #define SAMPLE_SIZE_IN_BYTE 2
mahphalke 1:819ac9aa5667 36 #endif
mahphalke 1:819ac9aa5667 37
mahphalke 1:819ac9aa5667 38 /******************************************************************************/
mahphalke 1:819ac9aa5667 39 /********************** Variables and User Defined Data Types *****************/
mahphalke 1:819ac9aa5667 40 /******************************************************************************/
mahphalke 1:819ac9aa5667 41
Kjansen 7:054dbd5e1f45 42 /* Polarity of channels */
Kjansen 7:054dbd5e1f45 43 static polarity_e polarity[AD7606X_ADC_CHANNELS];
mahphalke 1:819ac9aa5667 44
mahphalke 1:819ac9aa5667 45 /******************************************************************************/
mahphalke 1:819ac9aa5667 46 /************************ Functions Declarations ******************************/
mahphalke 1:819ac9aa5667 47 /******************************************************************************/
mahphalke 1:819ac9aa5667 48
Kjansen 7:054dbd5e1f45 49 /* Perform conversion on input channel and read single conversion sample */
Kjansen 7:054dbd5e1f45 50 static int32_t ad7606_perform_conv_and_read_sample(uint32_t *adc_data,
Kjansen 7:054dbd5e1f45 51 uint8_t chn);
Kjansen 7:054dbd5e1f45 52
Kjansen 7:054dbd5e1f45 53 /* Perform continuous sample read pre-operations */
Kjansen 7:054dbd5e1f45 54 static int32_t ad7606_continuous_sample_read_start_ops(uint32_t ch_mask);
Kjansen 7:054dbd5e1f45 55
Kjansen 7:054dbd5e1f45 56 /* Read ADC sampled/conversion data */
Kjansen 7:054dbd5e1f45 57 static int32_t ad7606_read_converted_sample(uint32_t *adc_data,
Kjansen 7:054dbd5e1f45 58 uint8_t input_chn);
Kjansen 7:054dbd5e1f45 59
Kjansen 7:054dbd5e1f45 60 /* Trigger next ADC conversion */
Kjansen 7:054dbd5e1f45 61 static int32_t ad7606_trigger_next_conversion(void);
Kjansen 7:054dbd5e1f45 62
Kjansen 7:054dbd5e1f45 63 /* Define the variable for data_capture_ops structure */
Kjansen 7:054dbd5e1f45 64 struct data_capture_ops data_capture_ops = {
Kjansen 7:054dbd5e1f45 65 /* Point AD7606 data capture functions to generic ADC data capture functions */
Kjansen 7:054dbd5e1f45 66 .single_sample_read_start_ops = NULL,
Kjansen 7:054dbd5e1f45 67 .perform_conv_and_read_sample = ad7606_perform_conv_and_read_sample,
Kjansen 7:054dbd5e1f45 68 .single_sample_read_stop_ops = NULL,
Kjansen 7:054dbd5e1f45 69 .continuous_sample_read_start_ops = ad7606_continuous_sample_read_start_ops,
Kjansen 7:054dbd5e1f45 70 .read_converted_sample = ad7606_read_converted_sample,
Kjansen 7:054dbd5e1f45 71 .continuous_sample_read_stop_ops = NULL,
Kjansen 7:054dbd5e1f45 72 .trigger_next_conversion = ad7606_trigger_next_conversion
Kjansen 7:054dbd5e1f45 73 };
mahphalke 1:819ac9aa5667 74
mahphalke 1:819ac9aa5667 75 /******************************************************************************/
mahphalke 1:819ac9aa5667 76 /************************ Functions Definitions *******************************/
mahphalke 1:819ac9aa5667 77 /******************************************************************************/
mahphalke 1:819ac9aa5667 78
mahphalke 1:819ac9aa5667 79 /*!
Kjansen 7:054dbd5e1f45 80 * @brief Remove the offset from data to change output data format to
Kjansen 7:054dbd5e1f45 81 * normal or stright binary representation (needed for IIO client)
Kjansen 7:054dbd5e1f45 82 * @param adc_raw[out] - Pointer to adc data read variable
Kjansen 7:054dbd5e1f45 83 * @param bipolar[in] - Channel polarity
Kjansen 7:054dbd5e1f45 84 * @return SUCCESS in case of success, FAILURE otherwise
mahphalke 1:819ac9aa5667 85 */
Kjansen 7:054dbd5e1f45 86 static int32_t reformat_adc_raw_data(uint32_t adc_raw_data, polarity_e polarity)
mahphalke 1:819ac9aa5667 87 {
Kjansen 7:054dbd5e1f45 88 int32_t adc_data;
mahphalke 1:819ac9aa5667 89
Kjansen 7:054dbd5e1f45 90 /* Bipolar ADC Range: (-FS) <-> 0 <-> (+FS) : 2^(ADC_RES-1) <-> 0 <-> 2^(ADC_RES-1)-1
Kjansen 7:054dbd5e1f45 91 Unipolar ADC Range: 0 <-> (+FS) : 0 <-> 2^ADC_RES
Kjansen 7:054dbd5e1f45 92 **/
mahphalke 1:819ac9aa5667 93 if (polarity == BIPOLAR) {
Kjansen 7:054dbd5e1f45 94 /* Data output format is 2's complement for bipolar mode */
Kjansen 7:054dbd5e1f45 95 if (adc_raw_data > ADC_MAX_COUNT_BIPOLAR) {
Kjansen 7:054dbd5e1f45 96 /* Remove the offset from result to convert into negative reading */
Kjansen 7:054dbd5e1f45 97 adc_data = ADC_MAX_COUNT_UNIPOLAR - adc_raw_data;
Kjansen 7:054dbd5e1f45 98 adc_data = -adc_data;
mahphalke 1:819ac9aa5667 99 } else {
Kjansen 7:054dbd5e1f45 100 adc_data = adc_raw_data;
mahphalke 1:819ac9aa5667 101 }
mahphalke 1:819ac9aa5667 102 } else {
Kjansen 7:054dbd5e1f45 103 /* Data output format is straight binary for unipolar mode */
Kjansen 7:054dbd5e1f45 104 adc_data = adc_raw_data;
mahphalke 1:819ac9aa5667 105 }
mahphalke 1:819ac9aa5667 106
mahphalke 1:819ac9aa5667 107 return adc_data;
mahphalke 1:819ac9aa5667 108 }
mahphalke 1:819ac9aa5667 109
mahphalke 1:819ac9aa5667 110
mahphalke 1:819ac9aa5667 111 /*!
Kjansen 7:054dbd5e1f45 112 * @brief Perform conversion and read conversion sample
Kjansen 7:054dbd5e1f45 113 * @param adc_data[out] - Pointer to adc data read variable
Kjansen 7:054dbd5e1f45 114 * @param chn[in] - Channel for which data is to read
Kjansen 7:054dbd5e1f45 115 * @return SUCCESS in case of success, FAILURE otherwise
mahphalke 1:819ac9aa5667 116 */
Kjansen 7:054dbd5e1f45 117 int32_t ad7606_perform_conv_and_read_sample(uint32_t *adc_data, uint8_t chn)
mahphalke 1:819ac9aa5667 118 {
Kjansen 7:054dbd5e1f45 119 uint32_t adc_raw[AD7606X_ADC_CHANNELS] = { 0 };
Kjansen 7:054dbd5e1f45 120 uint8_t read_val;
Kjansen 7:054dbd5e1f45 121 uint8_t chn_range;
Kjansen 7:054dbd5e1f45 122 polarity_e polarity;
mahphalke 1:819ac9aa5667 123
Kjansen 7:054dbd5e1f45 124 /* Get input channel range */
Kjansen 7:054dbd5e1f45 125 if (ad7606_spi_reg_read(p_ad7606_dev_inst,
Kjansen 7:054dbd5e1f45 126 AD7606_REG_RANGE_CH_ADDR(chn),
Kjansen 7:054dbd5e1f45 127 &read_val) != SUCCESS) {
Kjansen 7:054dbd5e1f45 128 return FAILURE;
mahphalke 1:819ac9aa5667 129 }
mahphalke 1:819ac9aa5667 130
Kjansen 7:054dbd5e1f45 131 if (((chn) % 2) != 0) {
Kjansen 7:054dbd5e1f45 132 read_val >>= CHANNEL_RANGE_MSK_OFFSET;
Kjansen 7:054dbd5e1f45 133 chn_range = read_val;
Kjansen 7:054dbd5e1f45 134 } else {
Kjansen 7:054dbd5e1f45 135 chn_range = (read_val & AD7606_RANGE_CH_MSK(chn));
mahphalke 1:819ac9aa5667 136 }
mahphalke 1:819ac9aa5667 137
Kjansen 7:054dbd5e1f45 138 /* Get polarity based on input channel range */
Kjansen 7:054dbd5e1f45 139 polarity = ad7606_get_input_polarity(chn_range);
mahphalke 1:819ac9aa5667 140
Kjansen 7:054dbd5e1f45 141 /* This function monitors BUSY line for EOC and read ADC result post that */
Kjansen 7:054dbd5e1f45 142 if (ad7606_read(p_ad7606_dev_inst, adc_raw) != SUCCESS) {
Kjansen 7:054dbd5e1f45 143 adc_raw[chn] = 0;
mahphalke 1:819ac9aa5667 144 }
mahphalke 1:819ac9aa5667 145
Kjansen 7:054dbd5e1f45 146 *adc_data = reformat_adc_raw_data(adc_raw[chn], polarity);
Kjansen 7:054dbd5e1f45 147
Kjansen 7:054dbd5e1f45 148 return SUCCESS;
mahphalke 1:819ac9aa5667 149 }
mahphalke 1:819ac9aa5667 150
mahphalke 1:819ac9aa5667 151
mahphalke 1:819ac9aa5667 152 /*!
Kjansen 7:054dbd5e1f45 153 * @brief Perform the operations required before starting continuous sample read
Kjansen 7:054dbd5e1f45 154 * @param chn_mask[in] - active channels list received from IIO client
Kjansen 7:054dbd5e1f45 155 * @return SUCCESS in case of success, FAILURE otherwise
mahphalke 1:819ac9aa5667 156 */
Kjansen 7:054dbd5e1f45 157 int32_t ad7606_continuous_sample_read_start_ops(uint32_t chn_mask)
mahphalke 1:819ac9aa5667 158 {
Kjansen 7:054dbd5e1f45 159 uint8_t read_val;
Kjansen 7:054dbd5e1f45 160 uint8_t chn_range;
mahphalke 1:819ac9aa5667 161
Kjansen 7:054dbd5e1f45 162 for (uint8_t chn = 0; chn < AD7606X_ADC_CHANNELS; chn++) {
Kjansen 7:054dbd5e1f45 163 /* Store the channels polarity */
Kjansen 7:054dbd5e1f45 164 if (ad7606_spi_reg_read(p_ad7606_dev_inst,
Kjansen 7:054dbd5e1f45 165 AD7606_REG_RANGE_CH_ADDR(chn),
Kjansen 7:054dbd5e1f45 166 &read_val) == SUCCESS) {
Kjansen 7:054dbd5e1f45 167 if (((chn) % 2) != 0) {
Kjansen 7:054dbd5e1f45 168 read_val >>= CHANNEL_RANGE_MSK_OFFSET;
Kjansen 7:054dbd5e1f45 169 chn_range = read_val;
Kjansen 7:054dbd5e1f45 170 } else {
Kjansen 7:054dbd5e1f45 171 chn_range = (read_val & AD7606_RANGE_CH_MSK(chn));
mahphalke 1:819ac9aa5667 172 }
mahphalke 1:819ac9aa5667 173
Kjansen 7:054dbd5e1f45 174 polarity[chn] = ad7606_get_input_polarity(chn_range);
mahphalke 1:819ac9aa5667 175 }
mahphalke 1:819ac9aa5667 176 }
Kjansen 7:054dbd5e1f45 177
Kjansen 7:054dbd5e1f45 178 /* Trigger first conversion */
Kjansen 7:054dbd5e1f45 179 return ad7606_trigger_next_conversion();
mahphalke 1:819ac9aa5667 180 }
mahphalke 1:819ac9aa5667 181
mahphalke 1:819ac9aa5667 182
mahphalke 1:819ac9aa5667 183 /*!
Kjansen 7:054dbd5e1f45 184 * @brief Read ADC raw data for recently sampled channel
Kjansen 7:054dbd5e1f45 185 * @param adc_data[out] - Pointer to adc data read variable
Kjansen 7:054dbd5e1f45 186 * @param input_chn[in] - Input channel
Kjansen 7:054dbd5e1f45 187 * @return SUCCESS in case of success, FAILURE otherwise
Kjansen 7:054dbd5e1f45 188 * @note This function is intended to call from the conversion end trigger
Kjansen 7:054dbd5e1f45 189 * event. Therefore, this function should just read raw ADC data
Kjansen 7:054dbd5e1f45 190 * without further monitoring conversion end event
mahphalke 1:819ac9aa5667 191 */
Kjansen 7:054dbd5e1f45 192 int32_t ad7606_read_converted_sample(uint32_t *adc_data,
Kjansen 7:054dbd5e1f45 193 uint8_t input_chn)
mahphalke 1:819ac9aa5667 194 {
Kjansen 7:054dbd5e1f45 195 uint32_t adc_raw;
Kjansen 7:054dbd5e1f45 196 uint8_t bytes_to_read;
Kjansen 7:054dbd5e1f45 197 uint8_t buffer_offset;
mahphalke 1:819ac9aa5667 198
Kjansen 7:054dbd5e1f45 199 if (!adc_data) {
Kjansen 7:054dbd5e1f45 200 return FAILURE;
mahphalke 1:819ac9aa5667 201 }
mahphalke 1:819ac9aa5667 202
Kjansen 7:054dbd5e1f45 203 /* Get number of bytes to read count = chn_cnt * bytes per sample */
Kjansen 7:054dbd5e1f45 204 bytes_to_read = AD7606X_ADC_CHANNELS * SAMPLE_SIZE_IN_BYTE;
Kjansen 7:054dbd5e1f45 205 buffer_offset = input_chn * SAMPLE_SIZE_IN_BYTE;
Kjansen 7:054dbd5e1f45 206
Kjansen 7:054dbd5e1f45 207 /* Read data over spi interface for all ADC channels */
Kjansen 7:054dbd5e1f45 208 memset(p_ad7606_dev_inst->data, 0, sizeof(p_ad7606_dev_inst->data));
Kjansen 7:054dbd5e1f45 209 spi_write_and_read(p_ad7606_dev_inst->spi_desc,
Kjansen 7:054dbd5e1f45 210 p_ad7606_dev_inst->data, bytes_to_read);
Kjansen 7:054dbd5e1f45 211
Kjansen 7:054dbd5e1f45 212 #if (AD7606X_ADC_RESOLUTION == 18)
Kjansen 7:054dbd5e1f45 213 adc_raw =
Kjansen 7:054dbd5e1f45 214 (((uint32_t)p_ad7606_dev_inst->data[buffer_offset] << 16) | // MSB
Kjansen 7:054dbd5e1f45 215 ((uint32_t)p_ad7606_dev_inst->data[buffer_offset + 1] << 8) |
Kjansen 7:054dbd5e1f45 216 ((uint32_t)p_ad7606_dev_inst->data[buffer_offset + 2])); // LSB
Kjansen 7:054dbd5e1f45 217 #else
Kjansen 7:054dbd5e1f45 218 adc_raw =
Kjansen 7:054dbd5e1f45 219 (uint16_t)(((uint16_t)p_ad7606_dev_inst->data[buffer_offset] << 8) | // MSB
Kjansen 7:054dbd5e1f45 220 p_ad7606_dev_inst->data[buffer_offset + 1]); // LSB
Kjansen 7:054dbd5e1f45 221 #endif
Kjansen 7:054dbd5e1f45 222
Kjansen 7:054dbd5e1f45 223 *adc_data = reformat_adc_raw_data(adc_raw, polarity[input_chn]);
Kjansen 7:054dbd5e1f45 224
Kjansen 7:054dbd5e1f45 225 return SUCCESS;
mahphalke 1:819ac9aa5667 226 }
mahphalke 1:819ac9aa5667 227
mahphalke 1:819ac9aa5667 228
mahphalke 1:819ac9aa5667 229 /*!
Kjansen 7:054dbd5e1f45 230 * @brief Trigger next ADC conversion
Kjansen 7:054dbd5e1f45 231 * @return SUCCESS in case of success, FAILURE otherwise
mahphalke 1:819ac9aa5667 232 */
Kjansen 7:054dbd5e1f45 233 int32_t ad7606_trigger_next_conversion(void)
mahphalke 1:819ac9aa5667 234 {
Kjansen 7:054dbd5e1f45 235 if (ad7606_convst(p_ad7606_dev_inst) != SUCCESS) {
Kjansen 7:054dbd5e1f45 236 return FAILURE;
Kjansen 7:054dbd5e1f45 237 }
mahphalke 1:819ac9aa5667 238
Kjansen 7:054dbd5e1f45 239 return SUCCESS;
mahphalke 1:819ac9aa5667 240 }