this is testing

Committer:
pmallick
Date:
Thu Jan 14 18:54:16 2021 +0530
Revision:
0:3afcd581558d
this is testing

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pmallick 0:3afcd581558d 1 /***************************************************************************//**
pmallick 0:3afcd581558d 2 * @file ad7606_data_capture.c
pmallick 0:3afcd581558d 3 * @brief Data capture interface for AD7606 IIO application
pmallick 0:3afcd581558d 4 * @details This module handles the AD7606 data capturing
pmallick 0:3afcd581558d 5 ********************************************************************************
pmallick 0:3afcd581558d 6 * Copyright (c) 2020 Analog Devices, Inc.
pmallick 0:3afcd581558d 7 *
pmallick 0:3afcd581558d 8 * All rights reserved.
pmallick 0:3afcd581558d 9 *
pmallick 0:3afcd581558d 10 * This software is proprietary to Analog Devices, Inc. and its licensors.
pmallick 0:3afcd581558d 11 * By using this software you agree to the terms of the associated
pmallick 0:3afcd581558d 12 * Analog Devices Software License Agreement.
pmallick 0:3afcd581558d 13 *******************************************************************************/
pmallick 0:3afcd581558d 14
pmallick 0:3afcd581558d 15 /******************************************************************************/
pmallick 0:3afcd581558d 16 /***************************** Include Files **********************************/
pmallick 0:3afcd581558d 17 /******************************************************************************/
pmallick 0:3afcd581558d 18
pmallick 0:3afcd581558d 19 #include <string.h>
pmallick 0:3afcd581558d 20 #include <stdlib.h>
pmallick 0:3afcd581558d 21
pmallick 0:3afcd581558d 22 #include "app_config.h"
pmallick 0:3afcd581558d 23 #include "ad7606_data_capture.h"
pmallick 0:3afcd581558d 24 #include "ad7606_support.h"
pmallick 0:3afcd581558d 25 #include "gpio_extra.h"
pmallick 0:3afcd581558d 26
pmallick 0:3afcd581558d 27 /******************************************************************************/
pmallick 0:3afcd581558d 28 /********************** Macros and Constants Definition ***********************/
pmallick 0:3afcd581558d 29 /******************************************************************************/
pmallick 0:3afcd581558d 30
pmallick 0:3afcd581558d 31 /******************************************************************************/
pmallick 0:3afcd581558d 32 /********************** Variables and User Defined Data Types *****************/
pmallick 0:3afcd581558d 33 /******************************************************************************/
pmallick 0:3afcd581558d 34
pmallick 0:3afcd581558d 35 /* Device instance for background adc conversion callback */
pmallick 0:3afcd581558d 36 static volatile struct ad7606_dev *dev = NULL;
pmallick 0:3afcd581558d 37
pmallick 0:3afcd581558d 38 /*
pmallick 0:3afcd581558d 39 *@enum acq_buffer_state_e
pmallick 0:3afcd581558d 40 *@details Enum holding the data acquisition buffer states
pmallick 0:3afcd581558d 41 **/
pmallick 0:3afcd581558d 42 typedef enum {
pmallick 0:3afcd581558d 43 BUF_AVAILABLE,
pmallick 0:3afcd581558d 44 BUF_FULL
pmallick 0:3afcd581558d 45 } acq_buffer_state_e;
pmallick 0:3afcd581558d 46
pmallick 0:3afcd581558d 47 /*
pmallick 0:3afcd581558d 48 *@struct acq_buf_t
pmallick 0:3afcd581558d 49 *@details Structure holding the data acquisition buffer parameters
pmallick 0:3afcd581558d 50 **/
pmallick 0:3afcd581558d 51 typedef struct {
pmallick 0:3afcd581558d 52 acq_buffer_state_e state;
pmallick 0:3afcd581558d 53 #if (ADC_RESOLUTION > 16)
pmallick 0:3afcd581558d 54 uint32_t data[NO_OF_SAMPLES];
pmallick 0:3afcd581558d 55 #else
pmallick 0:3afcd581558d 56 uint16_t data[NO_OF_SAMPLES];
pmallick 0:3afcd581558d 57 #endif
pmallick 0:3afcd581558d 58 } acq_buf_t;
pmallick 0:3afcd581558d 59
pmallick 0:3afcd581558d 60 /* ADC data acquisition buffers */
pmallick 0:3afcd581558d 61 static volatile acq_buf_t acq_buffer[2];
pmallick 0:3afcd581558d 62
pmallick 0:3afcd581558d 63 /* Flag to indicate background data conversion status */
pmallick 0:3afcd581558d 64 static volatile bool start_background_conversion = false;
pmallick 0:3afcd581558d 65
pmallick 0:3afcd581558d 66 /* Active channels to be captured */
pmallick 0:3afcd581558d 67 static volatile uint32_t active_channels = 0;
pmallick 0:3afcd581558d 68
pmallick 0:3afcd581558d 69 /* Minimum number of bytes to be read from device */
pmallick 0:3afcd581558d 70 static volatile uint8_t min_bytes_to_read = 0;
pmallick 0:3afcd581558d 71
pmallick 0:3afcd581558d 72 /* Minimum number of samples to be stored into acquisition buffer */
pmallick 0:3afcd581558d 73 static volatile uint8_t min_samples_to_store = 0;
pmallick 0:3afcd581558d 74
pmallick 0:3afcd581558d 75 /******************************************************************************/
pmallick 0:3afcd581558d 76 /************************ Functions Definitions *******************************/
pmallick 0:3afcd581558d 77 /******************************************************************************/
pmallick 0:3afcd581558d 78
pmallick 0:3afcd581558d 79 /*!
pmallick 0:3afcd581558d 80 * @brief Function to init the data capture for AD7606 device
pmallick 0:3afcd581558d 81 * @param device[in]- Device instance
pmallick 0:3afcd581558d 82 * @return none
pmallick 0:3afcd581558d 83 */
pmallick 0:3afcd581558d 84 int32_t iio_data_capture_init(struct ad7606_dev *device)
pmallick 0:3afcd581558d 85 {
pmallick 0:3afcd581558d 86 /* Save the device structure for background conversion */
pmallick 0:3afcd581558d 87 dev = malloc(sizeof(struct ad7606_dev *));
pmallick 0:3afcd581558d 88 if (!dev) {
pmallick 0:3afcd581558d 89 return FAILURE;
pmallick 0:3afcd581558d 90 }
pmallick 0:3afcd581558d 91
pmallick 0:3afcd581558d 92 memcpy(&dev, &device, sizeof(dev));
pmallick 0:3afcd581558d 93
pmallick 0:3afcd581558d 94 return SUCCESS;
pmallick 0:3afcd581558d 95 }
pmallick 0:3afcd581558d 96
pmallick 0:3afcd581558d 97
pmallick 0:3afcd581558d 98 /*!
pmallick 0:3afcd581558d 99 * @brief Function to read the ADC raw data for single channel
pmallick 0:3afcd581558d 100 * @param device[in]- Device instance
pmallick 0:3afcd581558d 101 * @param chn[in] - Input channel
pmallick 0:3afcd581558d 102 * @return adc raw data/sample
pmallick 0:3afcd581558d 103 */
pmallick 0:3afcd581558d 104 int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity)
pmallick 0:3afcd581558d 105 {
pmallick 0:3afcd581558d 106 int32_t adc_data = 0;
pmallick 0:3afcd581558d 107 uint32_t adc_raw[ADC_RESOLUTION] = { 0 };
pmallick 0:3afcd581558d 108
pmallick 0:3afcd581558d 109 if (ad7606_read(device, adc_raw) != SUCCESS) {
pmallick 0:3afcd581558d 110 adc_raw[chn] = 0;
pmallick 0:3afcd581558d 111 }
pmallick 0:3afcd581558d 112
pmallick 0:3afcd581558d 113 if (polarity == BIPOLAR) {
pmallick 0:3afcd581558d 114 /* Check for negative adc value for bipolar inputs */
pmallick 0:3afcd581558d 115 if (adc_raw[chn] >= ADC_MAX_COUNT_BIPOLAR) {
pmallick 0:3afcd581558d 116 /* Take the 2s complement for the negative counts (>full scale value) */
pmallick 0:3afcd581558d 117 adc_data = ADC_MAX_COUNT_UNIPOLAR - adc_raw[chn];
pmallick 0:3afcd581558d 118 adc_data = 0 - adc_data;
pmallick 0:3afcd581558d 119 } else {
pmallick 0:3afcd581558d 120 adc_data = adc_raw[chn];
pmallick 0:3afcd581558d 121 }
pmallick 0:3afcd581558d 122 } else {
pmallick 0:3afcd581558d 123 adc_data = adc_raw[chn];
pmallick 0:3afcd581558d 124 }
pmallick 0:3afcd581558d 125
pmallick 0:3afcd581558d 126 return adc_data;
pmallick 0:3afcd581558d 127 }
pmallick 0:3afcd581558d 128
pmallick 0:3afcd581558d 129
pmallick 0:3afcd581558d 130 /*!
pmallick 0:3afcd581558d 131 * @brief Function to read the ADC buffered raw data
pmallick 0:3afcd581558d 132 * @param device[in]- Device instance
pmallick 0:3afcd581558d 133 * @param pbuf[out] - Buffer to load ADC raw data
pmallick 0:3afcd581558d 134 * @param bytes[in] - Number of bytes to be read
pmallick 0:3afcd581558d 135 * @param chn_mask[in] - Active channels mask
pmallick 0:3afcd581558d 136 * @return none
pmallick 0:3afcd581558d 137 * @details This function reads the data from any available acquisition
pmallick 0:3afcd581558d 138 * buffer (the buffer which is full). The intention here is to
pmallick 0:3afcd581558d 139 * have most recent data fetched from the device.
pmallick 0:3afcd581558d 140 */
pmallick 0:3afcd581558d 141 void buffered_data_read(char *pbuf, size_t bytes, size_t offset,
pmallick 0:3afcd581558d 142 uint32_t chn_mask)
pmallick 0:3afcd581558d 143 {
pmallick 0:3afcd581558d 144 uint8_t mask = 0x1;
pmallick 0:3afcd581558d 145
pmallick 0:3afcd581558d 146 if (acq_buffer[0].state == BUF_FULL) {
pmallick 0:3afcd581558d 147 /* Copy the acquisition buffer 0 into output data buffer */
pmallick 0:3afcd581558d 148 memcpy(pbuf, acq_buffer[0].data, bytes);
pmallick 0:3afcd581558d 149 } else if(acq_buffer[1].state == BUF_FULL) {
pmallick 0:3afcd581558d 150 /* Copy the acquisition buffer 1 into output data buffer */
pmallick 0:3afcd581558d 151 memcpy(pbuf, acq_buffer[1].data, bytes);
pmallick 0:3afcd581558d 152 } else {
pmallick 0:3afcd581558d 153 /* This case should never reach. At any instance, at least one
pmallick 0:3afcd581558d 154 * of the buffer should be full */
pmallick 0:3afcd581558d 155 }
pmallick 0:3afcd581558d 156
pmallick 0:3afcd581558d 157 /* Find the minimum number of bytes to be read from device during
pmallick 0:3afcd581558d 158 * background conversion (Reading all channels adds extra overhead,
pmallick 0:3afcd581558d 159 * so restrict the minimum reads to whatever is possible) */
pmallick 0:3afcd581558d 160 if (offset == 0) {
pmallick 0:3afcd581558d 161 active_channels = chn_mask;
pmallick 0:3afcd581558d 162 for (uint8_t chn = 1; chn <= NO_OF_CHANNELS; chn++) {
pmallick 0:3afcd581558d 163 if (active_channels & mask) {
pmallick 0:3afcd581558d 164 #if (ADC_RESOLUTION == 18)
pmallick 0:3afcd581558d 165 /* 1 sample = 3 bytes (max 18 bytes) */
pmallick 0:3afcd581558d 166 min_bytes_to_read = chn * 3;
pmallick 0:3afcd581558d 167 if (min_bytes_to_read > ADC_RESOLUTION) {
pmallick 0:3afcd581558d 168 min_bytes_to_read = ADC_RESOLUTION;
pmallick 0:3afcd581558d 169 }
pmallick 0:3afcd581558d 170 #else
pmallick 0:3afcd581558d 171 /* 1 sample = 2 bytes */
pmallick 0:3afcd581558d 172 min_bytes_to_read = chn * 2;
pmallick 0:3afcd581558d 173 #endif
pmallick 0:3afcd581558d 174 min_samples_to_store = chn;
pmallick 0:3afcd581558d 175 }
pmallick 0:3afcd581558d 176
pmallick 0:3afcd581558d 177 mask <<= 1;
pmallick 0:3afcd581558d 178 }
pmallick 0:3afcd581558d 179 }
pmallick 0:3afcd581558d 180 }
pmallick 0:3afcd581558d 181
pmallick 0:3afcd581558d 182
pmallick 0:3afcd581558d 183 /*!
pmallick 0:3afcd581558d 184 * @brief Function to perform background ADC conversion
pmallick 0:3afcd581558d 185 * @return none
pmallick 0:3afcd581558d 186 * @details This is an External Interrupt callback function/ISR, which is tied up to
pmallick 0:3afcd581558d 187 * falling edge trigger of BUSY pin. It is trigered when previous data
pmallick 0:3afcd581558d 188 * conversion is over and BUSY line goes low. Upon trigger, conversion
pmallick 0:3afcd581558d 189 * results are read into acquisition buffer and next conversion is triggered.
pmallick 0:3afcd581558d 190 * This continues until background conversion is stopped.
pmallick 0:3afcd581558d 191 */
pmallick 0:3afcd581558d 192 void do_conversion_callback(void)
pmallick 0:3afcd581558d 193 {
pmallick 0:3afcd581558d 194 static uint16_t sample_cnt = 0;
pmallick 0:3afcd581558d 195 #if (ADC_RESOLUTION == 18)
pmallick 0:3afcd581558d 196 uint8_t arr_indx = 0;
pmallick 0:3afcd581558d 197 uint8_t offset_end = 2;
pmallick 0:3afcd581558d 198 uint8_t mask = 0xff;
pmallick 0:3afcd581558d 199 #else
pmallick 0:3afcd581558d 200 uint8_t mask = 0x01;
pmallick 0:3afcd581558d 201 #endif
pmallick 0:3afcd581558d 202
pmallick 0:3afcd581558d 203 if (start_background_conversion == true) {
pmallick 0:3afcd581558d 204
pmallick 0:3afcd581558d 205 /* Read the conversion result for required number of bytes */
pmallick 0:3afcd581558d 206 (void)ad7606_read_conversion_data(dev, min_bytes_to_read);
pmallick 0:3afcd581558d 207
pmallick 0:3afcd581558d 208 /* Extract the channels data based on the active channels
pmallick 0:3afcd581558d 209 * Note: The extraction of data based on active channel needs
pmallick 0:3afcd581558d 210 * to be done since its not possible to capture individual
pmallick 0:3afcd581558d 211 * channel in AD7606 devices */
pmallick 0:3afcd581558d 212 for (uint8_t cnt = 0; cnt < min_samples_to_store; cnt++) {
pmallick 0:3afcd581558d 213 if (active_channels & mask) {
pmallick 0:3afcd581558d 214 /* Fill the buffer based on the availability */
pmallick 0:3afcd581558d 215 if (acq_buffer[0].state == BUF_AVAILABLE) {
pmallick 0:3afcd581558d 216 #if (ADC_RESOLUTION == 18)
pmallick 0:3afcd581558d 217 acq_buffer[0].data[sample_cnt] =
pmallick 0:3afcd581558d 218 (((uint32_t)(dev->data[arr_indx] & mask) << 16) | // MSB
pmallick 0:3afcd581558d 219 ((uint32_t)dev->data[arr_indx+1] << 8) |
pmallick 0:3afcd581558d 220 ((uint32_t)(dev->data[arr_indx+2] >> (8-offset_end)))); // LSB
pmallick 0:3afcd581558d 221 #else
pmallick 0:3afcd581558d 222 acq_buffer[0].data[sample_cnt] =
pmallick 0:3afcd581558d 223 (uint16_t)(((uint16_t)dev->data[cnt << 1] << 8) | // MSB
pmallick 0:3afcd581558d 224 dev->data[(cnt << 1) + 1]); // LSB
pmallick 0:3afcd581558d 225 #endif
pmallick 0:3afcd581558d 226 } else if (acq_buffer[1].state == BUF_AVAILABLE) {
pmallick 0:3afcd581558d 227 #if (ADC_RESOLUTION == 18)
pmallick 0:3afcd581558d 228 acq_buffer[1].data[sample_cnt] =
pmallick 0:3afcd581558d 229 (((uint32_t)(dev->data[arr_indx] & mask) << 16) | // MSB
pmallick 0:3afcd581558d 230 ((uint32_t)dev->data[arr_indx + 1] << 8) |
pmallick 0:3afcd581558d 231 ((uint32_t)(dev->data[arr_indx + 2] >> (8 - offset_end))));// LSB
pmallick 0:3afcd581558d 232 #else
pmallick 0:3afcd581558d 233 acq_buffer[1].data[sample_cnt] =
pmallick 0:3afcd581558d 234 (uint16_t)(((uint16_t)dev->data[cnt << 1] << 8) | // MSB
pmallick 0:3afcd581558d 235 dev->data[(cnt << 1) + 1]); // LSB
pmallick 0:3afcd581558d 236 #endif
pmallick 0:3afcd581558d 237 } else {
pmallick 0:3afcd581558d 238 /* This case should never reach */
pmallick 0:3afcd581558d 239 }
pmallick 0:3afcd581558d 240
pmallick 0:3afcd581558d 241 sample_cnt++;
pmallick 0:3afcd581558d 242 }
pmallick 0:3afcd581558d 243
pmallick 0:3afcd581558d 244 #if (ADC_RESOLUTION == 18)
pmallick 0:3afcd581558d 245 arr_indx += 2;
pmallick 0:3afcd581558d 246
pmallick 0:3afcd581558d 247 /* Track array to reach at the middle (9 bytes apart) to change the offsets */
pmallick 0:3afcd581558d 248 if (arr_indx == ((ADC_RESOLUTION / 2) -1)) {
pmallick 0:3afcd581558d 249 arr_indx++;
pmallick 0:3afcd581558d 250 offset_end = 2;
pmallick 0:3afcd581558d 251 mask = 0xff;
pmallick 0:3afcd581558d 252 } else {
pmallick 0:3afcd581558d 253 mask = (0xff >> offset_end);
pmallick 0:3afcd581558d 254 offset_end += 2;
pmallick 0:3afcd581558d 255 }
pmallick 0:3afcd581558d 256 #endif
pmallick 0:3afcd581558d 257
pmallick 0:3afcd581558d 258 if (sample_cnt >= NO_OF_SAMPLES) {
pmallick 0:3afcd581558d 259 break;
pmallick 0:3afcd581558d 260 }
pmallick 0:3afcd581558d 261
pmallick 0:3afcd581558d 262 mask <<= 1;
pmallick 0:3afcd581558d 263 }
pmallick 0:3afcd581558d 264
pmallick 0:3afcd581558d 265 /* Monitor buffer full status based on active buffer state */
pmallick 0:3afcd581558d 266 if (sample_cnt >= NO_OF_SAMPLES) {
pmallick 0:3afcd581558d 267 if (acq_buffer[0].state == BUF_AVAILABLE) {
pmallick 0:3afcd581558d 268 /* Buffer 0 is set FULL */
pmallick 0:3afcd581558d 269 acq_buffer[0].state = BUF_FULL;
pmallick 0:3afcd581558d 270
pmallick 0:3afcd581558d 271 /* Buffer 1 is set available to store next data samples */
pmallick 0:3afcd581558d 272 acq_buffer[1].state = BUF_AVAILABLE;
pmallick 0:3afcd581558d 273 } else if (acq_buffer[1].state == BUF_AVAILABLE) {
pmallick 0:3afcd581558d 274 /* Buffer 1 is set FULL */
pmallick 0:3afcd581558d 275 acq_buffer[1].state = BUF_FULL;
pmallick 0:3afcd581558d 276
pmallick 0:3afcd581558d 277 /* Buffer 0 is set available to store next data samples */
pmallick 0:3afcd581558d 278 acq_buffer[0].state = BUF_AVAILABLE;
pmallick 0:3afcd581558d 279 } else {
pmallick 0:3afcd581558d 280 /* This case should never reach */
pmallick 0:3afcd581558d 281 }
pmallick 0:3afcd581558d 282
pmallick 0:3afcd581558d 283 sample_cnt = 0;
pmallick 0:3afcd581558d 284 }
pmallick 0:3afcd581558d 285
pmallick 0:3afcd581558d 286 /* Trigger next conversion */
pmallick 0:3afcd581558d 287 (void)ad7606_convst(dev);
pmallick 0:3afcd581558d 288 }
pmallick 0:3afcd581558d 289 }
pmallick 0:3afcd581558d 290
pmallick 0:3afcd581558d 291
pmallick 0:3afcd581558d 292 /*!
pmallick 0:3afcd581558d 293 * @brief Function to start bakground ADC conversion
pmallick 0:3afcd581558d 294 * @return none
pmallick 0:3afcd581558d 295 */
pmallick 0:3afcd581558d 296 void start_background_data_conversion(void)
pmallick 0:3afcd581558d 297 {
pmallick 0:3afcd581558d 298 /* Start conversion */
pmallick 0:3afcd581558d 299 (void)ad7606_convst(dev);
pmallick 0:3afcd581558d 300 start_background_conversion = true;
pmallick 0:3afcd581558d 301 }
pmallick 0:3afcd581558d 302
pmallick 0:3afcd581558d 303
pmallick 0:3afcd581558d 304 /*!
pmallick 0:3afcd581558d 305 * @brief Function to stop bakground ADC conversion
pmallick 0:3afcd581558d 306 * @return none
pmallick 0:3afcd581558d 307 */
pmallick 0:3afcd581558d 308 void stop_background_data_conversion(void)
pmallick 0:3afcd581558d 309 {
pmallick 0:3afcd581558d 310 start_background_conversion = false;
pmallick 0:3afcd581558d 311 }