Example program for EVAL-AD4130

Dependencies:   tempsensors sdp_k1_sdram

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ad4130_data_capture.c Source File

ad4130_data_capture.c

Go to the documentation of this file.
00001 /***************************************************************************//**
00002  *   @file    ad4130_data_capture.c
00003  *   @brief   AD4130 data capture interface for IIO based applications
00004  *   @details This module handles the ADC data capturing for IIO client
00005 ********************************************************************************
00006  * Copyright (c) 2021-22 Analog Devices, Inc.
00007  * All rights reserved.
00008  *
00009  * This software is proprietary to Analog Devices, Inc. and its licensors.
00010  * By using this software you agree to the terms of the associated
00011  * Analog Devices Software License Agreement.
00012 *******************************************************************************/
00013 
00014 /******************************************************************************/
00015 /***************************** Include Files **********************************/
00016 /******************************************************************************/
00017 
00018 #include <string.h>
00019 
00020 #include "app_config.h"
00021 #include "ad413x.h"
00022 #include "ad4130_support.h"
00023 #include "ad4130_iio.h"
00024 #include "ad4130_regs.h"
00025 #include "ad4130_data_capture.h"
00026 #include "ad4130_user_config.h"
00027 #include "no_os_gpio.h"
00028 #include "no_os_error.h"
00029 
00030 /******************************************************************************/
00031 /********************** Macros and Constants Definition ***********************/
00032 /******************************************************************************/
00033 
00034 /* Timeout count to avoid stuck into potential infinite loop while checking
00035  * for new data into an acquisition buffer. The actual timeout factor is determined
00036  * through 'sampling_frequency' attribute of IIO app, but this period here makes sure
00037  * we are not stuck into a forever loop in case data capture is interrupted
00038  * or failed in between.
00039  * Note: This timeout factor is dependent upon the MCU clock frequency. Below timeout
00040  * is tested for SDP-K1 platform @180Mhz default core clock */
00041 #define BUF_READ_TIMEOUT    0xffffffff
00042 
00043 /* Fifo depth limit (watermark count) for data capture */
00044 #define FIFO_SIZE       256     // Range: 1-256
00045 
00046 /******************************************************************************/
00047 /********************** Variables and User Defined Data Types *****************/
00048 /******************************************************************************/
00049 
00050 /* ADC data buffer */
00051 #if !defined(USE_SDRAM_CAPTURE_BUFFER)
00052 int8_t adc_data_buffer[DATA_BUFFER_SIZE] = { 0 };
00053 #endif
00054 
00055 /*
00056  *@enum     acq_buffer_state_e
00057  *@details  Enum holding the data acquisition buffer states
00058  **/
00059 typedef enum {
00060     BUF_AVAILABLE,
00061     BUF_EMPTY,
00062     BUF_FULL
00063 } acq_buffer_state_e;
00064 
00065 /*
00066  *@struct   acq_buf_t
00067  *@details  Structure holding the data acquisition buffer parameters
00068  **/
00069 typedef struct {
00070     acq_buffer_state_e state;   // Buffer state
00071     uint32_t wr_indx;           // Buffer write index (incremented per sample read)
00072     uint32_t rd_indx;           // Buffer read index (incremented per sample read)
00073     int8_t *wr_pdata;           // Data buffer write pointer
00074     int8_t *rd_pdata;           // Data buffer read pointer
00075     bool reindex_buffer;        // Reindex buffer to 0th channel
00076 } acq_buf_t;
00077 
00078 /* ADC data acquisition buffers */
00079 static volatile acq_buf_t acq_buffer;
00080 
00081 /* Flag to indicate data capture status */
00082 static volatile bool start_cont_data_capture = false;
00083 
00084 /* Count to track number of actual samples requested by IIO client */
00085 static volatile uint32_t num_of_requested_samples = 0;
00086 
00087 /* ADC sample/raw data size in bytes */
00088 static volatile uint8_t sample_size_in_bytes;
00089 
00090 /* Max available buffer size (after considering the data alignment with IIO buffer) */
00091 static volatile uint32_t max_buffer_sz;
00092 
00093 /* List of channels to be captured */
00094 static volatile uint8_t active_channels[ADC_USER_CHANNELS];
00095 
00096 /* Number of active channels */
00097 static volatile uint8_t num_of_active_channels;
00098 
00099 /* Current active channel index */
00100 static volatile uint8_t chn_indx;
00101 
00102 /* FIFO data capture flags */
00103 static volatile bool start_fifo_mode_data_capture = false;
00104 static volatile bool fifo_data_available = false;
00105 static uint32_t fifo_data[FIFO_SIZE];
00106 
00107 /******************************************************************************/
00108 /************************ Functions Declarations ******************************/
00109 /******************************************************************************/
00110 
00111 /******************************************************************************/
00112 /************************ Functions Definitions *******************************/
00113 /******************************************************************************/
00114 
00115 /*!
00116  * @brief   Function to init the data capture for AD4130 device
00117  * @return  0 in case of success, negative error code otherwise
00118  */
00119 int32_t ad4130_data_capture_init(void)
00120 {
00121     int32_t ret;
00122     uint8_t preset;
00123     adc_conv_int_source_e conv_int_source;
00124 
00125     /* Stop any previous conversion */
00126     ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_STANDBY_MODE);
00127     if (ret) {
00128         return ret;
00129     }
00130 
00131     /* Select and enable the interupt pin source for data conversion monitor */
00132 #if defined(AD4130_WLCSP_PACKAGE_TYPE)
00133     conv_int_source = INT_PIN;
00134 #else
00135     conv_int_source = CLK_PIN;
00136 #endif
00137 
00138     ret = ad413x_set_int_source(ad4130_dev_inst, conv_int_source);
00139     if (ret) {
00140         return ret;
00141     }
00142 
00143     /* Set the filter FS value (same for all setups/channels for
00144      * consistant ODR/sample rate) */
00145     for (preset = 0; preset <= ADC_PRESETS; preset++) {
00146         ret = ad413x_set_filter_fs(ad4130_dev_inst, AD4130_FS_CONFIG, preset);
00147         if (ret) {
00148             return ret;
00149         }
00150     }
00151 
00152     return 0;
00153 }
00154 
00155 /*!
00156  * @brief   Store the list of all previously enabled channels and enable
00157  *          new channels set in the channel mask argument
00158  * @param   chn_mask[in] - Active channels list
00159  * @return  0 in case of success, negative error code otherwise
00160  */
00161 static int32_t adc_store_active_chns(uint32_t chn_mask)
00162 {
00163     uint8_t mask = 0x1;
00164     uint8_t index = 0;
00165     uint8_t chn;
00166     int32_t ret;
00167 
00168     /* Enable/Disable channels based on channel mask set in the IIO client */
00169     for (chn = 0; chn < ADC_USER_CHANNELS; chn++) {
00170         if (chn_mask & mask) {
00171             /* Store the active channel */
00172             active_channels[index++] = chn;
00173             num_of_active_channels++;
00174 
00175             /* Enable the selected channel */
00176             ret = ad413x_ch_en(ad4130_dev_inst, chn, 1);
00177         } else {
00178             /* Disable the selected channel */
00179             ret = ad413x_ch_en(ad4130_dev_inst, chn, 0);
00180         }
00181 
00182         if (ret) {
00183             return ret;
00184         }
00185 
00186         mask <<= 1;
00187     }
00188 
00189     return 0;
00190 }
00191 
00192 /*!
00193  * @brief   Trigger a data capture in continuous/burst mode
00194  * @return  0 in case of success, negative error code otherwise
00195  */
00196 static int32_t adc_start_data_capture(void)
00197 {
00198     int32_t ret;
00199 
00200     /* Stop any previous conversion */
00201     ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_STANDBY_MODE);
00202     if (ret) {
00203         return ret;
00204     }
00205 
00206     /* Trigger new conversion */
00207     ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_CONTINOUS_CONV_MODE);
00208     if (ret) {
00209         return ret;
00210     }
00211 
00212     return 0;
00213 }
00214 
00215 /*!
00216  * @brief   Stop a data capture from continuous/burst/fifo mode
00217  * @return  0 in case of success, negative error code otherwise
00218  */
00219 static int32_t adc_stop_data_capture(void)
00220 {
00221     /* Stop any active conversion */
00222     return ad413x_set_adc_mode(ad4130_dev_inst, AD413X_STANDBY_MODE);
00223 }
00224 
00225 /*!
00226  * @brief   Trigger a data capture in FIFO mode
00227  * @return  0 in case of success, negative error code otherwise
00228  */
00229 static int32_t adc_start_fifo_data_capture(void)
00230 {
00231     int32_t ret;
00232     uint32_t fifo_control_reg_val;
00233 
00234     /* Read FIFO control register */
00235     ret = ad413x_reg_read(ad4130_dev_inst, AD413X_REG_FIFO_CTRL,
00236                   &fifo_control_reg_val);
00237     if (ret) {
00238         return ret;
00239     }
00240 
00241     /* Store the watermark count in FIFO */
00242     fifo_control_reg_val = (fifo_control_reg_val & ~AD413X_WATERMARK_MSK) |
00243                    AD413X_WATERMARK(FIFO_SIZE);
00244 
00245     /* Select the FIFO mode to enable FIFO and enable watermark interrupt */
00246     fifo_control_reg_val = (fifo_control_reg_val & ~AD4130_FIFO_MODE_MSK) |
00247                    AD413X_FIFO_MODE(FIFO_OLDEST_SAVE_MODE) |
00248                    AD413X_WATERMARK_INT_EN;
00249 
00250     /* Disable the FIFO header and status (FIFO status and header is not appended to data) */
00251     fifo_control_reg_val &= ~(AD413X_ADD_FIFO_HEADER | AD413X_ADD_FIFO_STATUS);
00252 
00253     /* Write to ADC fifo_ctrl register */
00254     ret = ad413x_reg_write(ad4130_dev_inst, AD413X_REG_FIFO_CTRL,
00255                    fifo_control_reg_val);
00256     if (ret) {
00257         return ret;
00258     }
00259 
00260     start_fifo_mode_data_capture = true;
00261     ret = adc_start_data_capture();
00262     if (ret) {
00263         return ret;
00264     }
00265 
00266     return 0;
00267 }
00268 
00269 /*!
00270  * @brief   Read a single sample of ADC
00271  * @param   adc_raw[in] - Pointer to ADC raw data variable
00272  * @return  0 in case of success, negative error code otherwise
00273  */
00274 static int32_t adc_read_single_sample(uint32_t *adc_raw)
00275 {
00276     if (!adc_raw) {
00277         return -EINVAL;
00278     }
00279 
00280     return ad413x_mon_conv_and_read_data(ad4130_dev_inst, adc_raw);
00281 }
00282 
00283 /*!
00284  * @brief   Read a single sample of ADC
00285  * @param   data[in] - Pointer to FIFO data array
00286  * @param   samples[in] - Number of samples to read
00287  * @return  0 in case of success, negative error code otherwise
00288  */
00289 static int32_t adc_read_fifo(uint32_t *data, uint32_t samples)
00290 {
00291     if (!data) {
00292         return -EINVAL;
00293     }
00294 
00295     return ad4130_read_fifo(ad4130_dev_inst, data, samples);
00296 }
00297 
00298 /*!
00299  * @brief   Read ADC raw data for recently sampled channel
00300  * @param   adc_data[in, out] - Pointer to adc data read variable
00301  * @param   input_chn[in] - Input channel (optional)
00302  * @return  0 in case of success, negative error code otherwise
00303  * @note    This function is intended to call from the conversion end trigger
00304  *          event. Therefore, this function should just read raw ADC data
00305  *          without further monitoring conversion end event.
00306  *          Continuous conversion mode is used to for this operation.
00307  */
00308 static int32_t adc_read_converted_sample(uint32_t *adc_data,
00309         uint8_t input_chn)
00310 {
00311     if (!adc_data) {
00312         return -EINVAL;
00313     }
00314 
00315     /* Read the ADC data for previously sampled channel in sequencer */
00316     return ad413x_reg_read(ad4130_dev_inst, AD413X_REG_DATA, adc_data);
00317 }
00318 
00319 /*!
00320  * @brief   Function to read the single ADC sample (raw data) for input channel
00321  * @param   input_chn[in] - Input channel to be sampled and read data for
00322  * @param   raw_data[in, out]- ADC raw data
00323  * @return  0 in case of success, negative error code otherwise
00324  * @note    The single conversion mode is used to read a single sample
00325  */
00326 int32_t read_single_sample(uint8_t input_chn, uint32_t *adc_raw)
00327 {
00328     uint32_t chn_mask = 0;
00329     uint8_t chn;
00330     int32_t ret;
00331 
00332     if (!adc_raw) {
00333         return -EINVAL;
00334     }
00335 
00336     /* Disable all active channels */
00337     for (chn = 0; chn < ADC_USER_CHANNELS; chn++) {
00338         if (ad4130_dev_inst->ch[chn].enable) {
00339             chn_mask |= (1 << chn);
00340 
00341             /* Disable the current channel */
00342             ret = ad413x_ch_en(ad4130_dev_inst, chn, 0);
00343             if (ret) {
00344                 return ret;
00345             }
00346         }
00347     }
00348 
00349     /* Enable user input channel */
00350     if (!ad4130_dev_inst->ch[input_chn].enable) {
00351         ret = ad413x_ch_en(ad4130_dev_inst, input_chn, 1);
00352         if (ret) {
00353             return ret;
00354         }
00355     }
00356 
00357     /* Put device into single conversion mode */
00358     ret = ad413x_set_adc_mode(ad4130_dev_inst, AD413X_SINGLE_CONV_MODE);
00359     if (ret) {
00360         return ret;
00361     }
00362 
00363     /* Monitor conversion and read the result */
00364     ret = ad413x_mon_conv_and_read_data(ad4130_dev_inst, adc_raw);
00365 
00366     /* Disable user input channel */
00367     ret = ad413x_ch_en(ad4130_dev_inst, input_chn, 0);
00368     if (ret) {
00369         return ret;
00370     }
00371 
00372     return 0;
00373 }
00374 
00375 /********* Device Independent Data Capture Code Begin ************/
00376 
00377 /*!
00378  * @brief   Reset the data capture specific variables
00379  * @return  none
00380  */
00381 static void reset_data_capture(void)
00382 {
00383     /* Reset data capture flags */
00384     start_cont_data_capture = false;
00385     start_fifo_mode_data_capture = false;
00386     num_of_active_channels = 0;
00387     chn_indx = 0;
00388 
00389     /* Reset acquisition buffer states and clear old data */
00390     acq_buffer.state = BUF_EMPTY;
00391     acq_buffer.wr_indx = 0;
00392     acq_buffer.rd_indx = 0;
00393     acq_buffer.reindex_buffer = false;
00394     acq_buffer.wr_pdata = adc_data_buffer;
00395     acq_buffer.rd_pdata = adc_data_buffer;
00396     max_buffer_sz = DATA_BUFFER_SIZE;
00397 }
00398 
00399 /*!
00400  * @brief   Function to prepare the data ADC capture for new READBUFF
00401  *          request from IIO client (for active channels)
00402  * @param   ch_mask[in] - Channels to enable for data capturing
00403  * @param   sample_size[in] - Sample size in bytes
00404  * @return  0 in case of success, negative error code otherwise
00405  */
00406 int32_t prepare_data_transfer(uint32_t ch_mask, uint8_t sample_size)
00407 {
00408     int32_t ret;
00409 
00410     /* Reset data capture module specific flags and variables */
00411     reset_data_capture();
00412 
00413     sample_size_in_bytes = sample_size;
00414 
00415     /* Store active channels */
00416     ret = adc_store_active_chns(ch_mask);
00417     if (ret) {
00418         return ret;
00419     }
00420 
00421 #if (DATA_CAPTURE_MODE == CONTINUOUS_DATA_CAPTURE)
00422     /* Trigger continuous data capture */
00423     ret = adc_start_data_capture();
00424     if (ret) {
00425         return ret;
00426     }
00427 
00428     acq_buffer.state = BUF_AVAILABLE;
00429     start_cont_data_capture = true;
00430 #endif
00431 
00432     return 0;
00433 }
00434 
00435 /*!
00436  * @brief   Function to stop ADC data capture
00437  * @return  0 in case of success, negative error code otherwise
00438  */
00439 int32_t end_data_transfer(void)
00440 {
00441     int32_t ret;
00442     start_cont_data_capture = false;
00443 
00444     /* Stop data capture */
00445     ret = adc_stop_data_capture();
00446     if (ret) {
00447         return ret;
00448     }
00449 
00450     /* Reset data capture module specific flags and variables */
00451     reset_data_capture();
00452 
00453     return 0;
00454 }
00455 
00456 /*!
00457  * @brief   Perform buffer read operations to read requested samples
00458  * @param   nb_of_samples[in] - Requested number of samples to read
00459  * @return  0 in case of success, negative error code otherwise
00460  */
00461 static int32_t buffer_read_operations(uint32_t nb_of_samples)
00462 {
00463     uint32_t timeout = BUF_READ_TIMEOUT;
00464     int32_t offset;
00465 
00466     /* Wait until requested samples are available in the buffer to read */
00467     do {
00468         if (acq_buffer.wr_indx >= acq_buffer.rd_indx) {
00469             offset = acq_buffer.wr_indx - acq_buffer.rd_indx;
00470         } else {
00471             offset = max_buffer_sz + (acq_buffer.wr_indx - acq_buffer.rd_indx);
00472         }
00473 
00474         timeout--;
00475     } while ((offset < (int32_t)(nb_of_samples)) && (timeout > 0));
00476 
00477     if (timeout == 0) {
00478         /* This returns the empty buffer */
00479         return -EIO;
00480     }
00481 
00482     if (acq_buffer.rd_indx >= max_buffer_sz) {
00483         acq_buffer.rd_indx = 0;
00484     }
00485 
00486     return 0;
00487 }
00488 
00489 /*!
00490  * @brief   Perform buffer write operations such as buffer full or empty
00491  *          check, resetting buffer index and pointers, etc
00492  * @return  none
00493  */
00494 static void buffer_write_operations(void)
00495 {
00496     acq_buffer.wr_indx++;
00497 
00498     /* Perform buffer full check and operations */
00499     if (acq_buffer.wr_indx >= max_buffer_sz) {
00500         if ((acq_buffer.rd_indx >= num_of_requested_samples)
00501             && (acq_buffer.rd_indx != 0)) {
00502             /* Reset buffer write index and write pointer when enough
00503              * space available in the buffer to wrap to start */
00504             acq_buffer.wr_indx = 0;
00505             acq_buffer.wr_pdata = adc_data_buffer;
00506             if (acq_buffer.rd_indx >= max_buffer_sz) {
00507                 /* Wrap the read index and read pointer to start of buffer
00508                  * if buffer is completely read/emptied */
00509                 acq_buffer.rd_indx = 0;
00510                 acq_buffer.rd_pdata = adc_data_buffer;
00511             }
00512 
00513             acq_buffer.state = BUF_AVAILABLE;
00514         } else {
00515             /* Wait until enough space available to wrap buffer write index
00516              * at the start of buffer */
00517             acq_buffer.wr_indx = max_buffer_sz;
00518             acq_buffer.state = BUF_FULL;
00519             acq_buffer.reindex_buffer = true;
00520         }
00521     }
00522 }
00523 
00524 /*!
00525  * @brief   This is an ISR (Interrupt Service Routine) to monitor end of conversion event.
00526  * @param   ctx[in] - Callback context (unused)
00527  * @return  none
00528  * @details This is an Interrupt callback function/ISR invoked in synchronous/asynchronous
00529  *          manner depending upon the application implementation. The conversion results
00530  *          are read into acquisition buffer and control continue to sample next channel.
00531  *          This continues until conversion is stopped (through IIO client command)
00532  */
00533 void data_capture_callback(void *ctx)
00534 {
00535     uint32_t adc_sample;
00536     volatile uint8_t *wr_addr;
00537 
00538     if (start_cont_data_capture == true) {
00539         /* Read the sample for channel which has been sampled recently */
00540         if (!adc_read_converted_sample(&adc_sample,
00541                            active_channels[chn_indx])) {
00542             do {
00543                 if (acq_buffer.state == BUF_AVAILABLE) {
00544                     if (acq_buffer.reindex_buffer) {
00545                         /* Buffer refilling must start with first active channel data
00546                          * for IIO client to synchronize the buffered data */
00547                         if (chn_indx != 0) {
00548                             break;
00549                         }
00550                         acq_buffer.reindex_buffer = false;
00551                     }
00552 
00553                     /* Copy adc samples into acquisition buffer to transport over
00554                      * communication link */
00555                     wr_addr = (volatile uint8_t *)(acq_buffer.wr_pdata + (acq_buffer.wr_indx *
00556                                        sample_size_in_bytes));
00557                     memcpy((uint8_t *)wr_addr, &adc_sample, sample_size_in_bytes);
00558                 }
00559 
00560                 /* Perform buffer write operations */
00561                 buffer_write_operations();
00562             } while (0);
00563 
00564             /* Track the count for recently sampled channel */
00565             chn_indx++;
00566             if (chn_indx >= num_of_active_channels) {
00567                 chn_indx = 0;
00568             }
00569         }
00570     }
00571 }
00572 
00573 /*!
00574  * @brief   This is an ISR (Interrupt Service Routine) to monitor FIFO data available event.
00575  *          This function is expected to be called asynchronously when data from internal device
00576  *          FIFO is available to read.
00577  * @param   ctx[in] - Callback context (unused)
00578  * @return  none
00579  */
00580 void fifo_data_capture_callback(void *ctx)
00581 {
00582     if (start_fifo_mode_data_capture) {
00583         fifo_data_available = true;
00584     }
00585 }
00586 
00587 /*!
00588  * @brief   Capture requested number of ADC samples in burst mode
00589  * @param   pbuf[out] - Pointer to ADC data buffer
00590  * @param   nb_of_samples[in] - Number of samples to be read
00591  * @return  0 in case of success, negative error code otherwise
00592  */
00593 static int32_t read_burst_data(int8_t *pbuf, uint32_t nb_of_samples)
00594 {
00595     uint32_t sample_indx = 0;
00596     uint32_t adc_raw;
00597     int32_t ret;
00598 
00599     if (!pbuf) {
00600         return -EINVAL;
00601     }
00602 
00603     ret = adc_start_data_capture();
00604     if (ret) {
00605         return ret;
00606     }
00607 
00608     while (sample_indx < nb_of_samples) {
00609         ret = adc_read_single_sample(&adc_raw);
00610         if (ret) {
00611             return ret;
00612         }
00613 
00614         /* Copy adc samples into acquisition buffer to transport over
00615          * communication link */
00616         memcpy((uint8_t *)pbuf, &adc_raw, sample_size_in_bytes);
00617         pbuf += sample_size_in_bytes;
00618 
00619         sample_indx++;
00620     }
00621 
00622     /* Stop any active conversion */
00623     ret = adc_stop_data_capture();
00624     if (ret) {
00625         return ret;
00626     }
00627 
00628     return 0;
00629 }
00630 
00631 /*!
00632  * @brief   Capture requested number of ADC samples in FIFO mode
00633  * @param   pbuf[in] - Input buffer
00634  * @param   nb_of_samples[in] - Number of samples to read
00635  * @return  0 in case of success, negative error code otherwise
00636  */
00637 static int32_t read_fifo_data(int8_t *pbuf,
00638                   uint32_t nb_of_samples)
00639 {
00640     uint32_t sample_cnt;
00641     uint32_t remaining_samples = nb_of_samples;
00642     uint32_t timeout = BUF_READ_TIMEOUT;
00643     int32_t ret;
00644 
00645     if (!pbuf) {
00646         return -EINVAL;
00647     }
00648 
00649     fifo_data_available = false;
00650 
00651     ret = adc_start_fifo_data_capture();
00652     if (ret) {
00653         return ret;
00654     }
00655 
00656     /* Read all requeted samples into acquisition buffer */
00657     do {
00658         /* Wait for new FIFO event */
00659         timeout = BUF_READ_TIMEOUT;
00660         do {
00661             timeout--;
00662         } while ((!fifo_data_available) && (timeout > 0));
00663 
00664         if (timeout == 0) {
00665             return -EIO;
00666         }
00667 
00668         fifo_data_available = false;
00669 
00670         if (remaining_samples > FIFO_SIZE) {
00671             nb_of_samples = FIFO_SIZE;
00672             remaining_samples -= nb_of_samples;
00673         } else {
00674             nb_of_samples = remaining_samples;
00675             remaining_samples = 0;
00676         }
00677 
00678         /* Read data from FIFO and store into local buffer */
00679         ret = adc_read_fifo(fifo_data, nb_of_samples);
00680         if (ret) {
00681             return ret;
00682         }
00683 
00684         /* Read offloaded FIFO data and store into acquisition buffer */
00685         for (sample_cnt = 0; sample_cnt < nb_of_samples; sample_cnt++) {
00686             memcpy(pbuf, &fifo_data[sample_cnt], sample_size_in_bytes);
00687             pbuf += sample_size_in_bytes;
00688         }
00689     } while (remaining_samples > 0);
00690 
00691     /* Stop any active conversion */
00692     ret = adc_stop_data_capture();
00693     if (ret) {
00694         return ret;
00695     }
00696 
00697     return 0;
00698 }
00699 
00700 /*!
00701  * @brief   Read requested number of ADC samples in continuous mode
00702  * @param   pbuf[in] - Pointer to data buffer
00703  * @param   nb_of_samples[in] - Number of samples to read
00704  * @return  0 in case of success, negative error code otherwise
00705  * @note    The actual sample capturing happens through interrupt. This
00706  *          function tracks the buffer read pointer to read block of data
00707  */
00708 static int32_t read_continuous_conv_data(int8_t **pbuf, uint32_t nb_of_samples)
00709 {
00710     volatile int8_t *rd_addr;
00711     int32_t ret;
00712 
00713     if (!pbuf) {
00714         return -EINVAL;
00715     }
00716 
00717     /* Determine the max available buffer size based on the requested
00718      * samples count and actual avilable buffer size. Buffer should be
00719      * capable of holding all requested 'n' samples from previous write
00720      * index upto to the end of buffer, as data is read linearly
00721      * from adc buffer in IIO library.
00722      * E.g. If actual buffer size is 2048 samples and requested samples
00723      * are 1600, max available buffer size is actually 1600. So in given
00724      * iteration, only 1600 samples will be stored into buffer and after
00725      * that buffer indexes will be wrapped to a start of buffer. If index
00726      * is not wrapped, the next 1600 requested samples won't accomodate into
00727      * remaining 448 samples space. As buffer is read in linear fashion, the
00728      * read index can't be wrapped to start of buffer to read remaining samples.
00729      * So max available space in this case is 2048 but only utilized space
00730      * will be 1600 in single read buffer request from IIO client.
00731      **/
00732     max_buffer_sz = ((DATA_BUFFER_SIZE / sample_size_in_bytes) /
00733              nb_of_samples) * nb_of_samples;
00734 
00735     ret = buffer_read_operations(nb_of_samples);
00736     if (ret) {
00737         return ret;
00738     }
00739 
00740     /* Get the next read address */
00741     rd_addr = (volatile int8_t *)(acq_buffer.rd_pdata + (acq_buffer.rd_indx *
00742                       sample_size_in_bytes));
00743     acq_buffer.rd_indx += nb_of_samples;
00744 
00745     /* Update the IIO buffer pointer to point to next read start location */
00746     *pbuf = rd_addr;
00747 
00748     return 0;
00749 }
00750 
00751 /*!
00752  * @brief   Function to read the ADC buffered raw data requested
00753  *          by IIO client
00754  * @param   pbuf[in] - Pointer to data buffer
00755  * @param   nb_of_bytes[in] - Number of bytes to read
00756  * @return  0 in case of success, negative error code otherwise
00757  */
00758 int32_t read_buffered_data(int8_t **pbuf, uint32_t nb_of_bytes)
00759 {
00760     int32_t ret;
00761     num_of_requested_samples = nb_of_bytes / sample_size_in_bytes;
00762 
00763 #if (DATA_CAPTURE_MODE == BURST_DATA_CAPTURE)
00764     ret = read_burst_data(*pbuf, num_of_requested_samples);
00765 #elif (DATA_CAPTURE_MODE == FIFO_DATA_CAPTURE)
00766     ret = read_fifo_data(*pbuf, num_of_requested_samples);
00767 #else
00768     ret = read_continuous_conv_data(pbuf, num_of_requested_samples);
00769 #endif
00770 
00771     if (ret) {
00772         return ret;
00773     }
00774 
00775     return 0;
00776 }