Example Program for EVAL-AD7606
Dependencies: platform_drivers
app/ad7606_data_capture.c@7:054dbd5e1f45, 2021-08-03 (annotated)
- 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?
User | Revision | Line number | New 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 | } |