Example program for EVAL-AD4130
Dependencies: tempsensors sdp_k1_sdram
ad4130_data_capture.c
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 }
Generated on Wed Jul 20 2022 12:42:25 by 1.7.2