Example program for EVAL-AD4130

Dependencies:   tempsensors sdp_k1_sdram

Committer:
Mahesh Phalke
Date:
Wed Jul 20 18:12:00 2022 +0530
Revision:
2:7b2b268ea49c
Initial firmware commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Mahesh Phalke 2:7b2b268ea49c 1 /***************************************************************************//**
Mahesh Phalke 2:7b2b268ea49c 2 * @file ad4130_data_capture.c
Mahesh Phalke 2:7b2b268ea49c 3 * @brief AD4130 data capture interface for IIO based applications
Mahesh Phalke 2:7b2b268ea49c 4 * @details This module handles the ADC data capturing for IIO client
Mahesh Phalke 2:7b2b268ea49c 5 ********************************************************************************
Mahesh Phalke 2:7b2b268ea49c 6 * Copyright (c) 2021-22 Analog Devices, Inc.
Mahesh Phalke 2:7b2b268ea49c 7 * All rights reserved.
Mahesh Phalke 2:7b2b268ea49c 8 *
Mahesh Phalke 2:7b2b268ea49c 9 * This software is proprietary to Analog Devices, Inc. and its licensors.
Mahesh Phalke 2:7b2b268ea49c 10 * By using this software you agree to the terms of the associated
Mahesh Phalke 2:7b2b268ea49c 11 * Analog Devices Software License Agreement.
Mahesh Phalke 2:7b2b268ea49c 12 *******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 13
Mahesh Phalke 2:7b2b268ea49c 14 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 15 /***************************** Include Files **********************************/
Mahesh Phalke 2:7b2b268ea49c 16 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 17
Mahesh Phalke 2:7b2b268ea49c 18 #include <string.h>
Mahesh Phalke 2:7b2b268ea49c 19
Mahesh Phalke 2:7b2b268ea49c 20 #include "app_config.h"
Mahesh Phalke 2:7b2b268ea49c 21 #include "ad413x.h"
Mahesh Phalke 2:7b2b268ea49c 22 #include "ad4130_support.h"
Mahesh Phalke 2:7b2b268ea49c 23 #include "ad4130_iio.h"
Mahesh Phalke 2:7b2b268ea49c 24 #include "ad4130_regs.h"
Mahesh Phalke 2:7b2b268ea49c 25 #include "ad4130_data_capture.h"
Mahesh Phalke 2:7b2b268ea49c 26 #include "ad4130_user_config.h"
Mahesh Phalke 2:7b2b268ea49c 27 #include "no_os_gpio.h"
Mahesh Phalke 2:7b2b268ea49c 28 #include "no_os_error.h"
Mahesh Phalke 2:7b2b268ea49c 29
Mahesh Phalke 2:7b2b268ea49c 30 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 31 /********************** Macros and Constants Definition ***********************/
Mahesh Phalke 2:7b2b268ea49c 32 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 33
Mahesh Phalke 2:7b2b268ea49c 34 /* Timeout count to avoid stuck into potential infinite loop while checking
Mahesh Phalke 2:7b2b268ea49c 35 * for new data into an acquisition buffer. The actual timeout factor is determined
Mahesh Phalke 2:7b2b268ea49c 36 * through 'sampling_frequency' attribute of IIO app, but this period here makes sure
Mahesh Phalke 2:7b2b268ea49c 37 * we are not stuck into a forever loop in case data capture is interrupted
Mahesh Phalke 2:7b2b268ea49c 38 * or failed in between.
Mahesh Phalke 2:7b2b268ea49c 39 * Note: This timeout factor is dependent upon the MCU clock frequency. Below timeout
Mahesh Phalke 2:7b2b268ea49c 40 * is tested for SDP-K1 platform @180Mhz default core clock */
Mahesh Phalke 2:7b2b268ea49c 41 #define BUF_READ_TIMEOUT 0xffffffff
Mahesh Phalke 2:7b2b268ea49c 42
Mahesh Phalke 2:7b2b268ea49c 43 /* Fifo depth limit (watermark count) for data capture */
Mahesh Phalke 2:7b2b268ea49c 44 #define FIFO_SIZE 256 // Range: 1-256
Mahesh Phalke 2:7b2b268ea49c 45
Mahesh Phalke 2:7b2b268ea49c 46 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 47 /********************** Variables and User Defined Data Types *****************/
Mahesh Phalke 2:7b2b268ea49c 48 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 49
Mahesh Phalke 2:7b2b268ea49c 50 /* ADC data buffer */
Mahesh Phalke 2:7b2b268ea49c 51 #if !defined(USE_SDRAM_CAPTURE_BUFFER)
Mahesh Phalke 2:7b2b268ea49c 52 int8_t adc_data_buffer[DATA_BUFFER_SIZE] = { 0 };
Mahesh Phalke 2:7b2b268ea49c 53 #endif
Mahesh Phalke 2:7b2b268ea49c 54
Mahesh Phalke 2:7b2b268ea49c 55 /*
Mahesh Phalke 2:7b2b268ea49c 56 *@enum acq_buffer_state_e
Mahesh Phalke 2:7b2b268ea49c 57 *@details Enum holding the data acquisition buffer states
Mahesh Phalke 2:7b2b268ea49c 58 **/
Mahesh Phalke 2:7b2b268ea49c 59 typedef enum {
Mahesh Phalke 2:7b2b268ea49c 60 BUF_AVAILABLE,
Mahesh Phalke 2:7b2b268ea49c 61 BUF_EMPTY,
Mahesh Phalke 2:7b2b268ea49c 62 BUF_FULL
Mahesh Phalke 2:7b2b268ea49c 63 } acq_buffer_state_e;
Mahesh Phalke 2:7b2b268ea49c 64
Mahesh Phalke 2:7b2b268ea49c 65 /*
Mahesh Phalke 2:7b2b268ea49c 66 *@struct acq_buf_t
Mahesh Phalke 2:7b2b268ea49c 67 *@details Structure holding the data acquisition buffer parameters
Mahesh Phalke 2:7b2b268ea49c 68 **/
Mahesh Phalke 2:7b2b268ea49c 69 typedef struct {
Mahesh Phalke 2:7b2b268ea49c 70 acq_buffer_state_e state; // Buffer state
Mahesh Phalke 2:7b2b268ea49c 71 uint32_t wr_indx; // Buffer write index (incremented per sample read)
Mahesh Phalke 2:7b2b268ea49c 72 uint32_t rd_indx; // Buffer read index (incremented per sample read)
Mahesh Phalke 2:7b2b268ea49c 73 int8_t *wr_pdata; // Data buffer write pointer
Mahesh Phalke 2:7b2b268ea49c 74 int8_t *rd_pdata; // Data buffer read pointer
Mahesh Phalke 2:7b2b268ea49c 75 bool reindex_buffer; // Reindex buffer to 0th channel
Mahesh Phalke 2:7b2b268ea49c 76 } acq_buf_t;
Mahesh Phalke 2:7b2b268ea49c 77
Mahesh Phalke 2:7b2b268ea49c 78 /* ADC data acquisition buffers */
Mahesh Phalke 2:7b2b268ea49c 79 static volatile acq_buf_t acq_buffer;
Mahesh Phalke 2:7b2b268ea49c 80
Mahesh Phalke 2:7b2b268ea49c 81 /* Flag to indicate data capture status */
Mahesh Phalke 2:7b2b268ea49c 82 static volatile bool start_cont_data_capture = false;
Mahesh Phalke 2:7b2b268ea49c 83
Mahesh Phalke 2:7b2b268ea49c 84 /* Count to track number of actual samples requested by IIO client */
Mahesh Phalke 2:7b2b268ea49c 85 static volatile uint32_t num_of_requested_samples = 0;
Mahesh Phalke 2:7b2b268ea49c 86
Mahesh Phalke 2:7b2b268ea49c 87 /* ADC sample/raw data size in bytes */
Mahesh Phalke 2:7b2b268ea49c 88 static volatile uint8_t sample_size_in_bytes;
Mahesh Phalke 2:7b2b268ea49c 89
Mahesh Phalke 2:7b2b268ea49c 90 /* Max available buffer size (after considering the data alignment with IIO buffer) */
Mahesh Phalke 2:7b2b268ea49c 91 static volatile uint32_t max_buffer_sz;
Mahesh Phalke 2:7b2b268ea49c 92
Mahesh Phalke 2:7b2b268ea49c 93 /* List of channels to be captured */
Mahesh Phalke 2:7b2b268ea49c 94 static volatile uint8_t active_channels[ADC_USER_CHANNELS];
Mahesh Phalke 2:7b2b268ea49c 95
Mahesh Phalke 2:7b2b268ea49c 96 /* Number of active channels */
Mahesh Phalke 2:7b2b268ea49c 97 static volatile uint8_t num_of_active_channels;
Mahesh Phalke 2:7b2b268ea49c 98
Mahesh Phalke 2:7b2b268ea49c 99 /* Current active channel index */
Mahesh Phalke 2:7b2b268ea49c 100 static volatile uint8_t chn_indx;
Mahesh Phalke 2:7b2b268ea49c 101
Mahesh Phalke 2:7b2b268ea49c 102 /* FIFO data capture flags */
Mahesh Phalke 2:7b2b268ea49c 103 static volatile bool start_fifo_mode_data_capture = false;
Mahesh Phalke 2:7b2b268ea49c 104 static volatile bool fifo_data_available = false;
Mahesh Phalke 2:7b2b268ea49c 105 static uint32_t fifo_data[FIFO_SIZE];
Mahesh Phalke 2:7b2b268ea49c 106
Mahesh Phalke 2:7b2b268ea49c 107 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 108 /************************ Functions Declarations ******************************/
Mahesh Phalke 2:7b2b268ea49c 109 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 110
Mahesh Phalke 2:7b2b268ea49c 111 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 112 /************************ Functions Definitions *******************************/
Mahesh Phalke 2:7b2b268ea49c 113 /******************************************************************************/
Mahesh Phalke 2:7b2b268ea49c 114
Mahesh Phalke 2:7b2b268ea49c 115 /*!
Mahesh Phalke 2:7b2b268ea49c 116 * @brief Function to init the data capture for AD4130 device
Mahesh Phalke 2:7b2b268ea49c 117 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 118 */
Mahesh Phalke 2:7b2b268ea49c 119 int32_t ad4130_data_capture_init(void)
Mahesh Phalke 2:7b2b268ea49c 120 {
Mahesh Phalke 2:7b2b268ea49c 121 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 122 uint8_t preset;
Mahesh Phalke 2:7b2b268ea49c 123 adc_conv_int_source_e conv_int_source;
Mahesh Phalke 2:7b2b268ea49c 124
Mahesh Phalke 2:7b2b268ea49c 125 /* Stop any previous conversion */
Mahesh Phalke 2:7b2b268ea49c 126 ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_STANDBY_MODE);
Mahesh Phalke 2:7b2b268ea49c 127 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 128 return ret;
Mahesh Phalke 2:7b2b268ea49c 129 }
Mahesh Phalke 2:7b2b268ea49c 130
Mahesh Phalke 2:7b2b268ea49c 131 /* Select and enable the interupt pin source for data conversion monitor */
Mahesh Phalke 2:7b2b268ea49c 132 #if defined(AD4130_WLCSP_PACKAGE_TYPE)
Mahesh Phalke 2:7b2b268ea49c 133 conv_int_source = INT_PIN;
Mahesh Phalke 2:7b2b268ea49c 134 #else
Mahesh Phalke 2:7b2b268ea49c 135 conv_int_source = CLK_PIN;
Mahesh Phalke 2:7b2b268ea49c 136 #endif
Mahesh Phalke 2:7b2b268ea49c 137
Mahesh Phalke 2:7b2b268ea49c 138 ret = ad413x_set_int_source(ad4130_dev_inst, conv_int_source);
Mahesh Phalke 2:7b2b268ea49c 139 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 140 return ret;
Mahesh Phalke 2:7b2b268ea49c 141 }
Mahesh Phalke 2:7b2b268ea49c 142
Mahesh Phalke 2:7b2b268ea49c 143 /* Set the filter FS value (same for all setups/channels for
Mahesh Phalke 2:7b2b268ea49c 144 * consistant ODR/sample rate) */
Mahesh Phalke 2:7b2b268ea49c 145 for (preset = 0; preset <= ADC_PRESETS; preset++) {
Mahesh Phalke 2:7b2b268ea49c 146 ret = ad413x_set_filter_fs(ad4130_dev_inst, AD4130_FS_CONFIG, preset);
Mahesh Phalke 2:7b2b268ea49c 147 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 148 return ret;
Mahesh Phalke 2:7b2b268ea49c 149 }
Mahesh Phalke 2:7b2b268ea49c 150 }
Mahesh Phalke 2:7b2b268ea49c 151
Mahesh Phalke 2:7b2b268ea49c 152 return 0;
Mahesh Phalke 2:7b2b268ea49c 153 }
Mahesh Phalke 2:7b2b268ea49c 154
Mahesh Phalke 2:7b2b268ea49c 155 /*!
Mahesh Phalke 2:7b2b268ea49c 156 * @brief Store the list of all previously enabled channels and enable
Mahesh Phalke 2:7b2b268ea49c 157 * new channels set in the channel mask argument
Mahesh Phalke 2:7b2b268ea49c 158 * @param chn_mask[in] - Active channels list
Mahesh Phalke 2:7b2b268ea49c 159 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 160 */
Mahesh Phalke 2:7b2b268ea49c 161 static int32_t adc_store_active_chns(uint32_t chn_mask)
Mahesh Phalke 2:7b2b268ea49c 162 {
Mahesh Phalke 2:7b2b268ea49c 163 uint8_t mask = 0x1;
Mahesh Phalke 2:7b2b268ea49c 164 uint8_t index = 0;
Mahesh Phalke 2:7b2b268ea49c 165 uint8_t chn;
Mahesh Phalke 2:7b2b268ea49c 166 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 167
Mahesh Phalke 2:7b2b268ea49c 168 /* Enable/Disable channels based on channel mask set in the IIO client */
Mahesh Phalke 2:7b2b268ea49c 169 for (chn = 0; chn < ADC_USER_CHANNELS; chn++) {
Mahesh Phalke 2:7b2b268ea49c 170 if (chn_mask & mask) {
Mahesh Phalke 2:7b2b268ea49c 171 /* Store the active channel */
Mahesh Phalke 2:7b2b268ea49c 172 active_channels[index++] = chn;
Mahesh Phalke 2:7b2b268ea49c 173 num_of_active_channels++;
Mahesh Phalke 2:7b2b268ea49c 174
Mahesh Phalke 2:7b2b268ea49c 175 /* Enable the selected channel */
Mahesh Phalke 2:7b2b268ea49c 176 ret = ad413x_ch_en(ad4130_dev_inst, chn, 1);
Mahesh Phalke 2:7b2b268ea49c 177 } else {
Mahesh Phalke 2:7b2b268ea49c 178 /* Disable the selected channel */
Mahesh Phalke 2:7b2b268ea49c 179 ret = ad413x_ch_en(ad4130_dev_inst, chn, 0);
Mahesh Phalke 2:7b2b268ea49c 180 }
Mahesh Phalke 2:7b2b268ea49c 181
Mahesh Phalke 2:7b2b268ea49c 182 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 183 return ret;
Mahesh Phalke 2:7b2b268ea49c 184 }
Mahesh Phalke 2:7b2b268ea49c 185
Mahesh Phalke 2:7b2b268ea49c 186 mask <<= 1;
Mahesh Phalke 2:7b2b268ea49c 187 }
Mahesh Phalke 2:7b2b268ea49c 188
Mahesh Phalke 2:7b2b268ea49c 189 return 0;
Mahesh Phalke 2:7b2b268ea49c 190 }
Mahesh Phalke 2:7b2b268ea49c 191
Mahesh Phalke 2:7b2b268ea49c 192 /*!
Mahesh Phalke 2:7b2b268ea49c 193 * @brief Trigger a data capture in continuous/burst mode
Mahesh Phalke 2:7b2b268ea49c 194 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 195 */
Mahesh Phalke 2:7b2b268ea49c 196 static int32_t adc_start_data_capture(void)
Mahesh Phalke 2:7b2b268ea49c 197 {
Mahesh Phalke 2:7b2b268ea49c 198 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 199
Mahesh Phalke 2:7b2b268ea49c 200 /* Stop any previous conversion */
Mahesh Phalke 2:7b2b268ea49c 201 ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_STANDBY_MODE);
Mahesh Phalke 2:7b2b268ea49c 202 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 203 return ret;
Mahesh Phalke 2:7b2b268ea49c 204 }
Mahesh Phalke 2:7b2b268ea49c 205
Mahesh Phalke 2:7b2b268ea49c 206 /* Trigger new conversion */
Mahesh Phalke 2:7b2b268ea49c 207 ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_CONTINOUS_CONV_MODE);
Mahesh Phalke 2:7b2b268ea49c 208 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 209 return ret;
Mahesh Phalke 2:7b2b268ea49c 210 }
Mahesh Phalke 2:7b2b268ea49c 211
Mahesh Phalke 2:7b2b268ea49c 212 return 0;
Mahesh Phalke 2:7b2b268ea49c 213 }
Mahesh Phalke 2:7b2b268ea49c 214
Mahesh Phalke 2:7b2b268ea49c 215 /*!
Mahesh Phalke 2:7b2b268ea49c 216 * @brief Stop a data capture from continuous/burst/fifo mode
Mahesh Phalke 2:7b2b268ea49c 217 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 218 */
Mahesh Phalke 2:7b2b268ea49c 219 static int32_t adc_stop_data_capture(void)
Mahesh Phalke 2:7b2b268ea49c 220 {
Mahesh Phalke 2:7b2b268ea49c 221 /* Stop any active conversion */
Mahesh Phalke 2:7b2b268ea49c 222 return ad413x_set_adc_mode(ad4130_dev_inst, AD413X_STANDBY_MODE);
Mahesh Phalke 2:7b2b268ea49c 223 }
Mahesh Phalke 2:7b2b268ea49c 224
Mahesh Phalke 2:7b2b268ea49c 225 /*!
Mahesh Phalke 2:7b2b268ea49c 226 * @brief Trigger a data capture in FIFO mode
Mahesh Phalke 2:7b2b268ea49c 227 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 228 */
Mahesh Phalke 2:7b2b268ea49c 229 static int32_t adc_start_fifo_data_capture(void)
Mahesh Phalke 2:7b2b268ea49c 230 {
Mahesh Phalke 2:7b2b268ea49c 231 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 232 uint32_t fifo_control_reg_val;
Mahesh Phalke 2:7b2b268ea49c 233
Mahesh Phalke 2:7b2b268ea49c 234 /* Read FIFO control register */
Mahesh Phalke 2:7b2b268ea49c 235 ret = ad413x_reg_read(ad4130_dev_inst, AD413X_REG_FIFO_CTRL,
Mahesh Phalke 2:7b2b268ea49c 236 &fifo_control_reg_val);
Mahesh Phalke 2:7b2b268ea49c 237 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 238 return ret;
Mahesh Phalke 2:7b2b268ea49c 239 }
Mahesh Phalke 2:7b2b268ea49c 240
Mahesh Phalke 2:7b2b268ea49c 241 /* Store the watermark count in FIFO */
Mahesh Phalke 2:7b2b268ea49c 242 fifo_control_reg_val = (fifo_control_reg_val & ~AD413X_WATERMARK_MSK) |
Mahesh Phalke 2:7b2b268ea49c 243 AD413X_WATERMARK(FIFO_SIZE);
Mahesh Phalke 2:7b2b268ea49c 244
Mahesh Phalke 2:7b2b268ea49c 245 /* Select the FIFO mode to enable FIFO and enable watermark interrupt */
Mahesh Phalke 2:7b2b268ea49c 246 fifo_control_reg_val = (fifo_control_reg_val & ~AD4130_FIFO_MODE_MSK) |
Mahesh Phalke 2:7b2b268ea49c 247 AD413X_FIFO_MODE(FIFO_OLDEST_SAVE_MODE) |
Mahesh Phalke 2:7b2b268ea49c 248 AD413X_WATERMARK_INT_EN;
Mahesh Phalke 2:7b2b268ea49c 249
Mahesh Phalke 2:7b2b268ea49c 250 /* Disable the FIFO header and status (FIFO status and header is not appended to data) */
Mahesh Phalke 2:7b2b268ea49c 251 fifo_control_reg_val &= ~(AD413X_ADD_FIFO_HEADER | AD413X_ADD_FIFO_STATUS);
Mahesh Phalke 2:7b2b268ea49c 252
Mahesh Phalke 2:7b2b268ea49c 253 /* Write to ADC fifo_ctrl register */
Mahesh Phalke 2:7b2b268ea49c 254 ret = ad413x_reg_write(ad4130_dev_inst, AD413X_REG_FIFO_CTRL,
Mahesh Phalke 2:7b2b268ea49c 255 fifo_control_reg_val);
Mahesh Phalke 2:7b2b268ea49c 256 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 257 return ret;
Mahesh Phalke 2:7b2b268ea49c 258 }
Mahesh Phalke 2:7b2b268ea49c 259
Mahesh Phalke 2:7b2b268ea49c 260 start_fifo_mode_data_capture = true;
Mahesh Phalke 2:7b2b268ea49c 261 ret = adc_start_data_capture();
Mahesh Phalke 2:7b2b268ea49c 262 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 263 return ret;
Mahesh Phalke 2:7b2b268ea49c 264 }
Mahesh Phalke 2:7b2b268ea49c 265
Mahesh Phalke 2:7b2b268ea49c 266 return 0;
Mahesh Phalke 2:7b2b268ea49c 267 }
Mahesh Phalke 2:7b2b268ea49c 268
Mahesh Phalke 2:7b2b268ea49c 269 /*!
Mahesh Phalke 2:7b2b268ea49c 270 * @brief Read a single sample of ADC
Mahesh Phalke 2:7b2b268ea49c 271 * @param adc_raw[in] - Pointer to ADC raw data variable
Mahesh Phalke 2:7b2b268ea49c 272 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 273 */
Mahesh Phalke 2:7b2b268ea49c 274 static int32_t adc_read_single_sample(uint32_t *adc_raw)
Mahesh Phalke 2:7b2b268ea49c 275 {
Mahesh Phalke 2:7b2b268ea49c 276 if (!adc_raw) {
Mahesh Phalke 2:7b2b268ea49c 277 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 278 }
Mahesh Phalke 2:7b2b268ea49c 279
Mahesh Phalke 2:7b2b268ea49c 280 return ad413x_mon_conv_and_read_data(ad4130_dev_inst, adc_raw);
Mahesh Phalke 2:7b2b268ea49c 281 }
Mahesh Phalke 2:7b2b268ea49c 282
Mahesh Phalke 2:7b2b268ea49c 283 /*!
Mahesh Phalke 2:7b2b268ea49c 284 * @brief Read a single sample of ADC
Mahesh Phalke 2:7b2b268ea49c 285 * @param data[in] - Pointer to FIFO data array
Mahesh Phalke 2:7b2b268ea49c 286 * @param samples[in] - Number of samples to read
Mahesh Phalke 2:7b2b268ea49c 287 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 288 */
Mahesh Phalke 2:7b2b268ea49c 289 static int32_t adc_read_fifo(uint32_t *data, uint32_t samples)
Mahesh Phalke 2:7b2b268ea49c 290 {
Mahesh Phalke 2:7b2b268ea49c 291 if (!data) {
Mahesh Phalke 2:7b2b268ea49c 292 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 293 }
Mahesh Phalke 2:7b2b268ea49c 294
Mahesh Phalke 2:7b2b268ea49c 295 return ad4130_read_fifo(ad4130_dev_inst, data, samples);
Mahesh Phalke 2:7b2b268ea49c 296 }
Mahesh Phalke 2:7b2b268ea49c 297
Mahesh Phalke 2:7b2b268ea49c 298 /*!
Mahesh Phalke 2:7b2b268ea49c 299 * @brief Read ADC raw data for recently sampled channel
Mahesh Phalke 2:7b2b268ea49c 300 * @param adc_data[in, out] - Pointer to adc data read variable
Mahesh Phalke 2:7b2b268ea49c 301 * @param input_chn[in] - Input channel (optional)
Mahesh Phalke 2:7b2b268ea49c 302 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 303 * @note This function is intended to call from the conversion end trigger
Mahesh Phalke 2:7b2b268ea49c 304 * event. Therefore, this function should just read raw ADC data
Mahesh Phalke 2:7b2b268ea49c 305 * without further monitoring conversion end event.
Mahesh Phalke 2:7b2b268ea49c 306 * Continuous conversion mode is used to for this operation.
Mahesh Phalke 2:7b2b268ea49c 307 */
Mahesh Phalke 2:7b2b268ea49c 308 static int32_t adc_read_converted_sample(uint32_t *adc_data,
Mahesh Phalke 2:7b2b268ea49c 309 uint8_t input_chn)
Mahesh Phalke 2:7b2b268ea49c 310 {
Mahesh Phalke 2:7b2b268ea49c 311 if (!adc_data) {
Mahesh Phalke 2:7b2b268ea49c 312 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 313 }
Mahesh Phalke 2:7b2b268ea49c 314
Mahesh Phalke 2:7b2b268ea49c 315 /* Read the ADC data for previously sampled channel in sequencer */
Mahesh Phalke 2:7b2b268ea49c 316 return ad413x_reg_read(ad4130_dev_inst, AD413X_REG_DATA, adc_data);
Mahesh Phalke 2:7b2b268ea49c 317 }
Mahesh Phalke 2:7b2b268ea49c 318
Mahesh Phalke 2:7b2b268ea49c 319 /*!
Mahesh Phalke 2:7b2b268ea49c 320 * @brief Function to read the single ADC sample (raw data) for input channel
Mahesh Phalke 2:7b2b268ea49c 321 * @param input_chn[in] - Input channel to be sampled and read data for
Mahesh Phalke 2:7b2b268ea49c 322 * @param raw_data[in, out]- ADC raw data
Mahesh Phalke 2:7b2b268ea49c 323 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 324 * @note The single conversion mode is used to read a single sample
Mahesh Phalke 2:7b2b268ea49c 325 */
Mahesh Phalke 2:7b2b268ea49c 326 int32_t read_single_sample(uint8_t input_chn, uint32_t *adc_raw)
Mahesh Phalke 2:7b2b268ea49c 327 {
Mahesh Phalke 2:7b2b268ea49c 328 uint32_t chn_mask = 0;
Mahesh Phalke 2:7b2b268ea49c 329 uint8_t chn;
Mahesh Phalke 2:7b2b268ea49c 330 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 331
Mahesh Phalke 2:7b2b268ea49c 332 if (!adc_raw) {
Mahesh Phalke 2:7b2b268ea49c 333 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 334 }
Mahesh Phalke 2:7b2b268ea49c 335
Mahesh Phalke 2:7b2b268ea49c 336 /* Disable all active channels */
Mahesh Phalke 2:7b2b268ea49c 337 for (chn = 0; chn < ADC_USER_CHANNELS; chn++) {
Mahesh Phalke 2:7b2b268ea49c 338 if (ad4130_dev_inst->ch[chn].enable) {
Mahesh Phalke 2:7b2b268ea49c 339 chn_mask |= (1 << chn);
Mahesh Phalke 2:7b2b268ea49c 340
Mahesh Phalke 2:7b2b268ea49c 341 /* Disable the current channel */
Mahesh Phalke 2:7b2b268ea49c 342 ret = ad413x_ch_en(ad4130_dev_inst, chn, 0);
Mahesh Phalke 2:7b2b268ea49c 343 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 344 return ret;
Mahesh Phalke 2:7b2b268ea49c 345 }
Mahesh Phalke 2:7b2b268ea49c 346 }
Mahesh Phalke 2:7b2b268ea49c 347 }
Mahesh Phalke 2:7b2b268ea49c 348
Mahesh Phalke 2:7b2b268ea49c 349 /* Enable user input channel */
Mahesh Phalke 2:7b2b268ea49c 350 if (!ad4130_dev_inst->ch[input_chn].enable) {
Mahesh Phalke 2:7b2b268ea49c 351 ret = ad413x_ch_en(ad4130_dev_inst, input_chn, 1);
Mahesh Phalke 2:7b2b268ea49c 352 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 353 return ret;
Mahesh Phalke 2:7b2b268ea49c 354 }
Mahesh Phalke 2:7b2b268ea49c 355 }
Mahesh Phalke 2:7b2b268ea49c 356
Mahesh Phalke 2:7b2b268ea49c 357 /* Put device into single conversion mode */
Mahesh Phalke 2:7b2b268ea49c 358 ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_SINGLE_CONV_MODE);
Mahesh Phalke 2:7b2b268ea49c 359 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 360 return ret;
Mahesh Phalke 2:7b2b268ea49c 361 }
Mahesh Phalke 2:7b2b268ea49c 362
Mahesh Phalke 2:7b2b268ea49c 363 /* Monitor conversion and read the result */
Mahesh Phalke 2:7b2b268ea49c 364 ret = ad413x_mon_conv_and_read_data(ad4130_dev_inst, adc_raw);
Mahesh Phalke 2:7b2b268ea49c 365
Mahesh Phalke 2:7b2b268ea49c 366 /* Disable user input channel */
Mahesh Phalke 2:7b2b268ea49c 367 ret = ad413x_ch_en(ad4130_dev_inst, input_chn, 0);
Mahesh Phalke 2:7b2b268ea49c 368 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 369 return ret;
Mahesh Phalke 2:7b2b268ea49c 370 }
Mahesh Phalke 2:7b2b268ea49c 371
Mahesh Phalke 2:7b2b268ea49c 372 return 0;
Mahesh Phalke 2:7b2b268ea49c 373 }
Mahesh Phalke 2:7b2b268ea49c 374
Mahesh Phalke 2:7b2b268ea49c 375 /********* Device Independent Data Capture Code Begin ************/
Mahesh Phalke 2:7b2b268ea49c 376
Mahesh Phalke 2:7b2b268ea49c 377 /*!
Mahesh Phalke 2:7b2b268ea49c 378 * @brief Reset the data capture specific variables
Mahesh Phalke 2:7b2b268ea49c 379 * @return none
Mahesh Phalke 2:7b2b268ea49c 380 */
Mahesh Phalke 2:7b2b268ea49c 381 static void reset_data_capture(void)
Mahesh Phalke 2:7b2b268ea49c 382 {
Mahesh Phalke 2:7b2b268ea49c 383 /* Reset data capture flags */
Mahesh Phalke 2:7b2b268ea49c 384 start_cont_data_capture = false;
Mahesh Phalke 2:7b2b268ea49c 385 start_fifo_mode_data_capture = false;
Mahesh Phalke 2:7b2b268ea49c 386 num_of_active_channels = 0;
Mahesh Phalke 2:7b2b268ea49c 387 chn_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 388
Mahesh Phalke 2:7b2b268ea49c 389 /* Reset acquisition buffer states and clear old data */
Mahesh Phalke 2:7b2b268ea49c 390 acq_buffer.state = BUF_EMPTY;
Mahesh Phalke 2:7b2b268ea49c 391 acq_buffer.wr_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 392 acq_buffer.rd_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 393 acq_buffer.reindex_buffer = false;
Mahesh Phalke 2:7b2b268ea49c 394 acq_buffer.wr_pdata = adc_data_buffer;
Mahesh Phalke 2:7b2b268ea49c 395 acq_buffer.rd_pdata = adc_data_buffer;
Mahesh Phalke 2:7b2b268ea49c 396 max_buffer_sz = DATA_BUFFER_SIZE;
Mahesh Phalke 2:7b2b268ea49c 397 }
Mahesh Phalke 2:7b2b268ea49c 398
Mahesh Phalke 2:7b2b268ea49c 399 /*!
Mahesh Phalke 2:7b2b268ea49c 400 * @brief Function to prepare the data ADC capture for new READBUFF
Mahesh Phalke 2:7b2b268ea49c 401 * request from IIO client (for active channels)
Mahesh Phalke 2:7b2b268ea49c 402 * @param ch_mask[in] - Channels to enable for data capturing
Mahesh Phalke 2:7b2b268ea49c 403 * @param sample_size[in] - Sample size in bytes
Mahesh Phalke 2:7b2b268ea49c 404 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 405 */
Mahesh Phalke 2:7b2b268ea49c 406 int32_t prepare_data_transfer(uint32_t ch_mask, uint8_t sample_size)
Mahesh Phalke 2:7b2b268ea49c 407 {
Mahesh Phalke 2:7b2b268ea49c 408 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 409
Mahesh Phalke 2:7b2b268ea49c 410 /* Reset data capture module specific flags and variables */
Mahesh Phalke 2:7b2b268ea49c 411 reset_data_capture();
Mahesh Phalke 2:7b2b268ea49c 412
Mahesh Phalke 2:7b2b268ea49c 413 sample_size_in_bytes = sample_size;
Mahesh Phalke 2:7b2b268ea49c 414
Mahesh Phalke 2:7b2b268ea49c 415 /* Store active channels */
Mahesh Phalke 2:7b2b268ea49c 416 ret = adc_store_active_chns(ch_mask);
Mahesh Phalke 2:7b2b268ea49c 417 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 418 return ret;
Mahesh Phalke 2:7b2b268ea49c 419 }
Mahesh Phalke 2:7b2b268ea49c 420
Mahesh Phalke 2:7b2b268ea49c 421 #if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE)
Mahesh Phalke 2:7b2b268ea49c 422 /* Trigger continuous data capture */
Mahesh Phalke 2:7b2b268ea49c 423 ret = adc_start_data_capture();
Mahesh Phalke 2:7b2b268ea49c 424 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 425 return ret;
Mahesh Phalke 2:7b2b268ea49c 426 }
Mahesh Phalke 2:7b2b268ea49c 427
Mahesh Phalke 2:7b2b268ea49c 428 acq_buffer.state = BUF_AVAILABLE;
Mahesh Phalke 2:7b2b268ea49c 429 start_cont_data_capture = true;
Mahesh Phalke 2:7b2b268ea49c 430 #endif
Mahesh Phalke 2:7b2b268ea49c 431
Mahesh Phalke 2:7b2b268ea49c 432 return 0;
Mahesh Phalke 2:7b2b268ea49c 433 }
Mahesh Phalke 2:7b2b268ea49c 434
Mahesh Phalke 2:7b2b268ea49c 435 /*!
Mahesh Phalke 2:7b2b268ea49c 436 * @brief Function to stop ADC data capture
Mahesh Phalke 2:7b2b268ea49c 437 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 438 */
Mahesh Phalke 2:7b2b268ea49c 439 int32_t end_data_transfer(void)
Mahesh Phalke 2:7b2b268ea49c 440 {
Mahesh Phalke 2:7b2b268ea49c 441 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 442 start_cont_data_capture = false;
Mahesh Phalke 2:7b2b268ea49c 443
Mahesh Phalke 2:7b2b268ea49c 444 /* Stop data capture */
Mahesh Phalke 2:7b2b268ea49c 445 ret = adc_stop_data_capture();
Mahesh Phalke 2:7b2b268ea49c 446 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 447 return ret;
Mahesh Phalke 2:7b2b268ea49c 448 }
Mahesh Phalke 2:7b2b268ea49c 449
Mahesh Phalke 2:7b2b268ea49c 450 /* Reset data capture module specific flags and variables */
Mahesh Phalke 2:7b2b268ea49c 451 reset_data_capture();
Mahesh Phalke 2:7b2b268ea49c 452
Mahesh Phalke 2:7b2b268ea49c 453 return 0;
Mahesh Phalke 2:7b2b268ea49c 454 }
Mahesh Phalke 2:7b2b268ea49c 455
Mahesh Phalke 2:7b2b268ea49c 456 /*!
Mahesh Phalke 2:7b2b268ea49c 457 * @brief Perform buffer read operations to read requested samples
Mahesh Phalke 2:7b2b268ea49c 458 * @param nb_of_samples[in] - Requested number of samples to read
Mahesh Phalke 2:7b2b268ea49c 459 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 460 */
Mahesh Phalke 2:7b2b268ea49c 461 static int32_t buffer_read_operations(uint32_t nb_of_samples)
Mahesh Phalke 2:7b2b268ea49c 462 {
Mahesh Phalke 2:7b2b268ea49c 463 uint32_t timeout = BUF_READ_TIMEOUT;
Mahesh Phalke 2:7b2b268ea49c 464 int32_t offset;
Mahesh Phalke 2:7b2b268ea49c 465
Mahesh Phalke 2:7b2b268ea49c 466 /* Wait until requested samples are available in the buffer to read */
Mahesh Phalke 2:7b2b268ea49c 467 do {
Mahesh Phalke 2:7b2b268ea49c 468 if (acq_buffer.wr_indx >= acq_buffer.rd_indx) {
Mahesh Phalke 2:7b2b268ea49c 469 offset = acq_buffer.wr_indx - acq_buffer.rd_indx;
Mahesh Phalke 2:7b2b268ea49c 470 } else {
Mahesh Phalke 2:7b2b268ea49c 471 offset = max_buffer_sz + (acq_buffer.wr_indx - acq_buffer.rd_indx);
Mahesh Phalke 2:7b2b268ea49c 472 }
Mahesh Phalke 2:7b2b268ea49c 473
Mahesh Phalke 2:7b2b268ea49c 474 timeout--;
Mahesh Phalke 2:7b2b268ea49c 475 } while ((offset < (int32_t)(nb_of_samples)) && (timeout > 0));
Mahesh Phalke 2:7b2b268ea49c 476
Mahesh Phalke 2:7b2b268ea49c 477 if (timeout == 0) {
Mahesh Phalke 2:7b2b268ea49c 478 /* This returns the empty buffer */
Mahesh Phalke 2:7b2b268ea49c 479 return -EIO;
Mahesh Phalke 2:7b2b268ea49c 480 }
Mahesh Phalke 2:7b2b268ea49c 481
Mahesh Phalke 2:7b2b268ea49c 482 if (acq_buffer.rd_indx >= max_buffer_sz) {
Mahesh Phalke 2:7b2b268ea49c 483 acq_buffer.rd_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 484 }
Mahesh Phalke 2:7b2b268ea49c 485
Mahesh Phalke 2:7b2b268ea49c 486 return 0;
Mahesh Phalke 2:7b2b268ea49c 487 }
Mahesh Phalke 2:7b2b268ea49c 488
Mahesh Phalke 2:7b2b268ea49c 489 /*!
Mahesh Phalke 2:7b2b268ea49c 490 * @brief Perform buffer write operations such as buffer full or empty
Mahesh Phalke 2:7b2b268ea49c 491 * check, resetting buffer index and pointers, etc
Mahesh Phalke 2:7b2b268ea49c 492 * @return none
Mahesh Phalke 2:7b2b268ea49c 493 */
Mahesh Phalke 2:7b2b268ea49c 494 static void buffer_write_operations(void)
Mahesh Phalke 2:7b2b268ea49c 495 {
Mahesh Phalke 2:7b2b268ea49c 496 acq_buffer.wr_indx++;
Mahesh Phalke 2:7b2b268ea49c 497
Mahesh Phalke 2:7b2b268ea49c 498 /* Perform buffer full check and operations */
Mahesh Phalke 2:7b2b268ea49c 499 if (acq_buffer.wr_indx >= max_buffer_sz) {
Mahesh Phalke 2:7b2b268ea49c 500 if ((acq_buffer.rd_indx >= num_of_requested_samples)
Mahesh Phalke 2:7b2b268ea49c 501 && (acq_buffer.rd_indx != 0)) {
Mahesh Phalke 2:7b2b268ea49c 502 /* Reset buffer write index and write pointer when enough
Mahesh Phalke 2:7b2b268ea49c 503 * space available in the buffer to wrap to start */
Mahesh Phalke 2:7b2b268ea49c 504 acq_buffer.wr_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 505 acq_buffer.wr_pdata = adc_data_buffer;
Mahesh Phalke 2:7b2b268ea49c 506 if (acq_buffer.rd_indx >= max_buffer_sz) {
Mahesh Phalke 2:7b2b268ea49c 507 /* Wrap the read index and read pointer to start of buffer
Mahesh Phalke 2:7b2b268ea49c 508 * if buffer is completely read/emptied */
Mahesh Phalke 2:7b2b268ea49c 509 acq_buffer.rd_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 510 acq_buffer.rd_pdata = adc_data_buffer;
Mahesh Phalke 2:7b2b268ea49c 511 }
Mahesh Phalke 2:7b2b268ea49c 512
Mahesh Phalke 2:7b2b268ea49c 513 acq_buffer.state = BUF_AVAILABLE;
Mahesh Phalke 2:7b2b268ea49c 514 } else {
Mahesh Phalke 2:7b2b268ea49c 515 /* Wait until enough space available to wrap buffer write index
Mahesh Phalke 2:7b2b268ea49c 516 * at the start of buffer */
Mahesh Phalke 2:7b2b268ea49c 517 acq_buffer.wr_indx = max_buffer_sz;
Mahesh Phalke 2:7b2b268ea49c 518 acq_buffer.state = BUF_FULL;
Mahesh Phalke 2:7b2b268ea49c 519 acq_buffer.reindex_buffer = true;
Mahesh Phalke 2:7b2b268ea49c 520 }
Mahesh Phalke 2:7b2b268ea49c 521 }
Mahesh Phalke 2:7b2b268ea49c 522 }
Mahesh Phalke 2:7b2b268ea49c 523
Mahesh Phalke 2:7b2b268ea49c 524 /*!
Mahesh Phalke 2:7b2b268ea49c 525 * @brief This is an ISR (Interrupt Service Routine) to monitor end of conversion event.
Mahesh Phalke 2:7b2b268ea49c 526 * @param ctx[in] - Callback context (unused)
Mahesh Phalke 2:7b2b268ea49c 527 * @return none
Mahesh Phalke 2:7b2b268ea49c 528 * @details This is an Interrupt callback function/ISR invoked in synchronous/asynchronous
Mahesh Phalke 2:7b2b268ea49c 529 * manner depending upon the application implementation. The conversion results
Mahesh Phalke 2:7b2b268ea49c 530 * are read into acquisition buffer and control continue to sample next channel.
Mahesh Phalke 2:7b2b268ea49c 531 * This continues until conversion is stopped (through IIO client command)
Mahesh Phalke 2:7b2b268ea49c 532 */
Mahesh Phalke 2:7b2b268ea49c 533 void data_capture_callback(void *ctx)
Mahesh Phalke 2:7b2b268ea49c 534 {
Mahesh Phalke 2:7b2b268ea49c 535 uint32_t adc_sample;
Mahesh Phalke 2:7b2b268ea49c 536 volatile uint8_t *wr_addr;
Mahesh Phalke 2:7b2b268ea49c 537
Mahesh Phalke 2:7b2b268ea49c 538 if (start_cont_data_capture == true) {
Mahesh Phalke 2:7b2b268ea49c 539 /* Read the sample for channel which has been sampled recently */
Mahesh Phalke 2:7b2b268ea49c 540 if (!adc_read_converted_sample(&adc_sample,
Mahesh Phalke 2:7b2b268ea49c 541 active_channels[chn_indx])) {
Mahesh Phalke 2:7b2b268ea49c 542 do {
Mahesh Phalke 2:7b2b268ea49c 543 if (acq_buffer.state == BUF_AVAILABLE) {
Mahesh Phalke 2:7b2b268ea49c 544 if (acq_buffer.reindex_buffer) {
Mahesh Phalke 2:7b2b268ea49c 545 /* Buffer refilling must start with first active channel data
Mahesh Phalke 2:7b2b268ea49c 546 * for IIO client to synchronize the buffered data */
Mahesh Phalke 2:7b2b268ea49c 547 if (chn_indx != 0) {
Mahesh Phalke 2:7b2b268ea49c 548 break;
Mahesh Phalke 2:7b2b268ea49c 549 }
Mahesh Phalke 2:7b2b268ea49c 550 acq_buffer.reindex_buffer = false;
Mahesh Phalke 2:7b2b268ea49c 551 }
Mahesh Phalke 2:7b2b268ea49c 552
Mahesh Phalke 2:7b2b268ea49c 553 /* Copy adc samples into acquisition buffer to transport over
Mahesh Phalke 2:7b2b268ea49c 554 * communication link */
Mahesh Phalke 2:7b2b268ea49c 555 wr_addr = (volatile uint8_t *)(acq_buffer.wr_pdata + (acq_buffer.wr_indx *
Mahesh Phalke 2:7b2b268ea49c 556 sample_size_in_bytes));
Mahesh Phalke 2:7b2b268ea49c 557 memcpy((uint8_t *)wr_addr, &adc_sample, sample_size_in_bytes);
Mahesh Phalke 2:7b2b268ea49c 558 }
Mahesh Phalke 2:7b2b268ea49c 559
Mahesh Phalke 2:7b2b268ea49c 560 /* Perform buffer write operations */
Mahesh Phalke 2:7b2b268ea49c 561 buffer_write_operations();
Mahesh Phalke 2:7b2b268ea49c 562 } while (0);
Mahesh Phalke 2:7b2b268ea49c 563
Mahesh Phalke 2:7b2b268ea49c 564 /* Track the count for recently sampled channel */
Mahesh Phalke 2:7b2b268ea49c 565 chn_indx++;
Mahesh Phalke 2:7b2b268ea49c 566 if (chn_indx >= num_of_active_channels) {
Mahesh Phalke 2:7b2b268ea49c 567 chn_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 568 }
Mahesh Phalke 2:7b2b268ea49c 569 }
Mahesh Phalke 2:7b2b268ea49c 570 }
Mahesh Phalke 2:7b2b268ea49c 571 }
Mahesh Phalke 2:7b2b268ea49c 572
Mahesh Phalke 2:7b2b268ea49c 573 /*!
Mahesh Phalke 2:7b2b268ea49c 574 * @brief This is an ISR (Interrupt Service Routine) to monitor FIFO data available event.
Mahesh Phalke 2:7b2b268ea49c 575 * This function is expected to be called asynchronously when data from internal device
Mahesh Phalke 2:7b2b268ea49c 576 * FIFO is available to read.
Mahesh Phalke 2:7b2b268ea49c 577 * @param ctx[in] - Callback context (unused)
Mahesh Phalke 2:7b2b268ea49c 578 * @return none
Mahesh Phalke 2:7b2b268ea49c 579 */
Mahesh Phalke 2:7b2b268ea49c 580 void fifo_data_capture_callback(void *ctx)
Mahesh Phalke 2:7b2b268ea49c 581 {
Mahesh Phalke 2:7b2b268ea49c 582 if (start_fifo_mode_data_capture) {
Mahesh Phalke 2:7b2b268ea49c 583 fifo_data_available = true;
Mahesh Phalke 2:7b2b268ea49c 584 }
Mahesh Phalke 2:7b2b268ea49c 585 }
Mahesh Phalke 2:7b2b268ea49c 586
Mahesh Phalke 2:7b2b268ea49c 587 /*!
Mahesh Phalke 2:7b2b268ea49c 588 * @brief Capture requested number of ADC samples in burst mode
Mahesh Phalke 2:7b2b268ea49c 589 * @param pbuf[out] - Pointer to ADC data buffer
Mahesh Phalke 2:7b2b268ea49c 590 * @param nb_of_samples[in] - Number of samples to be read
Mahesh Phalke 2:7b2b268ea49c 591 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 592 */
Mahesh Phalke 2:7b2b268ea49c 593 static int32_t read_burst_data(int8_t *pbuf, uint32_t nb_of_samples)
Mahesh Phalke 2:7b2b268ea49c 594 {
Mahesh Phalke 2:7b2b268ea49c 595 uint32_t sample_indx = 0;
Mahesh Phalke 2:7b2b268ea49c 596 uint32_t adc_raw;
Mahesh Phalke 2:7b2b268ea49c 597 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 598
Mahesh Phalke 2:7b2b268ea49c 599 if (!pbuf) {
Mahesh Phalke 2:7b2b268ea49c 600 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 601 }
Mahesh Phalke 2:7b2b268ea49c 602
Mahesh Phalke 2:7b2b268ea49c 603 ret = adc_start_data_capture();
Mahesh Phalke 2:7b2b268ea49c 604 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 605 return ret;
Mahesh Phalke 2:7b2b268ea49c 606 }
Mahesh Phalke 2:7b2b268ea49c 607
Mahesh Phalke 2:7b2b268ea49c 608 while (sample_indx < nb_of_samples) {
Mahesh Phalke 2:7b2b268ea49c 609 ret = adc_read_single_sample(&adc_raw);
Mahesh Phalke 2:7b2b268ea49c 610 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 611 return ret;
Mahesh Phalke 2:7b2b268ea49c 612 }
Mahesh Phalke 2:7b2b268ea49c 613
Mahesh Phalke 2:7b2b268ea49c 614 /* Copy adc samples into acquisition buffer to transport over
Mahesh Phalke 2:7b2b268ea49c 615 * communication link */
Mahesh Phalke 2:7b2b268ea49c 616 memcpy((uint8_t *)pbuf, &adc_raw, sample_size_in_bytes);
Mahesh Phalke 2:7b2b268ea49c 617 pbuf += sample_size_in_bytes;
Mahesh Phalke 2:7b2b268ea49c 618
Mahesh Phalke 2:7b2b268ea49c 619 sample_indx++;
Mahesh Phalke 2:7b2b268ea49c 620 }
Mahesh Phalke 2:7b2b268ea49c 621
Mahesh Phalke 2:7b2b268ea49c 622 /* Stop any active conversion */
Mahesh Phalke 2:7b2b268ea49c 623 ret = adc_stop_data_capture();
Mahesh Phalke 2:7b2b268ea49c 624 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 625 return ret;
Mahesh Phalke 2:7b2b268ea49c 626 }
Mahesh Phalke 2:7b2b268ea49c 627
Mahesh Phalke 2:7b2b268ea49c 628 return 0;
Mahesh Phalke 2:7b2b268ea49c 629 }
Mahesh Phalke 2:7b2b268ea49c 630
Mahesh Phalke 2:7b2b268ea49c 631 /*!
Mahesh Phalke 2:7b2b268ea49c 632 * @brief Capture requested number of ADC samples in FIFO mode
Mahesh Phalke 2:7b2b268ea49c 633 * @param pbuf[in] - Input buffer
Mahesh Phalke 2:7b2b268ea49c 634 * @param nb_of_samples[in] - Number of samples to read
Mahesh Phalke 2:7b2b268ea49c 635 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 636 */
Mahesh Phalke 2:7b2b268ea49c 637 static int32_t read_fifo_data(int8_t *pbuf,
Mahesh Phalke 2:7b2b268ea49c 638 uint32_t nb_of_samples)
Mahesh Phalke 2:7b2b268ea49c 639 {
Mahesh Phalke 2:7b2b268ea49c 640 uint32_t sample_cnt;
Mahesh Phalke 2:7b2b268ea49c 641 uint32_t remaining_samples = nb_of_samples;
Mahesh Phalke 2:7b2b268ea49c 642 uint32_t timeout = BUF_READ_TIMEOUT;
Mahesh Phalke 2:7b2b268ea49c 643 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 644
Mahesh Phalke 2:7b2b268ea49c 645 if (!pbuf) {
Mahesh Phalke 2:7b2b268ea49c 646 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 647 }
Mahesh Phalke 2:7b2b268ea49c 648
Mahesh Phalke 2:7b2b268ea49c 649 fifo_data_available = false;
Mahesh Phalke 2:7b2b268ea49c 650
Mahesh Phalke 2:7b2b268ea49c 651 ret = adc_start_fifo_data_capture();
Mahesh Phalke 2:7b2b268ea49c 652 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 653 return ret;
Mahesh Phalke 2:7b2b268ea49c 654 }
Mahesh Phalke 2:7b2b268ea49c 655
Mahesh Phalke 2:7b2b268ea49c 656 /* Read all requeted samples into acquisition buffer */
Mahesh Phalke 2:7b2b268ea49c 657 do {
Mahesh Phalke 2:7b2b268ea49c 658 /* Wait for new FIFO event */
Mahesh Phalke 2:7b2b268ea49c 659 timeout = BUF_READ_TIMEOUT;
Mahesh Phalke 2:7b2b268ea49c 660 do {
Mahesh Phalke 2:7b2b268ea49c 661 timeout--;
Mahesh Phalke 2:7b2b268ea49c 662 } while ((!fifo_data_available) && (timeout > 0));
Mahesh Phalke 2:7b2b268ea49c 663
Mahesh Phalke 2:7b2b268ea49c 664 if (timeout == 0) {
Mahesh Phalke 2:7b2b268ea49c 665 return -EIO;
Mahesh Phalke 2:7b2b268ea49c 666 }
Mahesh Phalke 2:7b2b268ea49c 667
Mahesh Phalke 2:7b2b268ea49c 668 fifo_data_available = false;
Mahesh Phalke 2:7b2b268ea49c 669
Mahesh Phalke 2:7b2b268ea49c 670 if (remaining_samples > FIFO_SIZE) {
Mahesh Phalke 2:7b2b268ea49c 671 nb_of_samples = FIFO_SIZE;
Mahesh Phalke 2:7b2b268ea49c 672 remaining_samples -= nb_of_samples;
Mahesh Phalke 2:7b2b268ea49c 673 } else {
Mahesh Phalke 2:7b2b268ea49c 674 nb_of_samples = remaining_samples;
Mahesh Phalke 2:7b2b268ea49c 675 remaining_samples = 0;
Mahesh Phalke 2:7b2b268ea49c 676 }
Mahesh Phalke 2:7b2b268ea49c 677
Mahesh Phalke 2:7b2b268ea49c 678 /* Read data from FIFO and store into local buffer */
Mahesh Phalke 2:7b2b268ea49c 679 ret = adc_read_fifo(fifo_data, nb_of_samples);
Mahesh Phalke 2:7b2b268ea49c 680 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 681 return ret;
Mahesh Phalke 2:7b2b268ea49c 682 }
Mahesh Phalke 2:7b2b268ea49c 683
Mahesh Phalke 2:7b2b268ea49c 684 /* Read offloaded FIFO data and store into acquisition buffer */
Mahesh Phalke 2:7b2b268ea49c 685 for (sample_cnt = 0; sample_cnt < nb_of_samples; sample_cnt++) {
Mahesh Phalke 2:7b2b268ea49c 686 memcpy(pbuf, &fifo_data[sample_cnt], sample_size_in_bytes);
Mahesh Phalke 2:7b2b268ea49c 687 pbuf += sample_size_in_bytes;
Mahesh Phalke 2:7b2b268ea49c 688 }
Mahesh Phalke 2:7b2b268ea49c 689 } while (remaining_samples > 0);
Mahesh Phalke 2:7b2b268ea49c 690
Mahesh Phalke 2:7b2b268ea49c 691 /* Stop any active conversion */
Mahesh Phalke 2:7b2b268ea49c 692 ret = adc_stop_data_capture();
Mahesh Phalke 2:7b2b268ea49c 693 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 694 return ret;
Mahesh Phalke 2:7b2b268ea49c 695 }
Mahesh Phalke 2:7b2b268ea49c 696
Mahesh Phalke 2:7b2b268ea49c 697 return 0;
Mahesh Phalke 2:7b2b268ea49c 698 }
Mahesh Phalke 2:7b2b268ea49c 699
Mahesh Phalke 2:7b2b268ea49c 700 /*!
Mahesh Phalke 2:7b2b268ea49c 701 * @brief Read requested number of ADC samples in continuous mode
Mahesh Phalke 2:7b2b268ea49c 702 * @param pbuf[in] - Pointer to data buffer
Mahesh Phalke 2:7b2b268ea49c 703 * @param nb_of_samples[in] - Number of samples to read
Mahesh Phalke 2:7b2b268ea49c 704 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 705 * @note The actual sample capturing happens through interrupt. This
Mahesh Phalke 2:7b2b268ea49c 706 * function tracks the buffer read pointer to read block of data
Mahesh Phalke 2:7b2b268ea49c 707 */
Mahesh Phalke 2:7b2b268ea49c 708 static int32_t read_continuous_conv_data(int8_t **pbuf, uint32_t nb_of_samples)
Mahesh Phalke 2:7b2b268ea49c 709 {
Mahesh Phalke 2:7b2b268ea49c 710 volatile int8_t *rd_addr;
Mahesh Phalke 2:7b2b268ea49c 711 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 712
Mahesh Phalke 2:7b2b268ea49c 713 if (!pbuf) {
Mahesh Phalke 2:7b2b268ea49c 714 return -EINVAL;
Mahesh Phalke 2:7b2b268ea49c 715 }
Mahesh Phalke 2:7b2b268ea49c 716
Mahesh Phalke 2:7b2b268ea49c 717 /* Determine the max available buffer size based on the requested
Mahesh Phalke 2:7b2b268ea49c 718 * samples count and actual avilable buffer size. Buffer should be
Mahesh Phalke 2:7b2b268ea49c 719 * capable of holding all requested 'n' samples from previous write
Mahesh Phalke 2:7b2b268ea49c 720 * index upto to the end of buffer, as data is read linearly
Mahesh Phalke 2:7b2b268ea49c 721 * from adc buffer in IIO library.
Mahesh Phalke 2:7b2b268ea49c 722 * E.g. If actual buffer size is 2048 samples and requested samples
Mahesh Phalke 2:7b2b268ea49c 723 * are 1600, max available buffer size is actually 1600. So in given
Mahesh Phalke 2:7b2b268ea49c 724 * iteration, only 1600 samples will be stored into buffer and after
Mahesh Phalke 2:7b2b268ea49c 725 * that buffer indexes will be wrapped to a start of buffer. If index
Mahesh Phalke 2:7b2b268ea49c 726 * is not wrapped, the next 1600 requested samples won't accomodate into
Mahesh Phalke 2:7b2b268ea49c 727 * remaining 448 samples space. As buffer is read in linear fashion, the
Mahesh Phalke 2:7b2b268ea49c 728 * read index can't be wrapped to start of buffer to read remaining samples.
Mahesh Phalke 2:7b2b268ea49c 729 * So max available space in this case is 2048 but only utilized space
Mahesh Phalke 2:7b2b268ea49c 730 * will be 1600 in single read buffer request from IIO client.
Mahesh Phalke 2:7b2b268ea49c 731 **/
Mahesh Phalke 2:7b2b268ea49c 732 max_buffer_sz = ((DATA_BUFFER_SIZE / sample_size_in_bytes) /
Mahesh Phalke 2:7b2b268ea49c 733 nb_of_samples) * nb_of_samples;
Mahesh Phalke 2:7b2b268ea49c 734
Mahesh Phalke 2:7b2b268ea49c 735 ret = buffer_read_operations(nb_of_samples);
Mahesh Phalke 2:7b2b268ea49c 736 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 737 return ret;
Mahesh Phalke 2:7b2b268ea49c 738 }
Mahesh Phalke 2:7b2b268ea49c 739
Mahesh Phalke 2:7b2b268ea49c 740 /* Get the next read address */
Mahesh Phalke 2:7b2b268ea49c 741 rd_addr = (volatile int8_t *)(acq_buffer.rd_pdata + (acq_buffer.rd_indx *
Mahesh Phalke 2:7b2b268ea49c 742 sample_size_in_bytes));
Mahesh Phalke 2:7b2b268ea49c 743 acq_buffer.rd_indx += nb_of_samples;
Mahesh Phalke 2:7b2b268ea49c 744
Mahesh Phalke 2:7b2b268ea49c 745 /* Update the IIO buffer pointer to point to next read start location */
Mahesh Phalke 2:7b2b268ea49c 746 *pbuf = rd_addr;
Mahesh Phalke 2:7b2b268ea49c 747
Mahesh Phalke 2:7b2b268ea49c 748 return 0;
Mahesh Phalke 2:7b2b268ea49c 749 }
Mahesh Phalke 2:7b2b268ea49c 750
Mahesh Phalke 2:7b2b268ea49c 751 /*!
Mahesh Phalke 2:7b2b268ea49c 752 * @brief Function to read the ADC buffered raw data requested
Mahesh Phalke 2:7b2b268ea49c 753 * by IIO client
Mahesh Phalke 2:7b2b268ea49c 754 * @param pbuf[in] - Pointer to data buffer
Mahesh Phalke 2:7b2b268ea49c 755 * @param nb_of_bytes[in] - Number of bytes to read
Mahesh Phalke 2:7b2b268ea49c 756 * @return 0 in case of success, negative error code otherwise
Mahesh Phalke 2:7b2b268ea49c 757 */
Mahesh Phalke 2:7b2b268ea49c 758 int32_t read_buffered_data(int8_t **pbuf, uint32_t nb_of_bytes)
Mahesh Phalke 2:7b2b268ea49c 759 {
Mahesh Phalke 2:7b2b268ea49c 760 int32_t ret;
Mahesh Phalke 2:7b2b268ea49c 761 num_of_requested_samples = nb_of_bytes / sample_size_in_bytes;
Mahesh Phalke 2:7b2b268ea49c 762
Mahesh Phalke 2:7b2b268ea49c 763 #if (DATA_CAPTURE_MODE == BURST_DATA_CAPTURE)
Mahesh Phalke 2:7b2b268ea49c 764 ret = read_burst_data(*pbuf, num_of_requested_samples);
Mahesh Phalke 2:7b2b268ea49c 765 #elif (DATA_CAPTURE_MODE == FIFO_DATA_CAPTURE)
Mahesh Phalke 2:7b2b268ea49c 766 ret = read_fifo_data(*pbuf, num_of_requested_samples);
Mahesh Phalke 2:7b2b268ea49c 767 #else
Mahesh Phalke 2:7b2b268ea49c 768 ret = read_continuous_conv_data(pbuf, num_of_requested_samples);
Mahesh Phalke 2:7b2b268ea49c 769 #endif
Mahesh Phalke 2:7b2b268ea49c 770
Mahesh Phalke 2:7b2b268ea49c 771 if (ret) {
Mahesh Phalke 2:7b2b268ea49c 772 return ret;
Mahesh Phalke 2:7b2b268ea49c 773 }
Mahesh Phalke 2:7b2b268ea49c 774
Mahesh Phalke 2:7b2b268ea49c 775 return 0;
Mahesh Phalke 2:7b2b268ea49c 776 }