this is testing

Revision:
0:3afcd581558d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/app/src/ad7606_data_capture.c	Thu Jan 14 18:54:16 2021 +0530
@@ -0,0 +1,311 @@
+/***************************************************************************//**
+ *   @file    ad7606_data_capture.c
+ *   @brief   Data capture interface for AD7606 IIO application
+ *   @details This module handles the AD7606 data capturing
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * All rights reserved.
+ *
+ * This software is proprietary to Analog Devices, Inc. and its licensors.
+ * By using this software you agree to the terms of the associated
+ * Analog Devices Software License Agreement.
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "app_config.h"
+#include "ad7606_data_capture.h"
+#include "ad7606_support.h"
+#include "gpio_extra.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/********************** 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_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;
+#if (ADC_RESOLUTION > 16)
+	uint32_t data[NO_OF_SAMPLES];
+#else
+	uint16_t data[NO_OF_SAMPLES];
+#endif
+} acq_buf_t;
+
+/* ADC data acquisition buffers */
+static volatile acq_buf_t acq_buffer[2];
+
+/* Flag to indicate background data conversion status */
+static volatile bool start_background_conversion = false;
+
+/* Active channels to be captured */
+static volatile uint32_t active_channels = 0;
+
+/* Minimum number of bytes to be read from device */
+static volatile uint8_t min_bytes_to_read = 0;
+
+/* Minimum number of samples to be stored into acquisition buffer */
+static volatile uint8_t min_samples_to_store = 0;
+
+/******************************************************************************/
+/************************ 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)
+{
+	/* Save the device structure for background conversion */
+	dev = malloc(sizeof(struct ad7606_dev *));
+	if (!dev) {
+		return FAILURE;
+	}
+
+	memcpy(&dev, &device, sizeof(dev));
+
+	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
+ */
+int32_t single_data_read(void *device, uint8_t chn, polarity_e polarity)
+{
+	int32_t adc_data = 0;
+	uint32_t adc_raw[ADC_RESOLUTION] = { 0 };
+
+	if (ad7606_read(device, adc_raw) != SUCCESS) {
+		adc_raw[chn] = 0;
+	}
+
+	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;
+		} else {
+			adc_data = adc_raw[chn];
+		}
+	} else {
+		adc_data = adc_raw[chn];
+	}
+
+	return adc_data;
+}
+
+
+/*!
+ * @brief	Function to read 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	chn_mask[in] - Active channels mask
+ * @return	none
+ * @details	This function reads the data from any available acquisition
+ *			buffer (the buffer which is full). The intention here is to
+ *			have most recent data fetched from the device.
+ */
+void buffered_data_read(char *pbuf, size_t bytes, size_t offset,
+			uint32_t chn_mask)
+{
+	uint8_t mask = 0x1;
+
+	if (acq_buffer[0].state == BUF_FULL) {
+		/* Copy the acquisition buffer 0 into output data buffer */
+		memcpy(pbuf, acq_buffer[0].data, bytes);
+	} else if(acq_buffer[1].state == BUF_FULL) {
+		/* Copy the acquisition buffer 1 into output data buffer */
+		memcpy(pbuf, acq_buffer[1].data, bytes);
+	} else {
+		/* This case should never reach. At any instance, at least one
+		 * of the buffer should be full */
+	}
+
+	/* Find the minimum number of bytes to be read from device during
+	 * background conversion (Reading all channels adds extra overhead,
+	 * so restrict the minimum reads to whatever is possible) */
+	if (offset == 0) {
+		active_channels = chn_mask;
+		for (uint8_t chn = 1; chn <= NO_OF_CHANNELS; chn++) {
+			if (active_channels & mask) {
+#if (ADC_RESOLUTION == 18)
+				/* 1 sample = 3 bytes (max 18 bytes) */
+				min_bytes_to_read = chn * 3;
+				if (min_bytes_to_read > ADC_RESOLUTION) {
+					min_bytes_to_read = ADC_RESOLUTION;
+				}
+#else
+				/* 1 sample = 2 bytes */
+				min_bytes_to_read = chn * 2;
+#endif
+				min_samples_to_store = chn;
+			}
+
+			mask <<= 1;
+		}
+	}
+}
+
+
+/*!
+ * @brief	Function to perform background ADC conversion
+ * @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.
+ */
+void do_conversion_callback(void)
+{
+	static uint16_t sample_cnt = 0;
+#if (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_background_conversion == true) {
+
+		/* Read the conversion result for required number of bytes */
+		(void)ad7606_read_conversion_data(dev, min_bytes_to_read);
+
+		/* Extract the channels data based on the active channels
+		 * 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 cnt = 0; cnt < min_samples_to_store; cnt++) {
+			if (active_channels & mask) {
+				/* Fill the buffer based on the availability */
+				if (acq_buffer[0].state == BUF_AVAILABLE) {
+#if (ADC_RESOLUTION == 18)
+					acq_buffer[0].data[sample_cnt] =
+						(((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
+					acq_buffer[0].data[sample_cnt] =
+						(uint16_t)(((uint16_t)dev->data[cnt << 1] << 8) |	// MSB
+							   dev->data[(cnt << 1) + 1]);					// LSB
+#endif
+				} else if (acq_buffer[1].state == BUF_AVAILABLE) {
+#if (ADC_RESOLUTION == 18)
+					acq_buffer[1].data[sample_cnt] =
+						(((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
+					acq_buffer[1].data[sample_cnt] =
+						(uint16_t)(((uint16_t)dev->data[cnt << 1] << 8) |	// MSB
+							   dev->data[(cnt << 1) + 1]);					// LSB
+#endif
+				} else {
+					/* This case should never reach */
+				}
+
+				sample_cnt++;
+			}
+
+#if (ADC_RESOLUTION == 18)
+			arr_indx += 2;
+
+			/* Track array to reach at the middle (9 bytes apart) to change the offsets */
+			if (arr_indx == ((ADC_RESOLUTION / 2) -1)) {
+				arr_indx++;
+				offset_end = 2;
+				mask = 0xff;
+			} else {
+				mask = (0xff >> offset_end);
+				offset_end += 2;
+			}
+#endif
+
+			if (sample_cnt >= NO_OF_SAMPLES) {
+				break;
+			}
+
+			mask <<= 1;
+		}
+
+		/* Monitor buffer full status based on active buffer state */
+		if (sample_cnt >= NO_OF_SAMPLES) {
+			if (acq_buffer[0].state == BUF_AVAILABLE) {
+				/* Buffer 0 is set FULL */
+				acq_buffer[0].state =  BUF_FULL;
+
+				/* Buffer 1 is set available to store next data samples */
+				acq_buffer[1].state =  BUF_AVAILABLE;
+			} else if (acq_buffer[1].state == BUF_AVAILABLE) {
+				/* Buffer 1 is set FULL */
+				acq_buffer[1].state =  BUF_FULL;
+
+				/* Buffer 0 is set available to store next data samples */
+				acq_buffer[0].state =  BUF_AVAILABLE;
+			} else {
+				/* This case should never reach */
+			}
+
+			sample_cnt = 0;
+		}
+
+		/* Trigger next conversion */
+		(void)ad7606_convst(dev);
+	}
+}
+
+
+/*!
+ * @brief	Function to start bakground ADC conversion
+ * @return	none
+ */
+void start_background_data_conversion(void)
+{
+	/* Start conversion */
+	(void)ad7606_convst(dev);
+	start_background_conversion = true;
+}
+
+
+/*!
+ * @brief	Function to stop bakground ADC conversion
+ * @return	none
+ */
+void stop_background_data_conversion(void)
+{
+	start_background_conversion = false;
+}