IIO firmware for the AD717x and AD411x family of devices.

Dependencies:   sdp_k1_sdram

Committer:
Janani Sunil
Date:
Tue Nov 15 17:05:27 2022 +0530
Revision:
3:0dcba3253ec1
Parent:
2:d0c2d3e1fb93
Added support for AD4116

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Janani Sunil 0:5ad86d8d396a 1 /***************************************************************************//**
Janani Sunil 0:5ad86d8d396a 2 * @file ad717x_data_capture.c
Janani Sunil 0:5ad86d8d396a 3 * @brief Source file for AD717x Data capture
Janani Sunil 0:5ad86d8d396a 4 ********************************************************************************
Janani Sunil 0:5ad86d8d396a 5 * Copyright (c) 2021-22 Analog Devices, Inc.
Janani Sunil 0:5ad86d8d396a 6 * All rights reserved.
Janani Sunil 0:5ad86d8d396a 7 *
Janani Sunil 0:5ad86d8d396a 8 * This software is proprietary to Analog Devices, Inc. and its licensors.
Janani Sunil 0:5ad86d8d396a 9 * By using this software you agree to the terms of the associated
Janani Sunil 0:5ad86d8d396a 10 * Analog Devices Software License Agreement.
Janani Sunil 0:5ad86d8d396a 11 *******************************************************************************/
Janani Sunil 0:5ad86d8d396a 12
Janani Sunil 0:5ad86d8d396a 13 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 14 /***************************** Include Files **********************************/
Janani Sunil 0:5ad86d8d396a 15 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 16
Janani Sunil 0:5ad86d8d396a 17 #include <stdbool.h>
Janani Sunil 0:5ad86d8d396a 18 #include "ad717x_data_capture.h"
Janani Sunil 0:5ad86d8d396a 19 #include "app_config.h"
Janani Sunil 0:5ad86d8d396a 20 #include "ad717x_iio.h"
Janani Sunil 0:5ad86d8d396a 21 #include "no_os_gpio.h"
Janani Sunil 0:5ad86d8d396a 22 #include "no_os_irq.h"
Janani Sunil 0:5ad86d8d396a 23 #include "ad717x_support.h"
Janani Sunil 0:5ad86d8d396a 24 #include "no_os_error.h"
Janani Sunil 0:5ad86d8d396a 25 #include "ad717x_user_config.h"
Janani Sunil 2:d0c2d3e1fb93 26 #include "no_os_delay.h"
Janani Sunil 0:5ad86d8d396a 27
Janani Sunil 0:5ad86d8d396a 28 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 29 /********************* Macros and Constants Definition ************************/
Janani Sunil 0:5ad86d8d396a 30 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 31
Janani Sunil 0:5ad86d8d396a 32 /* Timeout count to avoid stuck into potential infinite loop while checking
Janani Sunil 0:5ad86d8d396a 33 * for new data into an acquisition buffer. The actual timeout factor is determined
Janani Sunil 0:5ad86d8d396a 34 * through 'sampling_frequency' attribute of IIO app, but this period here makes sure
Janani Sunil 0:5ad86d8d396a 35 * we are not stuck into a forever loop in case data capture is interrupted
Janani Sunil 0:5ad86d8d396a 36 * or failed in between.
Janani Sunil 0:5ad86d8d396a 37 * Note: This timeout factor is dependent upon the MCU clock frequency. Below timeout
Janani Sunil 0:5ad86d8d396a 38 * is tested for SDP-K1 platform @180Mhz default core clock */
Janani Sunil 0:5ad86d8d396a 39 #define BUF_READ_TIMEOUT 0xffffffff
Janani Sunil 0:5ad86d8d396a 40
Janani Sunil 2:d0c2d3e1fb93 41 #define AD717x_CONV_TIMEOUT 10000
Janani Sunil 2:d0c2d3e1fb93 42
Janani Sunil 0:5ad86d8d396a 43 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 44 /******************** Variables and User Defined Data Types *******************/
Janani Sunil 0:5ad86d8d396a 45 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 46
Janani Sunil 0:5ad86d8d396a 47 /*
Janani Sunil 0:5ad86d8d396a 48 *@enum acq_buffer_state_e
Janani Sunil 0:5ad86d8d396a 49 *@details Data acquisition buffer states
Janani Sunil 0:5ad86d8d396a 50 **/
Janani Sunil 0:5ad86d8d396a 51 typedef enum {
Janani Sunil 0:5ad86d8d396a 52 BUF_AVAILABLE,
Janani Sunil 0:5ad86d8d396a 53 BUF_EMPTY,
Janani Sunil 0:5ad86d8d396a 54 BUF_FULL
Janani Sunil 0:5ad86d8d396a 55 } acq_buffer_state_e;
Janani Sunil 0:5ad86d8d396a 56
Janani Sunil 0:5ad86d8d396a 57 /*
Janani Sunil 0:5ad86d8d396a 58 *@struct acq_buf_t
Janani Sunil 0:5ad86d8d396a 59 *@details Data acquisition buffer parameters
Janani Sunil 0:5ad86d8d396a 60 **/
Janani Sunil 0:5ad86d8d396a 61 typedef struct {
Janani Sunil 0:5ad86d8d396a 62 acq_buffer_state_e state; // Buffer state
Janani Sunil 0:5ad86d8d396a 63 uint32_t wr_indx; // Buffer write index (incremented per sample read)
Janani Sunil 0:5ad86d8d396a 64 uint32_t rd_indx; // Buffer read index (incremented per sample read)
Janani Sunil 0:5ad86d8d396a 65 int8_t *wr_pdata; // Data buffer write pointer
Janani Sunil 0:5ad86d8d396a 66 int8_t *rd_pdata; // Data buffer read pointer
Janani Sunil 0:5ad86d8d396a 67 bool reindex_buffer; // Reindex buffer to 0th channel
Janani Sunil 0:5ad86d8d396a 68 } acq_buf_t;
Janani Sunil 0:5ad86d8d396a 69
Janani Sunil 0:5ad86d8d396a 70 /* ADC data acquisition buffers */
Janani Sunil 0:5ad86d8d396a 71 static volatile acq_buf_t acq_buffer;
Janani Sunil 0:5ad86d8d396a 72
Janani Sunil 0:5ad86d8d396a 73 /* Number of samples requested by IIO client */
Janani Sunil 0:5ad86d8d396a 74 static volatile uint32_t num_of_requested_samples = 0;
Janani Sunil 0:5ad86d8d396a 75
Janani Sunil 0:5ad86d8d396a 76 /* Number of active channels */
Janani Sunil 0:5ad86d8d396a 77 static volatile uint8_t num_of_active_channels;
Janani Sunil 0:5ad86d8d396a 78
Janani Sunil 0:5ad86d8d396a 79 /* ADC sample/raw data size in bytes */
Janani Sunil 0:5ad86d8d396a 80 static volatile uint8_t sample_size_in_bytes;
Janani Sunil 0:5ad86d8d396a 81
Janani Sunil 0:5ad86d8d396a 82 /* ADC data buffer */
Janani Sunil 0:5ad86d8d396a 83 #if !defined(USE_SDRAM_CAPTURE_BUFFER)
Janani Sunil 0:5ad86d8d396a 84 int8_t adc_data_buffer[DATA_BUFFER_SIZE] = { 0 };
Janani Sunil 0:5ad86d8d396a 85 #endif
Janani Sunil 0:5ad86d8d396a 86
Janani Sunil 0:5ad86d8d396a 87 /* List of input channels to be captured */
Janani Sunil 0:5ad86d8d396a 88 static volatile uint8_t input_channels[NUMBER_OF_CHANNELS];
Janani Sunil 0:5ad86d8d396a 89
Janani Sunil 0:5ad86d8d396a 90 /* Flag to indicate data capture status */
Janani Sunil 0:5ad86d8d396a 91 static volatile bool start_cont_data_capture = false;
Janani Sunil 0:5ad86d8d396a 92
Janani Sunil 0:5ad86d8d396a 93 /* Max available buffer size (after considering the data alignment with IIO buffer) */
Janani Sunil 0:5ad86d8d396a 94 static volatile uint32_t max_buffer_sz;
Janani Sunil 0:5ad86d8d396a 95
Janani Sunil 0:5ad86d8d396a 96 /* Current active channel index */
Janani Sunil 0:5ad86d8d396a 97 static volatile uint8_t chn_indx;
Janani Sunil 0:5ad86d8d396a 98
Janani Sunil 0:5ad86d8d396a 99 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 100 /************************** Functions Declaration *****************************/
Janani Sunil 0:5ad86d8d396a 101 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 102
Janani Sunil 0:5ad86d8d396a 103 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 104 /************************** Functions Definition ******************************/
Janani Sunil 0:5ad86d8d396a 105 /******************************************************************************/
Janani Sunil 0:5ad86d8d396a 106
Janani Sunil 0:5ad86d8d396a 107 /*!
Janani Sunil 0:5ad86d8d396a 108 * @brief Reset the data capture specific variables
Janani Sunil 0:5ad86d8d396a 109 * @return none
Janani Sunil 0:5ad86d8d396a 110 */
Janani Sunil 0:5ad86d8d396a 111 static void reset_data_capture(void)
Janani Sunil 0:5ad86d8d396a 112 {
Janani Sunil 0:5ad86d8d396a 113 /* Reset data capture flags */
Janani Sunil 0:5ad86d8d396a 114 num_of_active_channels = 0;
Janani Sunil 0:5ad86d8d396a 115 start_cont_data_capture = false;
Janani Sunil 0:5ad86d8d396a 116
Janani Sunil 0:5ad86d8d396a 117 /* Reset acquisition buffer states and clear old data */
Janani Sunil 0:5ad86d8d396a 118 acq_buffer.state = BUF_EMPTY;
Janani Sunil 0:5ad86d8d396a 119 acq_buffer.wr_indx = 0;
Janani Sunil 0:5ad86d8d396a 120 acq_buffer.rd_indx = 0;
Janani Sunil 0:5ad86d8d396a 121 acq_buffer.reindex_buffer = false;
Janani Sunil 0:5ad86d8d396a 122
Janani Sunil 0:5ad86d8d396a 123 acq_buffer.wr_pdata = adc_data_buffer;
Janani Sunil 0:5ad86d8d396a 124 acq_buffer.rd_pdata = adc_data_buffer;
Janani Sunil 0:5ad86d8d396a 125 max_buffer_sz = DATA_BUFFER_SIZE;
Janani Sunil 0:5ad86d8d396a 126 }
Janani Sunil 0:5ad86d8d396a 127
Janani Sunil 0:5ad86d8d396a 128
Janani Sunil 0:5ad86d8d396a 129 /*!
Janani Sunil 0:5ad86d8d396a 130 * @brief Trigger a data capture in continuous/burst mode
Janani Sunil 0:5ad86d8d396a 131 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 132 */
Janani Sunil 0:5ad86d8d396a 133 static int32_t adc_start_data_capture(void)
Janani Sunil 0:5ad86d8d396a 134 {
Janani Sunil 0:5ad86d8d396a 135 /* Set ADC to Continuous conversion mode */
Janani Sunil 0:5ad86d8d396a 136 return ad717x_set_adc_mode(p_ad717x_dev_inst, CONTINUOUS);
Janani Sunil 0:5ad86d8d396a 137 }
Janani Sunil 0:5ad86d8d396a 138
Janani Sunil 0:5ad86d8d396a 139
Janani Sunil 0:5ad86d8d396a 140 /*!
Janani Sunil 0:5ad86d8d396a 141 * @brief Stop a data capture operation
Janani Sunil 0:5ad86d8d396a 142 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 143 */
Janani Sunil 0:5ad86d8d396a 144 static int32_t adc_stop_data_capture(void)
Janani Sunil 0:5ad86d8d396a 145 {
Janani Sunil 0:5ad86d8d396a 146 /* Set ADC to Standby mode */
Janani Sunil 0:5ad86d8d396a 147 return ad717x_set_adc_mode(p_ad717x_dev_inst, STANDBY);
Janani Sunil 0:5ad86d8d396a 148 }
Janani Sunil 0:5ad86d8d396a 149
Janani Sunil 0:5ad86d8d396a 150
Janani Sunil 0:5ad86d8d396a 151 /*!
Janani Sunil 0:5ad86d8d396a 152 * @brief Function to prepare the data ADC capture for new READBUFF
Janani Sunil 0:5ad86d8d396a 153 * request from IIO client (for active channels)
Janani Sunil 0:5ad86d8d396a 154 * @param chn_mask[in] - Channels to enable for data capturing
Janani Sunil 0:5ad86d8d396a 155 * @param num_of_chns[in] - ADC channel count
Janani Sunil 0:5ad86d8d396a 156 * @param sample_size[in] - Sample size in bytes
Janani Sunil 0:5ad86d8d396a 157 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 158 */
Janani Sunil 0:5ad86d8d396a 159 int32_t prepare_data_transfer(uint32_t ch_mask, uint8_t num_of_chns,
Janani Sunil 0:5ad86d8d396a 160 uint8_t sample_size)
Janani Sunil 0:5ad86d8d396a 161 {
Janani Sunil 2:d0c2d3e1fb93 162 uint32_t mask = 0x1;
Janani Sunil 0:5ad86d8d396a 163 int32_t ret;
Janani Sunil 0:5ad86d8d396a 164 uint8_t ch_id;
Janani Sunil 0:5ad86d8d396a 165
Janani Sunil 0:5ad86d8d396a 166 /* Reset data capture module */
Janani Sunil 0:5ad86d8d396a 167 reset_data_capture();
Janani Sunil 0:5ad86d8d396a 168
Janani Sunil 0:5ad86d8d396a 169 sample_size_in_bytes = sample_size;
Janani Sunil 0:5ad86d8d396a 170
Janani Sunil 0:5ad86d8d396a 171 /* Enable Active channels requested and Disable the remaining */
Janani Sunil 0:5ad86d8d396a 172 for (ch_id = 0;
Janani Sunil 0:5ad86d8d396a 173 ch_id < NUMBER_OF_CHANNELS; ch_id++) {
Janani Sunil 0:5ad86d8d396a 174 if (ch_mask & mask) {
Janani Sunil 0:5ad86d8d396a 175 ret = ad717x_set_channel_status(p_ad717x_dev_inst, ch_id, true);
Janani Sunil 0:5ad86d8d396a 176 if (ret) {
Janani Sunil 0:5ad86d8d396a 177 return ret;
Janani Sunil 0:5ad86d8d396a 178 }
Janani Sunil 0:5ad86d8d396a 179 num_of_active_channels++;
Janani Sunil 0:5ad86d8d396a 180 } else {
Janani Sunil 0:5ad86d8d396a 181 ret = ad717x_set_channel_status(p_ad717x_dev_inst, ch_id, false);
Janani Sunil 0:5ad86d8d396a 182 if (ret) {
Janani Sunil 0:5ad86d8d396a 183 return ret;
Janani Sunil 0:5ad86d8d396a 184 }
Janani Sunil 0:5ad86d8d396a 185 }
Janani Sunil 0:5ad86d8d396a 186 mask <<= 1;
Janani Sunil 0:5ad86d8d396a 187 }
Janani Sunil 0:5ad86d8d396a 188
Janani Sunil 0:5ad86d8d396a 189 /* Trigger continuous data capture */
Janani Sunil 0:5ad86d8d396a 190 #if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE)
Janani Sunil 0:5ad86d8d396a 191
Janani Sunil 0:5ad86d8d396a 192 /* Trigger continuous data capture */
Janani Sunil 0:5ad86d8d396a 193 ret = adc_start_data_capture();
Janani Sunil 0:5ad86d8d396a 194 if (ret) {
Janani Sunil 0:5ad86d8d396a 195 return ret;
Janani Sunil 0:5ad86d8d396a 196 }
Janani Sunil 0:5ad86d8d396a 197
Janani Sunil 0:5ad86d8d396a 198 acq_buffer.state = BUF_AVAILABLE;
Janani Sunil 0:5ad86d8d396a 199 start_cont_data_capture = true;
Janani Sunil 0:5ad86d8d396a 200
Janani Sunil 0:5ad86d8d396a 201 /* Enable Continuous read operation */
Janani Sunil 0:5ad86d8d396a 202 ret = ad717x_enable_cont_read(p_ad717x_dev_inst, true);
Janani Sunil 0:5ad86d8d396a 203 if (ret) {
Janani Sunil 0:5ad86d8d396a 204 return ret;
Janani Sunil 0:5ad86d8d396a 205 }
Janani Sunil 0:5ad86d8d396a 206
Janani Sunil 0:5ad86d8d396a 207 /* Pull the cs line low to detect the EOC bit during data capture */
Janani Sunil 0:5ad86d8d396a 208 ret = no_os_gpio_set_value(csb_gpio, NO_OS_GPIO_LOW);
Janani Sunil 0:5ad86d8d396a 209 if (ret) {
Janani Sunil 0:5ad86d8d396a 210 return ret;
Janani Sunil 0:5ad86d8d396a 211 }
Janani Sunil 0:5ad86d8d396a 212
Janani Sunil 0:5ad86d8d396a 213 ret = no_os_irq_enable(external_int_desc, IRQ_INT_ID);
Janani Sunil 0:5ad86d8d396a 214 if (ret) {
Janani Sunil 0:5ad86d8d396a 215 return ret;
Janani Sunil 0:5ad86d8d396a 216 }
Janani Sunil 0:5ad86d8d396a 217 #endif
Janani Sunil 0:5ad86d8d396a 218
Janani Sunil 0:5ad86d8d396a 219 return 0;
Janani Sunil 0:5ad86d8d396a 220 }
Janani Sunil 0:5ad86d8d396a 221
Janani Sunil 0:5ad86d8d396a 222
Janani Sunil 0:5ad86d8d396a 223 /*!
Janani Sunil 0:5ad86d8d396a 224 * @brief Function to end data capture
Janani Sunil 0:5ad86d8d396a 225 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 226 */
Janani Sunil 0:5ad86d8d396a 227 int32_t end_data_transfer(void)
Janani Sunil 0:5ad86d8d396a 228 {
Janani Sunil 2:d0c2d3e1fb93 229 int32_t ret = 0;
Janani Sunil 0:5ad86d8d396a 230 start_cont_data_capture = false;
Janani Sunil 2:d0c2d3e1fb93 231 uint32_t adc_raw_data;
Janani Sunil 2:d0c2d3e1fb93 232 uint8_t rdy_value = NO_OS_GPIO_LOW;
Janani Sunil 2:d0c2d3e1fb93 233 uint32_t timeout = AD717x_CONV_TIMEOUT;
Janani Sunil 0:5ad86d8d396a 234
Janani Sunil 0:5ad86d8d396a 235 #if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE)
Janani Sunil 2:d0c2d3e1fb93 236 ret = no_os_irq_disable(external_int_desc, IRQ_INT_ID);
Janani Sunil 2:d0c2d3e1fb93 237 if (ret) {
Janani Sunil 2:d0c2d3e1fb93 238 return ret;
Janani Sunil 2:d0c2d3e1fb93 239 }
Janani Sunil 2:d0c2d3e1fb93 240
Janani Sunil 2:d0c2d3e1fb93 241 /* Read the data register when RDY is low to exit continuous read mode */
Janani Sunil 2:d0c2d3e1fb93 242 do {
Janani Sunil 2:d0c2d3e1fb93 243 ret = no_os_gpio_get_value(rdy_gpio, &rdy_value);
Janani Sunil 2:d0c2d3e1fb93 244 if (ret) {
Janani Sunil 2:d0c2d3e1fb93 245 return ret;
Janani Sunil 2:d0c2d3e1fb93 246 }
Janani Sunil 2:d0c2d3e1fb93 247 timeout--;
Janani Sunil 2:d0c2d3e1fb93 248 } while ((rdy_value != NO_OS_GPIO_LOW) && (timeout > 0));
Janani Sunil 2:d0c2d3e1fb93 249
Janani Sunil 2:d0c2d3e1fb93 250 if (timeout == 0) {
Janani Sunil 2:d0c2d3e1fb93 251 return -ETIMEDOUT;
Janani Sunil 2:d0c2d3e1fb93 252 }
Janani Sunil 2:d0c2d3e1fb93 253
Janani Sunil 2:d0c2d3e1fb93 254 ret = AD717X_ReadData(p_ad717x_dev_inst, &adc_raw_data);
Janani Sunil 2:d0c2d3e1fb93 255 if (ret) {
Janani Sunil 2:d0c2d3e1fb93 256 return ret;
Janani Sunil 2:d0c2d3e1fb93 257 }
Janani Sunil 2:d0c2d3e1fb93 258
Janani Sunil 0:5ad86d8d396a 259 /* Disable continous read mode */
Janani Sunil 0:5ad86d8d396a 260 ret = ad717x_enable_cont_read(p_ad717x_dev_inst, false);
Janani Sunil 0:5ad86d8d396a 261 if (ret) {
Janani Sunil 0:5ad86d8d396a 262 return ret;
Janani Sunil 0:5ad86d8d396a 263 }
Janani Sunil 0:5ad86d8d396a 264 #endif
Janani Sunil 0:5ad86d8d396a 265
Janani Sunil 0:5ad86d8d396a 266 /* Reset data capture module specific flags and variables */
Janani Sunil 0:5ad86d8d396a 267 reset_data_capture();
Janani Sunil 0:5ad86d8d396a 268
Janani Sunil 0:5ad86d8d396a 269 /* Stop ADC data capture */
Janani Sunil 0:5ad86d8d396a 270 return adc_stop_data_capture();
Janani Sunil 0:5ad86d8d396a 271 }
Janani Sunil 0:5ad86d8d396a 272
Janani Sunil 0:5ad86d8d396a 273
Janani Sunil 0:5ad86d8d396a 274 /*!
Janani Sunil 0:5ad86d8d396a 275 * @brief Capture requested number of ADC samples in burst mode
Janani Sunil 0:5ad86d8d396a 276 * @param pbuf[out] - Pointer to ADC data buffer
Janani Sunil 0:5ad86d8d396a 277 * @param nb_of_samples[in] - Number of samples to be read
Janani Sunil 0:5ad86d8d396a 278 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 279 */
Janani Sunil 0:5ad86d8d396a 280 static int32_t read_burst_data(int8_t *pbuf, uint32_t nb_of_samples)
Janani Sunil 0:5ad86d8d396a 281 {
Janani Sunil 0:5ad86d8d396a 282 uint32_t sample_index = 0;
Janani Sunil 0:5ad86d8d396a 283 int32_t adc_raw_data;
Janani Sunil 0:5ad86d8d396a 284 int32_t ret;
Janani Sunil 0:5ad86d8d396a 285
Janani Sunil 0:5ad86d8d396a 286 if (adc_start_data_capture() != 0) {
Janani Sunil 0:5ad86d8d396a 287 return -EINVAL;
Janani Sunil 0:5ad86d8d396a 288 }
Janani Sunil 0:5ad86d8d396a 289
Janani Sunil 0:5ad86d8d396a 290 while (sample_index < nb_of_samples) {
Janani Sunil 0:5ad86d8d396a 291 /* Wait for the RDY Bit to go low to notify end of conversion */
Janani Sunil 0:5ad86d8d396a 292 ret = AD717X_WaitForReady(p_ad717x_dev_inst, AD717X_CONV_TIMEOUT);
Janani Sunil 0:5ad86d8d396a 293 if (ret) {
Janani Sunil 0:5ad86d8d396a 294 return ret;
Janani Sunil 0:5ad86d8d396a 295 }
Janani Sunil 0:5ad86d8d396a 296
Janani Sunil 0:5ad86d8d396a 297 /* Read the converted data from the Data register */
Janani Sunil 0:5ad86d8d396a 298 ret = AD717X_ReadData(p_ad717x_dev_inst, &adc_raw_data);
Janani Sunil 0:5ad86d8d396a 299 if (ret) {
Janani Sunil 0:5ad86d8d396a 300 return ret;
Janani Sunil 0:5ad86d8d396a 301 }
Janani Sunil 0:5ad86d8d396a 302
Janani Sunil 0:5ad86d8d396a 303 memcpy((uint8_t*)pbuf, &adc_raw_data, sample_size_in_bytes);
Janani Sunil 0:5ad86d8d396a 304 sample_index++;
Janani Sunil 0:5ad86d8d396a 305 pbuf += sample_size_in_bytes;
Janani Sunil 0:5ad86d8d396a 306 }
Janani Sunil 0:5ad86d8d396a 307
Janani Sunil 0:5ad86d8d396a 308 /* Stop any active conversion */
Janani Sunil 0:5ad86d8d396a 309 adc_stop_data_capture();
Janani Sunil 0:5ad86d8d396a 310
Janani Sunil 0:5ad86d8d396a 311 return 0;
Janani Sunil 0:5ad86d8d396a 312 }
Janani Sunil 0:5ad86d8d396a 313
Janani Sunil 0:5ad86d8d396a 314
Janani Sunil 0:5ad86d8d396a 315 /*!
Janani Sunil 0:5ad86d8d396a 316 * @brief Perform buffer read operations to read requested samples
Janani Sunil 0:5ad86d8d396a 317 * @param nb_of_samples[in] - Requested number of samples to read
Janani Sunil 0:5ad86d8d396a 318 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 319 */
Janani Sunil 0:5ad86d8d396a 320 static int32_t buffer_read_operations(uint32_t nb_of_samples)
Janani Sunil 0:5ad86d8d396a 321 {
Janani Sunil 0:5ad86d8d396a 322 uint32_t timeout = BUF_READ_TIMEOUT;
Janani Sunil 0:5ad86d8d396a 323 int32_t offset;
Janani Sunil 0:5ad86d8d396a 324
Janani Sunil 0:5ad86d8d396a 325 /* Wait until requested samples are available in the buffer to read */
Janani Sunil 0:5ad86d8d396a 326 do {
Janani Sunil 0:5ad86d8d396a 327 if (acq_buffer.wr_indx >= acq_buffer.rd_indx) {
Janani Sunil 0:5ad86d8d396a 328 offset = acq_buffer.wr_indx - acq_buffer.rd_indx;
Janani Sunil 0:5ad86d8d396a 329 } else {
Janani Sunil 0:5ad86d8d396a 330 offset = max_buffer_sz + (acq_buffer.wr_indx - acq_buffer.rd_indx);
Janani Sunil 0:5ad86d8d396a 331 }
Janani Sunil 0:5ad86d8d396a 332
Janani Sunil 0:5ad86d8d396a 333 timeout--;
Janani Sunil 0:5ad86d8d396a 334 } while ((offset < (int32_t)(nb_of_samples)) && (timeout > 0));
Janani Sunil 0:5ad86d8d396a 335
Janani Sunil 0:5ad86d8d396a 336 if (timeout == 0) {
Janani Sunil 0:5ad86d8d396a 337 /* This returns the empty buffer */
Janani Sunil 0:5ad86d8d396a 338 return -EIO;
Janani Sunil 0:5ad86d8d396a 339 }
Janani Sunil 0:5ad86d8d396a 340
Janani Sunil 0:5ad86d8d396a 341 if (acq_buffer.rd_indx >= max_buffer_sz) {
Janani Sunil 0:5ad86d8d396a 342 acq_buffer.rd_indx = 0;
Janani Sunil 0:5ad86d8d396a 343 }
Janani Sunil 0:5ad86d8d396a 344
Janani Sunil 0:5ad86d8d396a 345 return 0;
Janani Sunil 0:5ad86d8d396a 346 }
Janani Sunil 0:5ad86d8d396a 347
Janani Sunil 0:5ad86d8d396a 348
Janani Sunil 0:5ad86d8d396a 349 /*!
Janani Sunil 0:5ad86d8d396a 350 * @brief Perform buffer write operations such as buffer full or empty
Janani Sunil 0:5ad86d8d396a 351 * check, resetting buffer index and pointers, etc
Janani Sunil 0:5ad86d8d396a 352 * @return none
Janani Sunil 0:5ad86d8d396a 353 */
Janani Sunil 0:5ad86d8d396a 354 static void buffer_write_operations(void)
Janani Sunil 0:5ad86d8d396a 355 {
Janani Sunil 0:5ad86d8d396a 356 acq_buffer.wr_indx++;
Janani Sunil 0:5ad86d8d396a 357
Janani Sunil 0:5ad86d8d396a 358 /* Perform buffer full check and operations */
Janani Sunil 0:5ad86d8d396a 359 if (acq_buffer.wr_indx >= max_buffer_sz) {
Janani Sunil 0:5ad86d8d396a 360 if ((acq_buffer.rd_indx >= num_of_requested_samples)
Janani Sunil 0:5ad86d8d396a 361 && (acq_buffer.rd_indx != 0)) {
Janani Sunil 0:5ad86d8d396a 362 /* Reset buffer write index and write pointer when enough
Janani Sunil 0:5ad86d8d396a 363 * space available in the buffer to wrap to start */
Janani Sunil 0:5ad86d8d396a 364 acq_buffer.wr_indx = 0;
Janani Sunil 0:5ad86d8d396a 365
Janani Sunil 0:5ad86d8d396a 366 acq_buffer.wr_pdata = adc_data_buffer;
Janani Sunil 0:5ad86d8d396a 367 if (acq_buffer.rd_indx >= max_buffer_sz) {
Janani Sunil 0:5ad86d8d396a 368 /* Wrap the read index and read pointer to start of buffer
Janani Sunil 0:5ad86d8d396a 369 * if buffer is completely read/emptied */
Janani Sunil 0:5ad86d8d396a 370 acq_buffer.rd_indx = 0;
Janani Sunil 0:5ad86d8d396a 371 acq_buffer.rd_pdata = adc_data_buffer;
Janani Sunil 0:5ad86d8d396a 372 }
Janani Sunil 0:5ad86d8d396a 373
Janani Sunil 0:5ad86d8d396a 374 acq_buffer.state = BUF_AVAILABLE;
Janani Sunil 0:5ad86d8d396a 375 } else {
Janani Sunil 0:5ad86d8d396a 376 /* Wait until enough space available to wrap buffer write index
Janani Sunil 0:5ad86d8d396a 377 * at the start of buffer */
Janani Sunil 0:5ad86d8d396a 378 acq_buffer.wr_indx = max_buffer_sz;
Janani Sunil 0:5ad86d8d396a 379 acq_buffer.state = BUF_FULL;
Janani Sunil 0:5ad86d8d396a 380 acq_buffer.reindex_buffer = true;
Janani Sunil 0:5ad86d8d396a 381 }
Janani Sunil 0:5ad86d8d396a 382 }
Janani Sunil 0:5ad86d8d396a 383 }
Janani Sunil 0:5ad86d8d396a 384
Janani Sunil 0:5ad86d8d396a 385
Janani Sunil 0:5ad86d8d396a 386 /*!
Janani Sunil 0:5ad86d8d396a 387 * @brief Read requested number of ADC samples in continuous mode
Janani Sunil 0:5ad86d8d396a 388 * @param pbuf[in] - Pointer to data buffer
Janani Sunil 0:5ad86d8d396a 389 * @param nb_of_samples[in] - Number of samples to read
Janani Sunil 0:5ad86d8d396a 390 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 391 * @note The actual sample capturing happens through interrupt. This
Janani Sunil 0:5ad86d8d396a 392 * function tracks the buffer read pointer to read block of data
Janani Sunil 0:5ad86d8d396a 393 */
Janani Sunil 0:5ad86d8d396a 394 static int32_t read_continuous_conv_data(int8_t **pbuf, uint32_t nb_of_samples)
Janani Sunil 0:5ad86d8d396a 395 {
Janani Sunil 0:5ad86d8d396a 396 volatile int8_t *rd_addr;
Janani Sunil 0:5ad86d8d396a 397 int32_t ret;
Janani Sunil 0:5ad86d8d396a 398
Janani Sunil 0:5ad86d8d396a 399 /* Determine the max available buffer size based on the requested
Janani Sunil 0:5ad86d8d396a 400 * samples count and actual avilable buffer size. Buffer should be
Janani Sunil 0:5ad86d8d396a 401 * capable of holding all requested 'n' samples from previous write
Janani Sunil 0:5ad86d8d396a 402 * index upto to the end of buffer, as data is read linearly
Janani Sunil 0:5ad86d8d396a 403 * from adc buffer in IIO library.
Janani Sunil 0:5ad86d8d396a 404 * E.g. If actual buffer size is 2048 samples and requested samples
Janani Sunil 0:5ad86d8d396a 405 * are 1600, max available buffer size is actually 1600. So in given
Janani Sunil 0:5ad86d8d396a 406 * iteration, only 1600 samples will be stored into buffer and after
Janani Sunil 0:5ad86d8d396a 407 * that buffer indexes will be wrapped to a start of buffer. If index
Janani Sunil 0:5ad86d8d396a 408 * is not wrapped, the next 1600 requested samples won't accomodate into
Janani Sunil 0:5ad86d8d396a 409 * remaining 448 samples space. As buffer is read in linear fashion, the
Janani Sunil 0:5ad86d8d396a 410 * read index can't be wrapped to start of buffer to read remaining samples.
Janani Sunil 0:5ad86d8d396a 411 * So max available space in this case is 2048 but only utilized space
Janani Sunil 0:5ad86d8d396a 412 * will be 1600 in single read buffer request from IIO client.
Janani Sunil 0:5ad86d8d396a 413 **/
Janani Sunil 0:5ad86d8d396a 414 max_buffer_sz = ((DATA_BUFFER_SIZE / sample_size_in_bytes) /
Janani Sunil 0:5ad86d8d396a 415 nb_of_samples) * nb_of_samples;
Janani Sunil 0:5ad86d8d396a 416
Janani Sunil 0:5ad86d8d396a 417 ret = buffer_read_operations(nb_of_samples);
Janani Sunil 0:5ad86d8d396a 418 if (ret) {
Janani Sunil 0:5ad86d8d396a 419 return ret;
Janani Sunil 0:5ad86d8d396a 420 }
Janani Sunil 0:5ad86d8d396a 421
Janani Sunil 0:5ad86d8d396a 422 /* Get the next read address */
Janani Sunil 0:5ad86d8d396a 423 rd_addr = (volatile int8_t *)(acq_buffer.rd_pdata + (acq_buffer.rd_indx *
Janani Sunil 0:5ad86d8d396a 424 sample_size_in_bytes));
Janani Sunil 0:5ad86d8d396a 425 acq_buffer.rd_indx += nb_of_samples;
Janani Sunil 0:5ad86d8d396a 426
Janani Sunil 0:5ad86d8d396a 427 /* Update the IIO buffer pointer to point to next read start location */
Janani Sunil 0:5ad86d8d396a 428 *pbuf = rd_addr;
Janani Sunil 0:5ad86d8d396a 429
Janani Sunil 0:5ad86d8d396a 430 return 0;
Janani Sunil 0:5ad86d8d396a 431 }
Janani Sunil 0:5ad86d8d396a 432
Janani Sunil 0:5ad86d8d396a 433
Janani Sunil 0:5ad86d8d396a 434 /*!
Janani Sunil 0:5ad86d8d396a 435 * @brief Read ADC raw data for recently sampled channel
Janani Sunil 0:5ad86d8d396a 436 * @param adc_data[out] - Pointer to adc data read variable
Janani Sunil 0:5ad86d8d396a 437 * @param input_chn[in] - Input channel
Janani Sunil 0:5ad86d8d396a 438 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 439 * @note This function is intended to call from the conversion end trigger
Janani Sunil 0:5ad86d8d396a 440 * event. Therefore, this function should just read raw ADC data
Janani Sunil 0:5ad86d8d396a 441 * without further monitoring conversion end event
Janani Sunil 0:5ad86d8d396a 442 */
Janani Sunil 0:5ad86d8d396a 443 static int32_t adc_read_converted_sample(uint32_t *adc_data, uint8_t input_chn)
Janani Sunil 0:5ad86d8d396a 444 {
Janani Sunil 0:5ad86d8d396a 445 uint32_t adc_raw = 0;
Janani Sunil 0:5ad86d8d396a 446 int32_t ret;
Janani Sunil 0:5ad86d8d396a 447 uint8_t buffer[3] = { 0, 0, 0 };
Janani Sunil 0:5ad86d8d396a 448 uint8_t buffer_index;
Janani Sunil 0:5ad86d8d396a 449
Janani Sunil 0:5ad86d8d396a 450 if (!adc_data) {
Janani Sunil 0:5ad86d8d396a 451 return -EINVAL;
Janani Sunil 0:5ad86d8d396a 452 }
Janani Sunil 0:5ad86d8d396a 453
Janani Sunil 0:5ad86d8d396a 454 ret = no_os_spi_write_and_read(p_ad717x_dev_inst->spi_desc, buffer,
Janani Sunil 0:5ad86d8d396a 455 sizeof(buffer));
Janani Sunil 0:5ad86d8d396a 456 if (ret) {
Janani Sunil 0:5ad86d8d396a 457 return ret;
Janani Sunil 0:5ad86d8d396a 458 }
Janani Sunil 0:5ad86d8d396a 459
Janani Sunil 0:5ad86d8d396a 460 ret = no_os_gpio_set_value(csb_gpio, NO_OS_GPIO_LOW);
Janani Sunil 0:5ad86d8d396a 461 if (ret) {
Janani Sunil 0:5ad86d8d396a 462 return ret;
Janani Sunil 0:5ad86d8d396a 463 }
Janani Sunil 0:5ad86d8d396a 464
Janani Sunil 0:5ad86d8d396a 465 for (buffer_index = 0; buffer_index < sizeof(buffer); buffer_index++) {
Janani Sunil 0:5ad86d8d396a 466 adc_raw <<= 8;
Janani Sunil 0:5ad86d8d396a 467 adc_raw += buffer[buffer_index];
Janani Sunil 0:5ad86d8d396a 468 }
Janani Sunil 0:5ad86d8d396a 469
Janani Sunil 0:5ad86d8d396a 470 /* Enable external interrupts */
Janani Sunil 0:5ad86d8d396a 471 ret = no_os_irq_enable(external_int_desc, IRQ_INT_ID);
Janani Sunil 0:5ad86d8d396a 472 if (ret) {
Janani Sunil 0:5ad86d8d396a 473 return ret;
Janani Sunil 0:5ad86d8d396a 474 }
Janani Sunil 0:5ad86d8d396a 475
Janani Sunil 0:5ad86d8d396a 476 *adc_data = adc_raw;
Janani Sunil 0:5ad86d8d396a 477
Janani Sunil 0:5ad86d8d396a 478 return 0;
Janani Sunil 0:5ad86d8d396a 479 }
Janani Sunil 0:5ad86d8d396a 480
Janani Sunil 0:5ad86d8d396a 481
Janani Sunil 0:5ad86d8d396a 482 /*!
Janani Sunil 0:5ad86d8d396a 483 * @brief This is an ISR (Interrupt Service Routine) to monitor end of conversion event.
Janani Sunil 0:5ad86d8d396a 484 * @param ctx[in] - Callback context (unused)
Janani Sunil 0:5ad86d8d396a 485 * @param event[in] - Callback event (unused)
Janani Sunil 0:5ad86d8d396a 486 * @param extra[in] - Callback extra (unused)
Janani Sunil 0:5ad86d8d396a 487 * @return none
Janani Sunil 0:5ad86d8d396a 488 * @details This is an Interrupt callback function/ISR invoked in synchronous/asynchronous
Janani Sunil 0:5ad86d8d396a 489 * manner depending upon the application implementation. The conversion results
Janani Sunil 0:5ad86d8d396a 490 * are read into acquisition buffer and control continue to sample next channel.
Janani Sunil 0:5ad86d8d396a 491 * This continues until conversion is stopped (through IIO client command)
Janani Sunil 0:5ad86d8d396a 492 */
Janani Sunil 0:5ad86d8d396a 493 void data_capture_callback(void *ctx, uint32_t event, void *extra)
Janani Sunil 0:5ad86d8d396a 494 {
Janani Sunil 0:5ad86d8d396a 495 uint32_t adc_sample;
Janani Sunil 0:5ad86d8d396a 496 volatile uint8_t *wr_addr;
Janani Sunil 0:5ad86d8d396a 497
Janani Sunil 0:5ad86d8d396a 498 /* The callback function is triggered when a falling edge is detected
Janani Sunil 0:5ad86d8d396a 499 * on the MISO pin. The first falling edge on the MISO pin indicates the
Janani Sunil 0:5ad86d8d396a 500 * end of conversion bit. The converted sample is also recieved on the MISO line and
Janani Sunil 0:5ad86d8d396a 501 * any falling edge during SPI tracsaction would be interpreted as interrupt and results
Janani Sunil 0:5ad86d8d396a 502 * in nested interrupts. Hence disabling the external interrupt as soon as the control
Janani Sunil 0:5ad86d8d396a 503 * enters the callback function due to an EOC event.
Janani Sunil 0:5ad86d8d396a 504 */
Janani Sunil 0:5ad86d8d396a 505 no_os_irq_disable(external_int_desc, IRQ_INT_ID);
Janani Sunil 0:5ad86d8d396a 506
Janani Sunil 0:5ad86d8d396a 507 if (start_cont_data_capture == true) {
Janani Sunil 0:5ad86d8d396a 508 /* Read the sample for channel which has been sampled recently */
Janani Sunil 0:5ad86d8d396a 509 if (adc_read_converted_sample(&adc_sample,
Janani Sunil 0:5ad86d8d396a 510 input_channels[chn_indx]) == 0) {
Janani Sunil 0:5ad86d8d396a 511 do {
Janani Sunil 0:5ad86d8d396a 512 if (acq_buffer.state == BUF_AVAILABLE) {
Janani Sunil 0:5ad86d8d396a 513 if (acq_buffer.reindex_buffer) {
Janani Sunil 0:5ad86d8d396a 514 /* Buffer refilling must start with first active channel data
Janani Sunil 0:5ad86d8d396a 515 * for IIO client to synchronize the buffered data */
Janani Sunil 0:5ad86d8d396a 516 if (chn_indx != 0) {
Janani Sunil 0:5ad86d8d396a 517 break;
Janani Sunil 0:5ad86d8d396a 518 }
Janani Sunil 0:5ad86d8d396a 519 acq_buffer.reindex_buffer = false;
Janani Sunil 0:5ad86d8d396a 520 }
Janani Sunil 0:5ad86d8d396a 521
Janani Sunil 0:5ad86d8d396a 522 /* Copy adc samples into acquisition buffer to transport over
Janani Sunil 0:5ad86d8d396a 523 * communication link */
Janani Sunil 0:5ad86d8d396a 524 wr_addr = (volatile uint8_t *)(acq_buffer.wr_pdata + (acq_buffer.wr_indx *
Janani Sunil 0:5ad86d8d396a 525 sample_size_in_bytes));
Janani Sunil 0:5ad86d8d396a 526 memcpy((uint8_t *)wr_addr, &adc_sample, sample_size_in_bytes);
Janani Sunil 0:5ad86d8d396a 527 }
Janani Sunil 0:5ad86d8d396a 528
Janani Sunil 0:5ad86d8d396a 529 /* Perform buffer write operations */
Janani Sunil 0:5ad86d8d396a 530 buffer_write_operations();
Janani Sunil 0:5ad86d8d396a 531 } while (0);
Janani Sunil 0:5ad86d8d396a 532
Janani Sunil 0:5ad86d8d396a 533 /* Track the count for recently sampled channel */
Janani Sunil 0:5ad86d8d396a 534 chn_indx++;
Janani Sunil 0:5ad86d8d396a 535 if (chn_indx >= num_of_active_channels) {
Janani Sunil 0:5ad86d8d396a 536 chn_indx = 0;
Janani Sunil 0:5ad86d8d396a 537 }
Janani Sunil 0:5ad86d8d396a 538 }
Janani Sunil 0:5ad86d8d396a 539 }
Janani Sunil 0:5ad86d8d396a 540 }
Janani Sunil 0:5ad86d8d396a 541
Janani Sunil 0:5ad86d8d396a 542
Janani Sunil 0:5ad86d8d396a 543 /*!
Janani Sunil 0:5ad86d8d396a 544 * @brief Function to read the ADC buffered raw data requested
Janani Sunil 0:5ad86d8d396a 545 * by IIO client
Janani Sunil 0:5ad86d8d396a 546 * @param pbuf[in] - Pointer to data buffer
Janani Sunil 0:5ad86d8d396a 547 * @param nb_of_bytes[in] - Number of bytes to read
Janani Sunil 0:5ad86d8d396a 548 * @return 0 in case of success, negative error code otherwise
Janani Sunil 0:5ad86d8d396a 549 */
Janani Sunil 0:5ad86d8d396a 550 int32_t read_buffered_data(int8_t **pbuf, uint32_t nb_of_bytes)
Janani Sunil 0:5ad86d8d396a 551 {
Janani Sunil 0:5ad86d8d396a 552 int32_t ret;
Janani Sunil 0:5ad86d8d396a 553 num_of_requested_samples = nb_of_bytes / sample_size_in_bytes;
Janani Sunil 0:5ad86d8d396a 554
Janani Sunil 0:5ad86d8d396a 555 #if (DATA_CAPTURE_MODE == BURST_DATA_CAPTURE)
Janani Sunil 0:5ad86d8d396a 556 ret = read_burst_data(*pbuf, num_of_requested_samples);
Janani Sunil 0:5ad86d8d396a 557 #else
Janani Sunil 0:5ad86d8d396a 558 ret = read_continuous_conv_data(pbuf, num_of_requested_samples);
Janani Sunil 0:5ad86d8d396a 559 #endif
Janani Sunil 0:5ad86d8d396a 560
Janani Sunil 0:5ad86d8d396a 561 if (ret) {
Janani Sunil 0:5ad86d8d396a 562 return ret;
Janani Sunil 0:5ad86d8d396a 563 }
Janani Sunil 0:5ad86d8d396a 564
Janani Sunil 0:5ad86d8d396a 565 return nb_of_bytes;
Janani Sunil 0:5ad86d8d396a 566 }