Example Program for EVAL-AD7606
Dependencies: platform_drivers
Revision 7:054dbd5e1f45, committed 2021-08-03
- Comitter:
- Kjansen
- Date:
- Tue Aug 03 11:54:49 2021 +0100
- Parent:
- 6:32de160dce43
- Commit message:
- Modified the ADC data capture module to remove dependancy on type of ADC and it's specific operations
Changed in this revision
diff -r 32de160dce43 -r 054dbd5e1f45 app/.mbedignore --- a/app/.mbedignore Wed Jul 21 11:16:56 2021 +0100 +++ b/app/.mbedignore Tue Aug 03 11:54:49 2021 +0100 @@ -57,6 +57,4 @@ no-OS/tools/ no-OS/v4l2_config/ libtinyiiod/ci/ -libtinyiiod/example.c -mbed_platform_drivers/adc_data_capture.c -mbed_platform_drivers/adc_data_capture.h \ No newline at end of file +libtinyiiod/example.c \ No newline at end of file
diff -r 32de160dce43 -r 054dbd5e1f45 app/ad7606_data_capture.c --- a/app/ad7606_data_capture.c Wed Jul 21 11:16:56 2021 +0100 +++ b/app/ad7606_data_capture.c Tue Aug 03 11:54:49 2021 +0100 @@ -3,8 +3,7 @@ * @brief Data capture interface for AD7606 IIO application * @details This module handles the AD7606 data capturing ******************************************************************************** - * Copyright (c) 2020 Analog Devices, Inc. - * + * Copyright (c) 2020-2021 Analog Devices, Inc. * All rights reserved. * * This software is proprietary to Analog Devices, Inc. and its licensors. @@ -21,135 +20,88 @@ #include "app_config.h" #include "ad7606_data_capture.h" +#include "iio_ad7606.h" #include "ad7606_support.h" -#include "gpio_extra.h" +#include "error.h" +#include "adc_data_capture.h" /******************************************************************************/ /********************** Macros and Constants Definition ***********************/ /******************************************************************************/ -#if (AD7606X_ADC_RESOLUTION > 16) -#define BYTES_PER_SAMPLE sizeof(uint32_t) +#if (AD7606X_ADC_RESOLUTION == 18) +#define SAMPLE_SIZE_IN_BYTE 3 #else -#define BYTES_PER_SAMPLE sizeof(uint16_t) +#define SAMPLE_SIZE_IN_BYTE 2 #endif -/* Max size of the acquisition buffer (in terms of samples) */ -#define DATA_BUFFER_SIZE (8192) - -/* Timeout count to avoid stuck into potential infinite loop while checking - * for new data into an acquisition buffer. The actual timeout factor is determined - * through 'sampling_frequency' attribute, but this period here makes sure - * we are not stuck into a loop forever, in case data capture interrupted - * or failed in between */ -#define BUF_READ_TIMEOUT (5000000) - /******************************************************************************/ /********************** Variables and User Defined Data Types *****************/ /******************************************************************************/ -/* Device instance for background adc conversion callback */ -static volatile struct ad7606_dev *dev = NULL; - -/* - *@enum acq_buffer_state_e - *@details Enum holding the data acquisition buffer states - **/ -typedef enum { - BUF_EMPTY, - BUF_AVAILABLE, - BUF_FULL -} acq_buffer_state_e; - -/* - *@struct acq_buf_t - *@details Structure holding the data acquisition buffer parameters - **/ -typedef struct { - acq_buffer_state_e state; // buffer state - uint32_t rd_indx; // buffer read index - uint32_t wr_indx; // buffer write index - uint32_t align_cnt; // buffer alignment counter -#if (AD7606X_ADC_RESOLUTION > 16) - uint32_t data[DATA_BUFFER_SIZE]; -#else - uint16_t data[DATA_BUFFER_SIZE]; -#endif -} acq_buf_t; - -/* ADC data acquisition buffers */ -static volatile acq_buf_t acq_buffer; - -/* Flag to indicate background data capture status */ -static volatile bool start_adc_data_capture = false; - -/* Active channels to be captured */ -static volatile uint32_t active_channels = 0; - -/* Number of active channels */ -static volatile uint8_t num_of_active_channels = 0; - -/* Minimum number of bytes to be read from device over digital interface */ -static volatile uint8_t min_bytes_to_read = 0; - -/* Number of channels requested for read into acquisition buffer */ -static volatile uint8_t chn_read_cnt = 0; - -/* Number of samples requested by IIO client */ -static volatile uint16_t num_of_samples = 0; - -/* Max available size of buffer */ -static volatile uint16_t max_available_buffer_size = 0; +/* Polarity of channels */ +static polarity_e polarity[AD7606X_ADC_CHANNELS]; /******************************************************************************/ /************************ Functions Declarations ******************************/ /******************************************************************************/ -static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end, - uint8_t *mask); +/* Perform conversion on input channel and read single conversion sample */ +static int32_t ad7606_perform_conv_and_read_sample(uint32_t *adc_data, + uint8_t chn); + +/* Perform continuous sample read pre-operations */ +static int32_t ad7606_continuous_sample_read_start_ops(uint32_t ch_mask); + +/* Read ADC sampled/conversion data */ +static int32_t ad7606_read_converted_sample(uint32_t *adc_data, + uint8_t input_chn); + +/* Trigger next ADC conversion */ +static int32_t ad7606_trigger_next_conversion(void); + +/* Define the variable for data_capture_ops structure */ +struct data_capture_ops data_capture_ops = { + /* Point AD7606 data capture functions to generic ADC data capture functions */ + .single_sample_read_start_ops = NULL, + .perform_conv_and_read_sample = ad7606_perform_conv_and_read_sample, + .single_sample_read_stop_ops = NULL, + .continuous_sample_read_start_ops = ad7606_continuous_sample_read_start_ops, + .read_converted_sample = ad7606_read_converted_sample, + .continuous_sample_read_stop_ops = NULL, + .trigger_next_conversion = ad7606_trigger_next_conversion +}; /******************************************************************************/ /************************ Functions Definitions *******************************/ /******************************************************************************/ /*! - * @brief Function to init the data capture for AD7606 device - * @param device[in]- Device instance - * @return none - */ -int32_t iio_data_capture_init(struct ad7606_dev **device) -{ - dev = *device; - return SUCCESS; -} - - -/*! - * @brief Function to read the ADC raw data for single channel - * @param device[in]- Device instance - * @param chn[in] - Input channel - * @return adc raw data/sample + * @brief Remove the offset from data to change output data format to + * normal or stright binary representation (needed for IIO client) + * @param adc_raw[out] - Pointer to adc data read variable + * @param bipolar[in] - Channel polarity + * @return SUCCESS in case of success, FAILURE otherwise */ -int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity) +static int32_t reformat_adc_raw_data(uint32_t adc_raw_data, polarity_e polarity) { - int32_t adc_data = 0; - uint32_t adc_raw[AD7606X_ADC_RESOLUTION] = { 0 }; - - if (ad7606_read(device, adc_raw) != SUCCESS) { - adc_raw[chn] = 0; - } + int32_t adc_data; + /* Bipolar ADC Range: (-FS) <-> 0 <-> (+FS) : 2^(ADC_RES-1) <-> 0 <-> 2^(ADC_RES-1)-1 + Unipolar ADC Range: 0 <-> (+FS) : 0 <-> 2^ADC_RES + **/ if (polarity == BIPOLAR) { - /* Check for negative adc value for bipolar inputs */ - if (adc_raw[chn] >= ADC_MAX_COUNT_BIPOLAR) { - /* Take the 2s complement for the negative counts (>full scale value) */ - adc_data = ADC_MAX_COUNT_UNIPOLAR - adc_raw[chn]; - adc_data = 0 - adc_data; + /* Data output format is 2's complement for bipolar mode */ + if (adc_raw_data > ADC_MAX_COUNT_BIPOLAR) { + /* Remove the offset from result to convert into negative reading */ + adc_data = ADC_MAX_COUNT_UNIPOLAR - adc_raw_data; + adc_data = -adc_data; } else { - adc_data = adc_raw[chn]; + adc_data = adc_raw_data; } } else { - adc_data = adc_raw[chn]; + /* Data output format is straight binary for unipolar mode */ + adc_data = adc_raw_data; } return adc_data; @@ -157,270 +109,132 @@ /*! - * @brief Function to store the number of requested samples from IIO client - * @param bytes[in] - Number of bytes corresponding to requested samples - * @return none + * @brief Perform conversion and read conversion sample + * @param adc_data[out] - Pointer to adc data read variable + * @param chn[in] - Channel for which data is to read + * @return SUCCESS in case of success, FAILURE otherwise */ -void store_requested_samples_count(size_t bytes) +int32_t ad7606_perform_conv_and_read_sample(uint32_t *adc_data, uint8_t chn) { - /* This gets the number of samples requested by IIO client for all active channels */ - num_of_samples = bytes / BYTES_PER_SAMPLE; - - /* Get the actual available size of buffer by aligning with number of requested samples. - * e.g. if requested samples are 1050, the max available size of buffer is: - * available size = (8192 / 1050) * 1050 = 7 * 1050 = 7350. - * The max samples to be requested should always be less than half the max size of buffer - * (in this case: 8192 / 2 = 4096). - * */ - max_available_buffer_size = ((DATA_BUFFER_SIZE / num_of_samples) * - num_of_samples); -} - + uint32_t adc_raw[AD7606X_ADC_CHANNELS] = { 0 }; + uint8_t read_val; + uint8_t chn_range; + polarity_e polarity; -/*! - * @brief Function to read new samples into buffer without timeout IIO request - * @param input_buffer[in] - Input data acquisition buffer - * @param output_buffer[in, out] - Output data buffer - * @param samples_to_read[in] - Number of samples to read - * @return none - */ -static void wait_and_read_new_samples(char *output_buffer, - size_t samples_to_read) -{ - int32_t buff_rd_wr_indx_offset; // Offset b/w buffer read and write indexes - uint32_t timeout = BUF_READ_TIMEOUT; // Buffer new data read timeout count - size_t bytes = samples_to_read * BYTES_PER_SAMPLE; - - /* Copy the bytes into buffer provided there is enough offset b/w read and write counts. - * If there is overlap b/w read and write indexes (read is faster than write), empty buffer - * should be returned to IIO client to avoid IIO request timeout */ - do { - buff_rd_wr_indx_offset = acq_buffer.wr_indx - acq_buffer.rd_indx; - timeout--; - } while (((buff_rd_wr_indx_offset < (int32_t)(samples_to_read)) - || (acq_buffer.wr_indx < acq_buffer.rd_indx)) && (timeout > 0) - && start_adc_data_capture); - - if ((timeout == 0) || (acq_buffer.wr_indx <= 0)) { - /* This returns the empty buffer */ - return; + /* Get input channel range */ + if (ad7606_spi_reg_read(p_ad7606_dev_inst, + AD7606_REG_RANGE_CH_ADDR(chn), + &read_val) != SUCCESS) { + return FAILURE; } - memcpy(output_buffer, - (void const *)&acq_buffer.data[acq_buffer.rd_indx], - bytes); - acq_buffer.rd_indx += samples_to_read; -} - - -/*! - * @brief Function to read and align the ADC buffered raw data - * @param device[in]- Device instance - * @param pbuf[out] - Buffer to load ADC raw data - * @param bytes[in] - Number of bytes to be read - * @param active_chns_mask[in] - Active channels mask - * @return Number of bytes read - */ -size_t buffered_data_read(char *pbuf, size_t bytes, size_t offset, - uint32_t active_chns_mask) -{ - size_t samples_to_read = bytes / BYTES_PER_SAMPLE; // Bytes to sample conversion - - /* Make sure requested samples size is less than ADC buffer size. Return constant - * value to avoid IIO client getting timed-out */ - if (num_of_samples >= max_available_buffer_size) { - memset(pbuf, 1, bytes); - return bytes; + if (((chn) % 2) != 0) { + read_val >>= CHANNEL_RANGE_MSK_OFFSET; + chn_range = read_val; + } else { + chn_range = (read_val & AD7606_RANGE_CH_MSK(chn)); } - wait_and_read_new_samples(pbuf, samples_to_read); + /* Get polarity based on input channel range */ + polarity = ad7606_get_input_polarity(chn_range); - /* Make buffer available again once read completely */ - if (acq_buffer.rd_indx >= max_available_buffer_size) { - acq_buffer.rd_indx = 0; - acq_buffer.wr_indx = 0; - acq_buffer.align_cnt = 0; - acq_buffer.state = BUF_AVAILABLE; + /* This function monitors BUSY line for EOC and read ADC result post that */ + if (ad7606_read(p_ad7606_dev_inst, adc_raw) != SUCCESS) { + adc_raw[chn] = 0; } - return bytes; + *adc_data = reformat_adc_raw_data(adc_raw[chn], polarity); + + return SUCCESS; } /*! - * @brief Function to perform background ADC conversion and data capture - * @return none - * @details This is an External Interrupt callback function/ISR, which is tied up to - * falling edge trigger of BUSY pin. It is trigered when previous data - * conversion is over and BUSY line goes low. Upon trigger, conversion - * results are read into acquisition buffer and next conversion is triggered. - * This continues until background conversion is stopped. + * @brief Perform the operations required before starting continuous sample read + * @param chn_mask[in] - active channels list received from IIO client + * @return SUCCESS in case of success, FAILURE otherwise */ -void do_conversion_callback(void *ctx, uint32_t event, void *extra) +int32_t ad7606_continuous_sample_read_start_ops(uint32_t chn_mask) { -#if (AD7606X_ADC_RESOLUTION == 18) - uint8_t arr_indx = 0; - uint8_t offset_end = 2; - uint8_t mask = 0xff; -#else - uint8_t mask = 0x01; -#endif - - if (start_adc_data_capture == true) { - /* Read the conversion result for required number of bytes */ - if (ad7606_read_conversion_data(dev, min_bytes_to_read) == SUCCESS) { - /* Extract the data based on the active channels selected in IIO client. - * Note: The extraction of data based on active channel needs - * to be done since its not possible to capture individual - * channel in AD7606 devices */ - for (uint8_t chn = 0; chn < chn_read_cnt; chn++) { - if (active_channels & mask) { - if (acq_buffer.state == BUF_AVAILABLE) { -#if (AD7606X_ADC_RESOLUTION == 18) - /* For AD7606C device (18-bit resolution) */ - acq_buffer.data[acq_buffer.wr_indx++] = - (((uint32_t)(dev->data[arr_indx] & mask) << 16) | // MSB - ((uint32_t)dev->data[arr_indx + 1] << 8) | - ((uint32_t)(dev->data[arr_indx + 2] >> (8 - offset_end)))); // LSB -#else + uint8_t read_val; + uint8_t chn_range; - acq_buffer.data[acq_buffer.wr_indx++] = - (uint16_t)(((uint16_t)dev->data[chn << 1] << 8) | // MSB - dev->data[(chn << 1) + 1]); // LSB -#endif - - acq_buffer.align_cnt++; - - /* Monitor primary buffer full state */ - if (acq_buffer.wr_indx >= max_available_buffer_size) { - acq_buffer.state = BUF_FULL; - - /* This aligns the buffer to first active channel once all requested samples are transmitted */ - if (acq_buffer.align_cnt >= num_of_samples) { - acq_buffer.align_cnt = 0; - } -#if (AD7606X_ADC_RESOLUTION == 18) - adjust_buffer_offset(&arr_indx, &offset_end, &mask); -#endif - mask <<= 1; - continue; - } - - /* This aligns the buffer to first active channel once all requested samples are transmitted */ - if (acq_buffer.align_cnt >= num_of_samples) { - acq_buffer.align_cnt = 0; - break; - } - } - } - -#if (AD7606X_ADC_RESOLUTION == 18) - adjust_buffer_offset(&arr_indx, &offset_end, &mask); -#endif - - mask <<= 1; + for (uint8_t chn = 0; chn < AD7606X_ADC_CHANNELS; chn++) { + /* Store the channels polarity */ + if (ad7606_spi_reg_read(p_ad7606_dev_inst, + AD7606_REG_RANGE_CH_ADDR(chn), + &read_val) == SUCCESS) { + if (((chn) % 2) != 0) { + read_val >>= CHANNEL_RANGE_MSK_OFFSET; + chn_range = read_val; + } else { + chn_range = (read_val & AD7606_RANGE_CH_MSK(chn)); } - /* Trigger next conversion */ - if (ad7606_convst(dev) != SUCCESS) { - start_adc_data_capture = false; - } - } else { - start_adc_data_capture = false; + polarity[chn] = ad7606_get_input_polarity(chn_range); } } + + /* Trigger first conversion */ + return ad7606_trigger_next_conversion(); } /*! - * @brief Function to trigger bakground ADC conversion for new READBUFF - * request from IIO client (for active channels) - * @return Conversion start status + * @brief Read ADC raw data for recently sampled channel + * @param adc_data[out] - Pointer to adc data read variable + * @param input_chn[in] - Input channel + * @return SUCCESS in case of success, FAILURE otherwise + * @note This function is intended to call from the conversion end trigger + * event. Therefore, this function should just read raw ADC data + * without further monitoring conversion end event */ -void start_background_data_capture(uint32_t ch_mask, size_t bytes_count) +int32_t ad7606_read_converted_sample(uint32_t *adc_data, + uint8_t input_chn) { - uint8_t mask = 0x1; - - /* Make sure requested samples size is less than ADC buffer size */ - if (num_of_samples >= max_available_buffer_size) - return; - - active_channels = ch_mask; - - stop_background_data_capture(); + uint32_t adc_raw; + uint8_t bytes_to_read; + uint8_t buffer_offset; - /* Find the minimum number of bytes to be read from device during - * background conversion (Reading all bytes/channels adds extra overhead, - * so restrict the minimum reads to whatever is possible). - * Note: This happens only at the start of buffer read request. */ - for (uint8_t chn = 1, indx = 0; chn <= AD7606X_ADC_CHANNELS; chn++, indx++) { - if (ch_mask & mask) { - /* 1 sample = 2 or 4 bytes */ - min_bytes_to_read = chn * BYTES_PER_SAMPLE; - if (min_bytes_to_read > AD7606X_ADC_RESOLUTION) { - min_bytes_to_read = AD7606X_ADC_RESOLUTION; - } - - /* Get the count for number of samples to be stored into acquisition buffer */ - chn_read_cnt = chn; - num_of_active_channels++; - } - - mask <<= 1; + if (!adc_data) { + return FAILURE; } - /* Make primary acquisition buffer available and start conversion */ - acq_buffer.state = BUF_AVAILABLE; - if (ad7606_convst(dev) == SUCCESS) { - start_adc_data_capture = true; - } else { - start_adc_data_capture = false; - } + /* Get number of bytes to read count = chn_cnt * bytes per sample */ + bytes_to_read = AD7606X_ADC_CHANNELS * SAMPLE_SIZE_IN_BYTE; + buffer_offset = input_chn * SAMPLE_SIZE_IN_BYTE; + + /* Read data over spi interface for all ADC channels */ + memset(p_ad7606_dev_inst->data, 0, sizeof(p_ad7606_dev_inst->data)); + spi_write_and_read(p_ad7606_dev_inst->spi_desc, + p_ad7606_dev_inst->data, bytes_to_read); + +#if (AD7606X_ADC_RESOLUTION == 18) + adc_raw = + (((uint32_t)p_ad7606_dev_inst->data[buffer_offset] << 16) | // MSB + ((uint32_t)p_ad7606_dev_inst->data[buffer_offset + 1] << 8) | + ((uint32_t)p_ad7606_dev_inst->data[buffer_offset + 2])); // LSB +#else + adc_raw = + (uint16_t)(((uint16_t)p_ad7606_dev_inst->data[buffer_offset] << 8) | // MSB + p_ad7606_dev_inst->data[buffer_offset + 1]); // LSB +#endif + + *adc_data = reformat_adc_raw_data(adc_raw, polarity[input_chn]); + + return SUCCESS; } /*! - * @brief Function to stop background ADC data capture - * @return none + * @brief Trigger next ADC conversion + * @return SUCCESS in case of success, FAILURE otherwise */ -void stop_background_data_capture(void) +int32_t ad7606_trigger_next_conversion(void) { - /* Reset data capture flags */ - start_adc_data_capture = false; - num_of_active_channels = 0; - min_bytes_to_read = 0; - chn_read_cnt = 0; - - /* Reset acquisition buffer states and clear old data */ - acq_buffer.state = BUF_EMPTY; - - memset((void *)acq_buffer.data, 0, sizeof(acq_buffer.data)); - - acq_buffer.wr_indx = 0; - acq_buffer.rd_indx = 0; - acq_buffer.align_cnt = 0; -} - + if (ad7606_convst(p_ad7606_dev_inst) != SUCCESS) { + return FAILURE; + } -/*! - * @brief Function to adjust the data buffer offset - * @param *arr_indx[in, out]- Array index - * @param *offset_end[out] - offset to extract LSB from 18-bit data - * @param *mask[out] - channel select mask - * @return none - */ -static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end, - uint8_t *mask) -{ - *arr_indx += 2; - - /* Track array to reach at the middle (9 bytes apart) to change the offsets */ - if (*arr_indx == ((AD7606X_ADC_RESOLUTION / 2) - 1)) { - (*arr_indx)++; - *offset_end = 2; - *mask = 0xff; - } else { - *mask = (0xff >> *offset_end); - *offset_end += 2; - } + return SUCCESS; }
diff -r 32de160dce43 -r 054dbd5e1f45 app/ad7606_data_capture.h --- a/app/ad7606_data_capture.h Wed Jul 21 11:16:56 2021 +0100 +++ b/app/ad7606_data_capture.h Tue Aug 03 11:54:49 2021 +0100 @@ -2,8 +2,7 @@ * @file ad7606_data_capture.h * @brief Header for AD7606 data capture interfaces ******************************************************************************** - * Copyright (c) 2020 Analog Devices, Inc. - * + * Copyright (c) 2020-2021 Analog Devices, Inc. * All rights reserved. * * This software is proprietary to Analog Devices, Inc. and its licensors. @@ -34,13 +33,4 @@ /************************ Public Declarations *********************************/ /******************************************************************************/ -int32_t iio_data_capture_init(struct ad7606_dev **device); -int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity); -size_t buffered_data_read(char *pbuf, size_t bytes, size_t offset, - uint32_t chn_mask); -void store_requested_samples_count(size_t bytes); -void do_conversion_callback(void *ctx, uint32_t event, void *extra); -void start_background_data_capture(uint32_t ch_mask, size_t bytes_count); -void stop_background_data_capture(void); - #endif /* AD7606_DATA_CAPTURE_H_ */
diff -r 32de160dce43 -r 054dbd5e1f45 app/app_config.c --- a/app/app_config.c Wed Jul 21 11:16:56 2021 +0100 +++ b/app/app_config.c Tue Aug 03 11:54:49 2021 +0100 @@ -18,7 +18,7 @@ #include <stdbool.h> #include "app_config.h" -#include "ad7606_data_capture.h" +#include "adc_data_capture.h" #include "error.h" #include "uart.h" #include "gpio.h" @@ -54,7 +54,7 @@ /* External interrupt callback descriptor */ static struct callback_desc ext_int_callback_desc = { - do_conversion_callback, + data_capture_callback, NULL, NULL };
diff -r 32de160dce43 -r 054dbd5e1f45 app/iio_ad7606.c --- a/app/iio_ad7606.c Wed Jul 21 11:16:56 2021 +0100 +++ b/app/iio_ad7606.c Tue Aug 03 11:54:49 2021 +0100 @@ -29,7 +29,7 @@ #include "error.h" #include "ad7606.h" -#include "ad7606_data_capture.h" +#include "adc_data_capture.h" #include "ad7606_support.h" #include "ad7606_user_config.h" @@ -68,6 +68,22 @@ #define OFFSET_REG_RESOLUTION 1 #endif +/* Bytes per sample. This count should divide the total 256 bytes into 'n' equivalent + * ADC samples as IIO library requests only 256bytes of data at a time in a given + * data read query. + * For 1 to 8-bit ADC, bytes per sample = 1 (2^0) + * For 9 to 16-bit ADC, bytes per sample = 2 (2^1) + * For 17 to 32-bit ADC, bytes per sample = 4 (2^2) + **/ +#if (AD7606X_ADC_RESOLUTION == 18) +#define BYTES_PER_SAMPLE sizeof(uint32_t) // For ADC resolution of 18-bits +#else +#define BYTES_PER_SAMPLE sizeof(uint16_t) // For ADC resolution of 16-bits +#endif + +/* Number of data storage bits (needed for IIO client to plot ADC data) */ +#define CHN_STORAGE_BITS (BYTES_PER_SAMPLE * 8) + /******************************************************************************/ /*************************** Types Declarations *******************************/ /******************************************************************************/ @@ -83,7 +99,7 @@ /** * Pointer to the struct representing the AD7606 IIO device */ -static struct ad7606_dev *p_ad7606_dev_inst = NULL; +struct ad7606_dev *p_ad7606_dev_inst = NULL; /* Device attributes with default values */ @@ -282,8 +298,9 @@ int32_t adc_data_raw; /* Capture the raw adc data */ - adc_data_raw = single_data_read(device, channel->ch_num, - attr_polarity_val[channel->ch_num]); + if (read_single_sample(channel->ch_num, (uint32_t *)&adc_data_raw) != SUCCESS) { + return -EINVAL; + } return (ssize_t) sprintf(buf, "%d", adc_data_raw); } @@ -834,7 +851,7 @@ const struct iio_ch_info *channel, intptr_t id) { - int32_t adc_chn_data = 0; + int32_t adc_data_raw = 0; float temperature; float voltage; @@ -849,11 +866,10 @@ udelay(100); /* Sample the channel and read conversion result */ - adc_chn_data = single_data_read(device, channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&adc_data_raw); /* Convert ADC data into equivalent voltage */ - voltage = convert_adc_raw_to_voltage(adc_chn_data, + voltage = convert_adc_raw_to_voltage(adc_data_raw, attr_scale_val[channel->ch_num]); /* Obtain the temperature using equation specified in device datasheet */ @@ -899,7 +915,7 @@ intptr_t id) { float vref_voltge; - int32_t adc_chn_data; + int32_t adc_data_raw; /* Configure the channel multiplexer to select Vref read */ if (ad7606_spi_write_mask(device, @@ -912,11 +928,10 @@ udelay(100); /* Sample the channel and read conversion result */ - adc_chn_data = single_data_read(device, channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&adc_data_raw); /* Convert ADC data into equivalent voltage */ - vref_voltge = convert_adc_raw_to_voltage(adc_chn_data, + vref_voltge = convert_adc_raw_to_voltage(adc_data_raw, attr_scale_val[channel->ch_num]); /* Divide by 4 since Vref Mux has 4x multiplier on it */ @@ -962,7 +977,7 @@ intptr_t id) { float vdrive_voltge; - int32_t adc_chn_data; + int32_t adc_data_raw; /* Configure the channel multiplexer to select Vdrive read */ if (ad7606_spi_write_mask(device, @@ -975,11 +990,10 @@ udelay(100); /* Sample the channel and read conversion result */ - adc_chn_data = single_data_read(device, channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&adc_data_raw); /* Convert ADC data into equivalent voltage */ - vdrive_voltge = convert_adc_raw_to_voltage(adc_chn_data, + vdrive_voltge = convert_adc_raw_to_voltage(adc_data_raw, attr_scale_val[channel->ch_num]); /* Change channel mux back to analog input */ @@ -1022,7 +1036,7 @@ intptr_t id) { float aldo_voltge; - int32_t adc_chn_data; + int32_t adc_data_raw; /* Configure the channel multiplexer to select ALDO read */ if (ad7606_spi_write_mask(device, @@ -1035,11 +1049,10 @@ udelay(100); /* Sample the channel and read conversion result */ - adc_chn_data = single_data_read(device, channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&adc_data_raw); /* Convert ADC data into equivalent voltage */ - aldo_voltge = convert_adc_raw_to_voltage(adc_chn_data, + aldo_voltge = convert_adc_raw_to_voltage(adc_data_raw, attr_scale_val[channel->ch_num]); /* Divide by 4 since ALDO Mux has 4x multiplier on it */ @@ -1085,7 +1098,7 @@ intptr_t id) { float dldo_voltge; - int32_t adc_chn_data; + int32_t adc_data_raw; /* Configure the channel multiplexer to select DLDO read */ if (ad7606_spi_write_mask(device, @@ -1098,12 +1111,10 @@ udelay(100); /* Sample the channel and read conversion result */ - adc_chn_data = single_data_read(device, - channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&adc_data_raw); /* Convert ADC data into equivalent voltage */ - dldo_voltge = convert_adc_raw_to_voltage(adc_chn_data, + dldo_voltge = convert_adc_raw_to_voltage(adc_data_raw, attr_scale_val[channel->ch_num]); /* Divide by 4 since ALDO Mux has 4x multiplier on it */ @@ -1156,18 +1167,14 @@ do { if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 1) == SUCCESS) { /* Read the ADC on selected chnnel (first reading post open circuit detection start) */ - prev_adc_code = single_data_read(device, - channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&prev_adc_code); /* Perform N conversions and monitor the code delta */ for (cnt = 0; cnt < MANUAL_OPEN_DETECT_CONV_CNTS; cnt++) { /* Check if code is within 350LSB (nearest ZS code) */ if (prev_adc_code >= 0 && prev_adc_code < MANUAL_OPEN_DETECT_ENTRY_TRHLD) { /* Perform next conversion and read the result */ - curr_adc_code = single_data_read(device, - channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&curr_adc_code); /* Check if delta b/w current and previus reading is within 10 LSB code */ if (abs(curr_adc_code - prev_adc_code) > MANUAL_OPEN_DETECT_CONV_TRSHLD) { @@ -1195,9 +1202,7 @@ /* Perform next conversions (~2-3) and read the result (with common mode set high) */ for (cnt = 0; cnt < MANUAL_OPEN_DETECT_CM_CNV_CNT; cnt++) { udelay(100); - curr_adc_code = single_data_read(device, - channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&curr_adc_code); } /* Check if delta b/w common mode high code and previous N conversion code is > threshold */ @@ -1218,9 +1223,7 @@ AD7606_REG_OPEN_DETECT_ENABLE, 0) == SUCCESS) { /* Perform next conversion and read the result (with common mode set low) */ - curr_adc_code = single_data_read(device, - channel->ch_num, - attr_polarity_val[channel->ch_num]); + read_single_sample(channel->ch_num, (uint32_t *)&curr_adc_code); /* Check if delta b/w common mode low code and previous N conversion code is < threshold */ if (abs(curr_adc_code - prev_adc_code) < MANUAL_OPEN_DETECT_THRESHOLD_RPD50K) { @@ -1395,7 +1398,7 @@ float lsb_voltage; float adc_voltage; polarity_e polarity = attr_polarity_val[channel->ch_num]; - int32_t adc_data; + int32_t adc_raw_data; int8_t chn_offset; /* Perform the system offset calibration */ @@ -1407,11 +1410,10 @@ } /* Sample and read the ADC channel */ - adc_data = single_data_read(device, channel->ch_num, - polarity); + read_single_sample(channel->ch_num, (uint32_t *)&adc_raw_data); /* Get an equivalent ADC voltage */ - adc_voltage = convert_adc_raw_to_voltage(adc_data, + adc_voltage = convert_adc_raw_to_voltage(adc_raw_data, attr_scale_val[channel->ch_num]); /* Calculate the channel offset and write it to offset register */ @@ -1553,12 +1555,16 @@ uint32_t ch_mask) { if (adc_data_capture_started == false) { - start_background_data_capture(ch_mask, bytes_count); + start_data_capture(ch_mask, AD7606X_ADC_CHANNELS); adc_data_capture_started = true; } /* Read the buffered data */ - return (ssize_t)buffered_data_read(pbuf, bytes_count, offset, ch_mask); + return (ssize_t)read_buffered_data(pbuf, + bytes_count, + offset, + ch_mask, + BYTES_PER_SAMPLE); } @@ -1579,7 +1585,7 @@ * iio_ad7606_read_data() function */ /* Store the requested samples count value for data capture */ - store_requested_samples_count(bytes_count); + store_requested_samples_count(bytes_count, BYTES_PER_SAMPLE); return SUCCESS; } @@ -1605,7 +1611,7 @@ static int32_t iio_ad7606_stop_transfer(void *dev) { adc_data_capture_started = false; - stop_background_data_capture(); + stop_data_capture(); return SUCCESS; } @@ -1688,7 +1694,6 @@ .store = set_chn_calibrate_adc_gain, }, #if defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16) - &iio_attr_bandwidth { .name = "bandwidth", .show = get_bandwidth, @@ -1750,13 +1755,8 @@ /* IIOD channels configurations */ struct scan_type chn_scan = { .sign = 's', -#if (AD7606X_ADC_RESOLUTION == 18) - .realbits = 18, - .storagebits = 18, -#else - .realbits = 16, - .storagebits = 16, -#endif + .realbits = CHN_STORAGE_BITS, + .storagebits = CHN_STORAGE_BITS, .shift = 0, .is_big_endian = false }; @@ -2008,12 +2008,6 @@ return init_status; } - /* Init the data capture for AD7606 IIO app */ - init_status = iio_data_capture_init(&p_ad7606_dev_inst); - if (init_status != SUCCESS) { - return init_status; - } - return init_status; }
diff -r 32de160dce43 -r 054dbd5e1f45 app/iio_ad7606.h --- a/app/iio_ad7606.h Wed Jul 21 11:16:56 2021 +0100 +++ b/app/iio_ad7606.h Tue Aug 03 11:54:49 2021 +0100 @@ -30,7 +30,7 @@ /******************************************************************************/ /******************************************************************************/ -/************************ Functions Declarations ******************************/ +/*************************** Public Declarations ******************************/ /******************************************************************************/ /* Init the IIO interface */ @@ -39,4 +39,6 @@ /* Run the IIO event handler */ void ad7606_iio_event_handler(void); +extern struct ad7606_dev *p_ad7606_dev_inst; + #endif /* IIO_AD7606_H_ */
diff -r 32de160dce43 -r 054dbd5e1f45 app/mbed_platform_drivers.lib --- a/app/mbed_platform_drivers.lib Wed Jul 21 11:16:56 2021 +0100 +++ b/app/mbed_platform_drivers.lib Tue Aug 03 11:54:49 2021 +0100 @@ -1,1 +1,1 @@ -https://os.mbed.com/teams/AnalogDevices/code/platform_drivers/#af1f2416dd26 \ No newline at end of file +https://os.mbed.com/teams/AnalogDevices/code/platform_drivers/#5ae03a197e59 \ No newline at end of file