Example Program for EVAL-AD7606

Dependencies:   platform_drivers

Committer:
mahphalke
Date:
Mon Oct 05 13:45:15 2020 +0530
Revision:
1:819ac9aa5667
Child:
3:83b3133f544a
AD7606 IIO Application- Initial Revision

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 ********************************************************************************
mahphalke 1:819ac9aa5667 6 * Copyright (c) 2020 Analog Devices, Inc.
mahphalke 1:819ac9aa5667 7 *
mahphalke 1:819ac9aa5667 8 * All rights reserved.
mahphalke 1:819ac9aa5667 9 *
mahphalke 1:819ac9aa5667 10 * This software is proprietary to Analog Devices, Inc. and its licensors.
mahphalke 1:819ac9aa5667 11 * By using this software you agree to the terms of the associated
mahphalke 1:819ac9aa5667 12 * Analog Devices Software License Agreement.
mahphalke 1:819ac9aa5667 13 *******************************************************************************/
mahphalke 1:819ac9aa5667 14
mahphalke 1:819ac9aa5667 15 /******************************************************************************/
mahphalke 1:819ac9aa5667 16 /***************************** Include Files **********************************/
mahphalke 1:819ac9aa5667 17 /******************************************************************************/
mahphalke 1:819ac9aa5667 18
mahphalke 1:819ac9aa5667 19 #include <string.h>
mahphalke 1:819ac9aa5667 20 #include <stdlib.h>
mahphalke 1:819ac9aa5667 21
mahphalke 1:819ac9aa5667 22 #include "app_config.h"
mahphalke 1:819ac9aa5667 23 #include "ad7606_data_capture.h"
mahphalke 1:819ac9aa5667 24 #include "ad7606_support.h"
mahphalke 1:819ac9aa5667 25 #include "gpio_extra.h"
mahphalke 1:819ac9aa5667 26
mahphalke 1:819ac9aa5667 27 /******************************************************************************/
mahphalke 1:819ac9aa5667 28 /********************** Macros and Constants Definition ***********************/
mahphalke 1:819ac9aa5667 29 /******************************************************************************/
mahphalke 1:819ac9aa5667 30
mahphalke 1:819ac9aa5667 31 #if (AD7606X_ADC_RESOLUTION > 16)
mahphalke 1:819ac9aa5667 32 #define BYTES_PER_SAMPLE sizeof(uint32_t)
mahphalke 1:819ac9aa5667 33 #else
mahphalke 1:819ac9aa5667 34 #define BYTES_PER_SAMPLE sizeof(uint16_t)
mahphalke 1:819ac9aa5667 35 #endif
mahphalke 1:819ac9aa5667 36
mahphalke 1:819ac9aa5667 37 /* Max size of the acquisition buffer (in terms of samples) */
mahphalke 1:819ac9aa5667 38 #define DATA_BUFFER_SIZE (8192)
mahphalke 1:819ac9aa5667 39
mahphalke 1:819ac9aa5667 40 /******************************************************************************/
mahphalke 1:819ac9aa5667 41 /********************** Variables and User Defined Data Types *****************/
mahphalke 1:819ac9aa5667 42 /******************************************************************************/
mahphalke 1:819ac9aa5667 43
mahphalke 1:819ac9aa5667 44 /* Device instance for background adc conversion callback */
mahphalke 1:819ac9aa5667 45 static volatile struct ad7606_dev *dev = NULL;
mahphalke 1:819ac9aa5667 46
mahphalke 1:819ac9aa5667 47 /*
mahphalke 1:819ac9aa5667 48 *@enum acq_buffer_state_e
mahphalke 1:819ac9aa5667 49 *@details Enum holding the data acquisition buffer states
mahphalke 1:819ac9aa5667 50 **/
mahphalke 1:819ac9aa5667 51 typedef enum {
mahphalke 1:819ac9aa5667 52 BUF_EMPTY,
mahphalke 1:819ac9aa5667 53 BUF_AVAILABLE,
mahphalke 1:819ac9aa5667 54 BUF_FULL
mahphalke 1:819ac9aa5667 55 } acq_buffer_state_e;
mahphalke 1:819ac9aa5667 56
mahphalke 1:819ac9aa5667 57 /*
mahphalke 1:819ac9aa5667 58 *@struct acq_buf_t
mahphalke 1:819ac9aa5667 59 *@details Structure holding the data acquisition buffer parameters
mahphalke 1:819ac9aa5667 60 **/
mahphalke 1:819ac9aa5667 61 typedef struct {
mahphalke 1:819ac9aa5667 62 acq_buffer_state_e state; // buffer state
mahphalke 1:819ac9aa5667 63 uint32_t rd_indx; // buffer read index
mahphalke 1:819ac9aa5667 64 uint32_t wr_indx; // buffer write index
mahphalke 1:819ac9aa5667 65 uint32_t align_cnt; // buffer alignment counter
mahphalke 1:819ac9aa5667 66 #if (AD7606X_ADC_RESOLUTION > 16)
mahphalke 1:819ac9aa5667 67 uint32_t data[DATA_BUFFER_SIZE];
mahphalke 1:819ac9aa5667 68 #else
mahphalke 1:819ac9aa5667 69 uint16_t data[DATA_BUFFER_SIZE];
mahphalke 1:819ac9aa5667 70 #endif
mahphalke 1:819ac9aa5667 71 } acq_buf_t;
mahphalke 1:819ac9aa5667 72
mahphalke 1:819ac9aa5667 73 /* ADC data acquisition buffers */
mahphalke 1:819ac9aa5667 74 static volatile acq_buf_t acq_buffer;
mahphalke 1:819ac9aa5667 75
mahphalke 1:819ac9aa5667 76 /* Flag to indicate background data capture status */
mahphalke 1:819ac9aa5667 77 static volatile bool start_adc_data_capture = false;
mahphalke 1:819ac9aa5667 78
mahphalke 1:819ac9aa5667 79 /* Active channels to be captured */
mahphalke 1:819ac9aa5667 80 static volatile uint32_t active_channels = 0;
mahphalke 1:819ac9aa5667 81
mahphalke 1:819ac9aa5667 82 /* Number of active channels */
mahphalke 1:819ac9aa5667 83 static uint8_t num_of_active_channels = 0;
mahphalke 1:819ac9aa5667 84
mahphalke 1:819ac9aa5667 85 /* Minimum number of bytes to be read from device over digital interface */
mahphalke 1:819ac9aa5667 86 static volatile uint8_t min_bytes_to_read = 0;
mahphalke 1:819ac9aa5667 87
mahphalke 1:819ac9aa5667 88 /* Number of channels requested for read into acquisition buffer */
mahphalke 1:819ac9aa5667 89 static volatile uint8_t chn_read_cnt = 0;
mahphalke 1:819ac9aa5667 90
mahphalke 1:819ac9aa5667 91 /* Number of samples requested by IIO client */
mahphalke 1:819ac9aa5667 92 static uint16_t num_of_samples = 0;
mahphalke 1:819ac9aa5667 93
mahphalke 1:819ac9aa5667 94 /* Max available size of buffer */
mahphalke 1:819ac9aa5667 95 static uint16_t max_available_buffer_size = 0;
mahphalke 1:819ac9aa5667 96
mahphalke 1:819ac9aa5667 97 /******************************************************************************/
mahphalke 1:819ac9aa5667 98 /************************ Functions Declarations ******************************/
mahphalke 1:819ac9aa5667 99 /******************************************************************************/
mahphalke 1:819ac9aa5667 100
mahphalke 1:819ac9aa5667 101 static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end,
mahphalke 1:819ac9aa5667 102 uint8_t *mask);
mahphalke 1:819ac9aa5667 103
mahphalke 1:819ac9aa5667 104 /******************************************************************************/
mahphalke 1:819ac9aa5667 105 /************************ Functions Definitions *******************************/
mahphalke 1:819ac9aa5667 106 /******************************************************************************/
mahphalke 1:819ac9aa5667 107
mahphalke 1:819ac9aa5667 108 /*!
mahphalke 1:819ac9aa5667 109 * @brief Function to init the data capture for AD7606 device
mahphalke 1:819ac9aa5667 110 * @param device[in]- Device instance
mahphalke 1:819ac9aa5667 111 * @return none
mahphalke 1:819ac9aa5667 112 */
mahphalke 1:819ac9aa5667 113 int32_t iio_data_capture_init(struct ad7606_dev *device)
mahphalke 1:819ac9aa5667 114 {
mahphalke 1:819ac9aa5667 115 /* Save the device structure for background conversion */
mahphalke 1:819ac9aa5667 116 dev = malloc(sizeof(struct ad7606_dev *));
mahphalke 1:819ac9aa5667 117 if (!dev) {
mahphalke 1:819ac9aa5667 118 return FAILURE;
mahphalke 1:819ac9aa5667 119 }
mahphalke 1:819ac9aa5667 120
mahphalke 1:819ac9aa5667 121 memcpy(&dev, &device, sizeof(dev));
mahphalke 1:819ac9aa5667 122
mahphalke 1:819ac9aa5667 123 return SUCCESS;
mahphalke 1:819ac9aa5667 124 }
mahphalke 1:819ac9aa5667 125
mahphalke 1:819ac9aa5667 126
mahphalke 1:819ac9aa5667 127 /*!
mahphalke 1:819ac9aa5667 128 * @brief Function to read the ADC raw data for single channel
mahphalke 1:819ac9aa5667 129 * @param device[in]- Device instance
mahphalke 1:819ac9aa5667 130 * @param chn[in] - Input channel
mahphalke 1:819ac9aa5667 131 * @return adc raw data/sample
mahphalke 1:819ac9aa5667 132 */
mahphalke 1:819ac9aa5667 133 int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity)
mahphalke 1:819ac9aa5667 134 {
mahphalke 1:819ac9aa5667 135 int32_t adc_data = 0;
mahphalke 1:819ac9aa5667 136 uint32_t adc_raw[AD7606X_ADC_RESOLUTION] = { 0 };
mahphalke 1:819ac9aa5667 137
mahphalke 1:819ac9aa5667 138 if (ad7606_read(device, adc_raw) != SUCCESS) {
mahphalke 1:819ac9aa5667 139 adc_raw[chn] = 0;
mahphalke 1:819ac9aa5667 140 }
mahphalke 1:819ac9aa5667 141
mahphalke 1:819ac9aa5667 142 if (polarity == BIPOLAR) {
mahphalke 1:819ac9aa5667 143 /* Check for negative adc value for bipolar inputs */
mahphalke 1:819ac9aa5667 144 if (adc_raw[chn] >= ADC_MAX_COUNT_BIPOLAR) {
mahphalke 1:819ac9aa5667 145 /* Take the 2s complement for the negative counts (>full scale value) */
mahphalke 1:819ac9aa5667 146 adc_data = ADC_MAX_COUNT_UNIPOLAR - adc_raw[chn];
mahphalke 1:819ac9aa5667 147 adc_data = 0 - adc_data;
mahphalke 1:819ac9aa5667 148 } else {
mahphalke 1:819ac9aa5667 149 adc_data = adc_raw[chn];
mahphalke 1:819ac9aa5667 150 }
mahphalke 1:819ac9aa5667 151 } else {
mahphalke 1:819ac9aa5667 152 adc_data = adc_raw[chn];
mahphalke 1:819ac9aa5667 153 }
mahphalke 1:819ac9aa5667 154
mahphalke 1:819ac9aa5667 155 return adc_data;
mahphalke 1:819ac9aa5667 156 }
mahphalke 1:819ac9aa5667 157
mahphalke 1:819ac9aa5667 158
mahphalke 1:819ac9aa5667 159 /*!
mahphalke 1:819ac9aa5667 160 * @brief Function to store the number of requested samples from IIO client
mahphalke 1:819ac9aa5667 161 * @param bytes[in] - Number of bytes corresponding to requested samples
mahphalke 1:819ac9aa5667 162 * @return none
mahphalke 1:819ac9aa5667 163 */
mahphalke 1:819ac9aa5667 164 void store_requested_samples_count(size_t bytes)
mahphalke 1:819ac9aa5667 165 {
mahphalke 1:819ac9aa5667 166 /* This gets the number of samples requested by IIO client for all active channels */
mahphalke 1:819ac9aa5667 167 num_of_samples = bytes / BYTES_PER_SAMPLE;
mahphalke 1:819ac9aa5667 168
mahphalke 1:819ac9aa5667 169 /* Get the actual available size of buffer by aligning with number of requested samples.
mahphalke 1:819ac9aa5667 170 * e.g. if requested samples are 1050, the max available size of buffer is:
mahphalke 1:819ac9aa5667 171 * available size = (8192 / 1050) * 1050 = 7 * 1050 = 7350.
mahphalke 1:819ac9aa5667 172 * The max samples to be requested should always be less than half the max size of buffer
mahphalke 1:819ac9aa5667 173 * (in this case: 8192 / 2 = 4096).
mahphalke 1:819ac9aa5667 174 * */
mahphalke 1:819ac9aa5667 175 max_available_buffer_size = ((DATA_BUFFER_SIZE / num_of_samples) *
mahphalke 1:819ac9aa5667 176 num_of_samples);
mahphalke 1:819ac9aa5667 177 }
mahphalke 1:819ac9aa5667 178
mahphalke 1:819ac9aa5667 179
mahphalke 1:819ac9aa5667 180 /*!
mahphalke 1:819ac9aa5667 181 * @brief Function to read new samples into buffer without timeout IIO request
mahphalke 1:819ac9aa5667 182 * @param input_buffer[in] - Input data acquisition buffer
mahphalke 1:819ac9aa5667 183 * @param output_buffer[in, out] - Output data buffer
mahphalke 1:819ac9aa5667 184 * @param samples_to_read[in] - Number of samples to read
mahphalke 1:819ac9aa5667 185 * @return none
mahphalke 1:819ac9aa5667 186 */
mahphalke 1:819ac9aa5667 187 static void wait_and_read_new_samples(volatile acq_buf_t *input_buffer,
mahphalke 1:819ac9aa5667 188 char *output_buffer,
mahphalke 1:819ac9aa5667 189 size_t samples_to_read)
mahphalke 1:819ac9aa5667 190 {
mahphalke 1:819ac9aa5667 191 int32_t buff_rd_wr_indx_offset; // Offset b/w buffer read and write indexes
mahphalke 1:819ac9aa5667 192 uint32_t timeout = 5000000; // To avoid IIO data request timeout
mahphalke 1:819ac9aa5667 193 size_t bytes = samples_to_read * BYTES_PER_SAMPLE;
mahphalke 1:819ac9aa5667 194
mahphalke 1:819ac9aa5667 195 /* Copy the bytes into buffer provided there is enough offset b/w read and write counts.
mahphalke 1:819ac9aa5667 196 * If there is overlap b/w read and write indexes (read is faster than write), empty buffer
mahphalke 1:819ac9aa5667 197 * should be returned to IIO client to avoid IIO request timeout */
mahphalke 1:819ac9aa5667 198 do {
mahphalke 1:819ac9aa5667 199 buff_rd_wr_indx_offset = (int32_t)input_buffer->wr_indx -
mahphalke 1:819ac9aa5667 200 (int32_t)input_buffer->rd_indx;
mahphalke 1:819ac9aa5667 201 timeout--;
mahphalke 1:819ac9aa5667 202 } while (((buff_rd_wr_indx_offset < (int32_t)(samples_to_read))
mahphalke 1:819ac9aa5667 203 || (input_buffer->wr_indx < input_buffer->rd_indx)) && (timeout > 0));
mahphalke 1:819ac9aa5667 204
mahphalke 1:819ac9aa5667 205 if ((timeout == 0) || (input_buffer->wr_indx <= 0)) {
mahphalke 1:819ac9aa5667 206 /* This returns the empty buffer */
mahphalke 1:819ac9aa5667 207 return;
mahphalke 1:819ac9aa5667 208 }
mahphalke 1:819ac9aa5667 209
mahphalke 1:819ac9aa5667 210 memcpy(output_buffer,
mahphalke 1:819ac9aa5667 211 (void const *)&input_buffer->data[input_buffer->rd_indx],
mahphalke 1:819ac9aa5667 212 bytes);
mahphalke 1:819ac9aa5667 213 input_buffer->rd_indx += samples_to_read;
mahphalke 1:819ac9aa5667 214 }
mahphalke 1:819ac9aa5667 215
mahphalke 1:819ac9aa5667 216
mahphalke 1:819ac9aa5667 217 /*!
mahphalke 1:819ac9aa5667 218 * @brief Function to read and align the ADC buffered raw data
mahphalke 1:819ac9aa5667 219 * @param device[in]- Device instance
mahphalke 1:819ac9aa5667 220 * @param pbuf[out] - Buffer to load ADC raw data
mahphalke 1:819ac9aa5667 221 * @param bytes[in] - Number of bytes to be read
mahphalke 1:819ac9aa5667 222 * @param active_chns_mask[in] - Active channels mask
mahphalke 1:819ac9aa5667 223 * @return Number of bytes read
mahphalke 1:819ac9aa5667 224 */
mahphalke 1:819ac9aa5667 225 size_t buffered_data_read(char *pbuf, size_t bytes, size_t offset,
mahphalke 1:819ac9aa5667 226 uint32_t active_chns_mask)
mahphalke 1:819ac9aa5667 227 {
mahphalke 1:819ac9aa5667 228 size_t samples_to_read = bytes / BYTES_PER_SAMPLE; // Bytes to sample conversion
mahphalke 1:819ac9aa5667 229
mahphalke 1:819ac9aa5667 230 /* Make sure requested samples size is less than ADC buffer size. Return constant
mahphalke 1:819ac9aa5667 231 * value to avoid IIO client getting timed-out */
mahphalke 1:819ac9aa5667 232 if (num_of_samples >= max_available_buffer_size) {
mahphalke 1:819ac9aa5667 233 memset(pbuf, 1, bytes);
mahphalke 1:819ac9aa5667 234 return bytes;
mahphalke 1:819ac9aa5667 235 }
mahphalke 1:819ac9aa5667 236
mahphalke 1:819ac9aa5667 237 wait_and_read_new_samples(&acq_buffer, pbuf, samples_to_read);
mahphalke 1:819ac9aa5667 238
mahphalke 1:819ac9aa5667 239 /* Make buffer available again once read completely */
mahphalke 1:819ac9aa5667 240 if (acq_buffer.rd_indx >= max_available_buffer_size) {
mahphalke 1:819ac9aa5667 241 acq_buffer.rd_indx = 0;
mahphalke 1:819ac9aa5667 242 acq_buffer.wr_indx = 0;
mahphalke 1:819ac9aa5667 243 acq_buffer.align_cnt = 0;
mahphalke 1:819ac9aa5667 244 acq_buffer.state = BUF_AVAILABLE;
mahphalke 1:819ac9aa5667 245 }
mahphalke 1:819ac9aa5667 246
mahphalke 1:819ac9aa5667 247 return bytes;
mahphalke 1:819ac9aa5667 248 }
mahphalke 1:819ac9aa5667 249
mahphalke 1:819ac9aa5667 250
mahphalke 1:819ac9aa5667 251 /*!
mahphalke 1:819ac9aa5667 252 * @brief Function to perform background ADC conversion and data capture
mahphalke 1:819ac9aa5667 253 * @return none
mahphalke 1:819ac9aa5667 254 * @details This is an External Interrupt callback function/ISR, which is tied up to
mahphalke 1:819ac9aa5667 255 * falling edge trigger of BUSY pin. It is trigered when previous data
mahphalke 1:819ac9aa5667 256 * conversion is over and BUSY line goes low. Upon trigger, conversion
mahphalke 1:819ac9aa5667 257 * results are read into acquisition buffer and next conversion is triggered.
mahphalke 1:819ac9aa5667 258 * This continues until background conversion is stopped.
mahphalke 1:819ac9aa5667 259 */
mahphalke 1:819ac9aa5667 260 void do_conversion_callback(void)
mahphalke 1:819ac9aa5667 261 {
mahphalke 1:819ac9aa5667 262 #if (AD7606X_ADC_RESOLUTION == 18)
mahphalke 1:819ac9aa5667 263 uint8_t arr_indx = 0;
mahphalke 1:819ac9aa5667 264 uint8_t offset_end = 2;
mahphalke 1:819ac9aa5667 265 uint8_t mask = 0xff;
mahphalke 1:819ac9aa5667 266 #else
mahphalke 1:819ac9aa5667 267 uint8_t mask = 0x01;
mahphalke 1:819ac9aa5667 268 #endif
mahphalke 1:819ac9aa5667 269
mahphalke 1:819ac9aa5667 270 if (start_adc_data_capture == true) {
mahphalke 1:819ac9aa5667 271
mahphalke 1:819ac9aa5667 272 /* Read the conversion result for required number of bytes */
mahphalke 1:819ac9aa5667 273 if (ad7606_read_conversion_data(dev, min_bytes_to_read) == SUCCESS) {
mahphalke 1:819ac9aa5667 274
mahphalke 1:819ac9aa5667 275 /* Extract the data based on the active channels selected in IIO client.
mahphalke 1:819ac9aa5667 276 * Note: The extraction of data based on active channel needs
mahphalke 1:819ac9aa5667 277 * to be done since its not possible to capture individual
mahphalke 1:819ac9aa5667 278 * channel in AD7606 devices */
mahphalke 1:819ac9aa5667 279 for (uint8_t chn = 0; chn < chn_read_cnt; chn++) {
mahphalke 1:819ac9aa5667 280 if (active_channels & mask) {
mahphalke 1:819ac9aa5667 281 if (acq_buffer.state == BUF_AVAILABLE) {
mahphalke 1:819ac9aa5667 282 #if (AD7606X_ADC_RESOLUTION == 18)
mahphalke 1:819ac9aa5667 283 /* For AD7606C device (18-bit resolution) */
mahphalke 1:819ac9aa5667 284 acq_buffer.data[acq_buffer.wr_indx++] =
mahphalke 1:819ac9aa5667 285 (((uint32_t)(dev->data[arr_indx] & mask) << 16) | // MSB
mahphalke 1:819ac9aa5667 286 ((uint32_t)dev->data[arr_indx + 1] << 8) |
mahphalke 1:819ac9aa5667 287 ((uint32_t)(dev->data[arr_indx + 2] >> (8 - offset_end)))); // LSB
mahphalke 1:819ac9aa5667 288 #else
mahphalke 1:819ac9aa5667 289
mahphalke 1:819ac9aa5667 290 acq_buffer.data[acq_buffer.wr_indx++] =
mahphalke 1:819ac9aa5667 291 (uint16_t)(((uint16_t)dev->data[chn << 1] << 8) | // MSB
mahphalke 1:819ac9aa5667 292 dev->data[(chn << 1) + 1]); // LSB
mahphalke 1:819ac9aa5667 293 #endif
mahphalke 1:819ac9aa5667 294
mahphalke 1:819ac9aa5667 295 acq_buffer.align_cnt++;
mahphalke 1:819ac9aa5667 296
mahphalke 1:819ac9aa5667 297 /* Monitor primary buffer full state */
mahphalke 1:819ac9aa5667 298 if (acq_buffer.wr_indx >= max_available_buffer_size) {
mahphalke 1:819ac9aa5667 299 acq_buffer.state = BUF_FULL;
mahphalke 1:819ac9aa5667 300
mahphalke 1:819ac9aa5667 301 /* This aligns the buffer to first active channel once all requested samples are transmitted */
mahphalke 1:819ac9aa5667 302 if (acq_buffer.align_cnt >= num_of_samples) {
mahphalke 1:819ac9aa5667 303 acq_buffer.align_cnt = 0;
mahphalke 1:819ac9aa5667 304 }
mahphalke 1:819ac9aa5667 305 #if (AD7606X_ADC_RESOLUTION == 18)
mahphalke 1:819ac9aa5667 306 adjust_buffer_offset(&arr_indx, &offset_end, &mask);
mahphalke 1:819ac9aa5667 307 #endif
mahphalke 1:819ac9aa5667 308 mask <<= 1;
mahphalke 1:819ac9aa5667 309 continue;
mahphalke 1:819ac9aa5667 310 }
mahphalke 1:819ac9aa5667 311
mahphalke 1:819ac9aa5667 312 /* This aligns the buffer to first active channel once all requested samples are transmitted */
mahphalke 1:819ac9aa5667 313 if (acq_buffer.align_cnt >= num_of_samples) {
mahphalke 1:819ac9aa5667 314 acq_buffer.align_cnt = 0;
mahphalke 1:819ac9aa5667 315 break;
mahphalke 1:819ac9aa5667 316 }
mahphalke 1:819ac9aa5667 317 }
mahphalke 1:819ac9aa5667 318 }
mahphalke 1:819ac9aa5667 319
mahphalke 1:819ac9aa5667 320 #if (AD7606X_ADC_RESOLUTION == 18)
mahphalke 1:819ac9aa5667 321 adjust_buffer_offset(&arr_indx, &offset_end, &mask);
mahphalke 1:819ac9aa5667 322 #endif
mahphalke 1:819ac9aa5667 323
mahphalke 1:819ac9aa5667 324 mask <<= 1;
mahphalke 1:819ac9aa5667 325 }
mahphalke 1:819ac9aa5667 326
mahphalke 1:819ac9aa5667 327 /* Trigger next conversion */
mahphalke 1:819ac9aa5667 328 if (ad7606_convst(dev) != SUCCESS) {
mahphalke 1:819ac9aa5667 329 start_adc_data_capture = false;
mahphalke 1:819ac9aa5667 330 }
mahphalke 1:819ac9aa5667 331 } else {
mahphalke 1:819ac9aa5667 332 start_adc_data_capture = false;
mahphalke 1:819ac9aa5667 333 }
mahphalke 1:819ac9aa5667 334 }
mahphalke 1:819ac9aa5667 335 }
mahphalke 1:819ac9aa5667 336
mahphalke 1:819ac9aa5667 337
mahphalke 1:819ac9aa5667 338 /*!
mahphalke 1:819ac9aa5667 339 * @brief Function to trigger bakground ADC conversion for new READBUFF
mahphalke 1:819ac9aa5667 340 * request from IIO client (for active channels)
mahphalke 1:819ac9aa5667 341 * @return Conversion start status
mahphalke 1:819ac9aa5667 342 */
mahphalke 1:819ac9aa5667 343 void start_background_data_capture(uint32_t ch_mask, size_t bytes_count)
mahphalke 1:819ac9aa5667 344 {
mahphalke 1:819ac9aa5667 345 uint8_t mask = 0x1;
mahphalke 1:819ac9aa5667 346
mahphalke 1:819ac9aa5667 347 /* Make sure requested samples size is less than ADC buffer size */
mahphalke 1:819ac9aa5667 348 if (num_of_samples >= max_available_buffer_size)
mahphalke 1:819ac9aa5667 349 return;
mahphalke 1:819ac9aa5667 350
mahphalke 1:819ac9aa5667 351 active_channels = ch_mask;
mahphalke 1:819ac9aa5667 352
mahphalke 1:819ac9aa5667 353 stop_background_data_capture();
mahphalke 1:819ac9aa5667 354
mahphalke 1:819ac9aa5667 355 /* Find the minimum number of bytes to be read from device during
mahphalke 1:819ac9aa5667 356 * background conversion (Reading all bytes/channels adds extra overhead,
mahphalke 1:819ac9aa5667 357 * so restrict the minimum reads to whatever is possible).
mahphalke 1:819ac9aa5667 358 * Note: This happens only at the start of buffer read request. */
mahphalke 1:819ac9aa5667 359 for (uint8_t chn = 1, indx = 0; chn <= AD7606X_ADC_CHANNELS; chn++, indx++) {
mahphalke 1:819ac9aa5667 360 if (ch_mask & mask) {
mahphalke 1:819ac9aa5667 361 /* 1 sample = 2 or 4 bytes */
mahphalke 1:819ac9aa5667 362 min_bytes_to_read = chn * BYTES_PER_SAMPLE;
mahphalke 1:819ac9aa5667 363 if (min_bytes_to_read > AD7606X_ADC_RESOLUTION) {
mahphalke 1:819ac9aa5667 364 min_bytes_to_read = AD7606X_ADC_RESOLUTION;
mahphalke 1:819ac9aa5667 365 }
mahphalke 1:819ac9aa5667 366
mahphalke 1:819ac9aa5667 367 /* Get the count for number of samples to be stored into acquisition buffer */
mahphalke 1:819ac9aa5667 368 chn_read_cnt = chn;
mahphalke 1:819ac9aa5667 369 num_of_active_channels++;
mahphalke 1:819ac9aa5667 370 }
mahphalke 1:819ac9aa5667 371
mahphalke 1:819ac9aa5667 372 mask <<= 1;
mahphalke 1:819ac9aa5667 373 }
mahphalke 1:819ac9aa5667 374
mahphalke 1:819ac9aa5667 375 /* Make primary acquisition buffer available and start conversion */
mahphalke 1:819ac9aa5667 376 acq_buffer.state = BUF_AVAILABLE;
mahphalke 1:819ac9aa5667 377 if (ad7606_convst(dev) == SUCCESS) {
mahphalke 1:819ac9aa5667 378 start_adc_data_capture = true;
mahphalke 1:819ac9aa5667 379 } else {
mahphalke 1:819ac9aa5667 380 start_adc_data_capture = false;
mahphalke 1:819ac9aa5667 381 }
mahphalke 1:819ac9aa5667 382 }
mahphalke 1:819ac9aa5667 383
mahphalke 1:819ac9aa5667 384
mahphalke 1:819ac9aa5667 385 /*!
mahphalke 1:819ac9aa5667 386 * @brief Function to stop background ADC data capture
mahphalke 1:819ac9aa5667 387 * @return none
mahphalke 1:819ac9aa5667 388 */
mahphalke 1:819ac9aa5667 389 void stop_background_data_capture(void)
mahphalke 1:819ac9aa5667 390 {
mahphalke 1:819ac9aa5667 391 /* Reset data capture flags */
mahphalke 1:819ac9aa5667 392 start_adc_data_capture = false;
mahphalke 1:819ac9aa5667 393 num_of_active_channels = 0;
mahphalke 1:819ac9aa5667 394 min_bytes_to_read = 0;
mahphalke 1:819ac9aa5667 395 chn_read_cnt = 0;
mahphalke 1:819ac9aa5667 396
mahphalke 1:819ac9aa5667 397 /* Reset acquisition buffer states and clear old data */
mahphalke 1:819ac9aa5667 398 acq_buffer.state = BUF_EMPTY;
mahphalke 1:819ac9aa5667 399
mahphalke 1:819ac9aa5667 400 memset((void *)acq_buffer.data, 0, sizeof(acq_buffer.data));
mahphalke 1:819ac9aa5667 401
mahphalke 1:819ac9aa5667 402 acq_buffer.wr_indx = 0;
mahphalke 1:819ac9aa5667 403 acq_buffer.rd_indx = 0;
mahphalke 1:819ac9aa5667 404 acq_buffer.align_cnt = 0;
mahphalke 1:819ac9aa5667 405 }
mahphalke 1:819ac9aa5667 406
mahphalke 1:819ac9aa5667 407
mahphalke 1:819ac9aa5667 408 /*!
mahphalke 1:819ac9aa5667 409 * @brief Function to adjust the data buffer offset
mahphalke 1:819ac9aa5667 410 * @param *arr_indx[in, out]- Array index
mahphalke 1:819ac9aa5667 411 * @param *offset_end[out] - offset to extract LSB from 18-bit data
mahphalke 1:819ac9aa5667 412 * @param *mask[out] - channel select mask
mahphalke 1:819ac9aa5667 413 * @return none
mahphalke 1:819ac9aa5667 414 */
mahphalke 1:819ac9aa5667 415 static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end,
mahphalke 1:819ac9aa5667 416 uint8_t *mask)
mahphalke 1:819ac9aa5667 417 {
mahphalke 1:819ac9aa5667 418 *arr_indx += 2;
mahphalke 1:819ac9aa5667 419
mahphalke 1:819ac9aa5667 420 /* Track array to reach at the middle (9 bytes apart) to change the offsets */
mahphalke 1:819ac9aa5667 421 if (*arr_indx == ((AD7606X_ADC_RESOLUTION / 2) - 1)) {
mahphalke 1:819ac9aa5667 422 (*arr_indx)++;
mahphalke 1:819ac9aa5667 423 *offset_end = 2;
mahphalke 1:819ac9aa5667 424 *mask = 0xff;
mahphalke 1:819ac9aa5667 425 } else {
mahphalke 1:819ac9aa5667 426 *mask = (0xff >> *offset_end);
mahphalke 1:819ac9aa5667 427 *offset_end += 2;
mahphalke 1:819ac9aa5667 428 }
mahphalke 1:819ac9aa5667 429 }