Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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
--- 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
--- 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;
}
--- 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_ */
--- 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
};
--- 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;
}
--- 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_ */
--- 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