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 1:819ac9aa5667, committed 2020-10-05
- Comitter:
- mahphalke
- Date:
- Mon Oct 05 13:45:15 2020 +0530
- Parent:
- 0:3791805e8370
- Child:
- 2:26002766580b
- Commit message:
- AD7606 IIO Application- Initial Revision
Changed in this revision
--- a/AD7606.lib Thu Aug 06 19:49:32 2020 +0000 +++ b/AD7606.lib Mon Oct 05 13:45:15 2020 +0530 @@ -1,1 +1,1 @@ -https://os.mbed.com/teams/AnalogDevices/code/AD7606/#84d38108c7b4 +https://os.mbed.com/teams/AnalogDevices/code/AD7606
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/License.txt Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,26 @@ +Analog Devices, Inc. (ADI) +Source Code Software License Agreement +20190709-LWSC-CTSLA +BEFORE YOU SELECT THE "I ACCEPT" BUTTON AT THE BOTTOM OF THIS WINDOW, CAREFULLY READ THE TERMS AND CONDITIONS SET FORTH BELOW. BY SELECTING THE I ACCEPT BUTTON BELOW, OR DOWNLOADING, REPRODUCING, DISTRIBUTING OR OTHERWISE USING THE SOFTWARE, YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS SET FORTH BELOW. IF YOU DO NOT AGREE TO ALL OF THE TERMS AND CONDITIONS, SELECT THE 'I DO NOT ACCEPT' BUTTON AND YOU MUST NOT DOWNLOAD, INSTALL OR OTHERWISE USE THE SOFTWARE. + +DOWNLOADING, REPRODUCING, DISTRIBUTING OR OTHERWISE USING THE SOFTWARE CONSTITUTES ACCEPTANCE OF THIS LICENSE. THE SOFTWARE MAY NOT BE USED EXCEPT AS EXPRESSLY AUTHORIZED UNDER THIS LICENSE. + +The software is protected by copyright law and international copyright treaties. + +1. License: Subject to the terms and conditions of this license, the software may be reproduced, modified and distributed in source code and object code form. + +2. Conditions: +(a) Any distribution of the software must include a complete copy of this license and retain all copyright and other proprietary notices. The software that is distributed (including modified versions of the software) shall be subject to the terms and conditions of this license. +(b) The software may not be combined or merged with other software in any manner that would cause the software to become subject to terms and conditions which differ from those of this license. +(c) The software is licensed solely and exclusively for use with processors manufactured by or for ADI. +(d) Licensee shall not use the name or any trademark of ADI (including those of its licensors) or any contributor to endorse or promote products without prior written consent of the owner of the name or trademark. The term contributor means any person or entity that modifies or distributes the software. +(e) Modified versions of the Software must be conspicuously marked as such. +(f) Use of the software may or may not infringe patent rights of one or more patent holders. This license does not alleviate the obligation to obtain separate licenses from patent holders to use the software. +(g) All rights not expressly granted hereunder are reserved. +(h) This license shall be governed by the laws of Massachusetts, without regard to its conflict of laws rules. The software shall only be used in compliance with all applicable laws and regulations, including without limitation export control laws. + +3. WARRANTY DISCLAIMER: THE SOFTWARE AND ANY RELATED INFORMATION AND/OR ADVICE IS PROVIDED ON AN AS IS BASIS, WITHOUT REPRESENTATIONS, GUARANTEES OR WARRANTIES OF ANY KIND, EXPRESS OR IMPLIED, ORAL OR WRITTEN, INCLUDING WITHOUT LIMITATION, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. There is no obligation to provide software support or updates. The Software is not fault-tolerant and is not intended for use in high risk applications, including without limitation in the operation of nuclear facilities, aircraft navigation or control systems, air traffic control, life support machines, weapons systems, autonomous driving or other safety critical automotive applications, or any other application in which the failure of the software could lead to death, personal injury, or severe physical or environmental damages. The software is not authorized to be used under such circumstances. + +4. LIMITATION OF LIABILITY: TO THE MAXIMUM EXTENT PERMITTED BY LAW ADI (INCLUDING ITS LICENSORS) AND CONTRIBUTORS SHALL NOT BE LIABLE FOR ANY DAMAGES ARISING FROM OR RELATED TO THE SOFTWARE, ITS USE OR ANY RELATED INFORMATION AND/OR SERVICES, INCLUDING BUT NOT LIMITED TO ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, PUNITIVE, EXEMPLARY, CONSEQUENTIAL OR ANALOGOUS DAMAGES (INCLUDING WITHOUT LIMITATION ANY DAMAGES RESULTING FROM LOSS OF USE, DATA, REVENUE, PROFITS, OR SAVINGS, COMPUTER DAMAGE OR ANY OTHER CAUSE), UNDER ANY LEGAL THEORY (INCLUDING WITHOUT LIMITATION CONTRACT, WARRANTY, TORT, NEGLIGENCE, STRICT OR PRODUCT LIABILITY), EVEN IF IT HAS BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. Some jurisdictions do not permit the exclusion or limitation of liability for consequential, incidental or other damages, and, as such, some portion of the above limitation may not apply. In such jurisdictions, liability is limited to the greatest extent permitted by law. +5. Third Party Software: The software may be accompanied by or include software made available by one or more third parties (Third Party Software). Each portion of Third Party Software is subject to its own separate software license terms and conditions (Third Party Licenses). The Third Party Licenses for Third Party Software delivered with the software are set forth or identified (by url or otherwise) in (i) Appendix A to this license (if any), (ii) the applicable software header or footer text, (iii) a text file located in the directory of the applicable Third Party Software component and/or (iv) such other location customarily used for licensing terms. The use of each portion of Third Party Software is subject to the Third Party Licenses, and you agree that your use of any Third Party Software is bound by the applicable Third Party License. You agree to review and comply with all applicable Third Party Licenses prior to any use or distribution of any Third Party Software. Third Party Software is provided on an as is basis without any representation, warranty or liability of any kind. ADI (including its licensors) and contributors shall have no liability or responsibility for the operation or performance of the Third Party Software and shall not be liable for any damages, costs, or expenses, direct or indirect, arising out of the performance or failure to perform of the Third Party Software. ADI (including its licensors) and contributors shall be entitled to the benefit of any and all limitations of liability and disclaimers of warranties contained in the Third Party Licenses. For the avoidance of doubt, this license does not alter, limit or expand the terms and conditions of, or rights granted to you pursuant to, Third Party Licenses. +
--- a/README.txt Thu Aug 06 19:49:32 2020 +0000 +++ b/README.txt Mon Oct 05 13:45:15 2020 +0530 @@ -1,40 +1,32 @@ Evaluation Boards/Products Supported ------------------------------------ -EVAL-AD1234 (AD1234) -EVAL-AD1256 (AD1256) -<< add more here >> +-Products supported: AD7606B, AD7606C, AD7605-4, AD7606-4, AD7606-6, AD7606-8, AD7608, AD7609 +-EVAL-AD7606B-FMCZ + Overview -------- -These code files provide drivers to interface with AD1234 and communicate with -EVAL-AD1234 board. This code was developed and tested on SDP-K1 controller board -https://os.mbed.com/platforms/SDP_K1/. - -Product details: https://www.analog.com/en/products/ad1234.html -Eval board details: https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/EVAL-AD1234.html +This is an IIO ecosystem based firmware application to evalute the AD7606 family ADCs. +The ARM GCC compiler is used for firmware development on ARM Mbed platform. +The ADI developed ARM Mbed SDP-K1 controlled board acts as a target device, where firmware application is running. +The AD7606-Eval board is interfaced with SDP-K1 (or any Arduino compatible board) controller board using on-board Arduino Headers. Hardware Setup -------------- -Required: SDP-K1, EVAL-AD1234, USB cable, 12 V power supply, 60 MHz external -clock supply. -Plug in the EVAL-AD124 board on SDP-K1 board (or any other Mbed enabled -controller board) using the SDP connector and screws. -Connect SDP-K1 board to the PC using the USB cable. +Refer "Hardware Connections" section from below wiki page link: +https://wiki.analog.com/resources/tools-software/product-support-software/ad7606_mbed_iio_application How to Get Started ------------------ Open Mbed online compiler. https://ide.mbed.com/compiler -Import Code into compiler from here: https://os.mbed.com/teams/AnalogDevices/code/EVAL-AD1234/ -instructions on how to import code are here: https://os.mbed.com/docs/mbed-os/v5.12/tools/importing-code.html -Compile code. Drag and drop binary into SDP-K1 controller board. Find detailed instructions -here: https://os.mbed.com/docs/mbed-os/v5.12/tools/getting-your-program-on-your-board.html -Open Tera Term (or alternative), select 9600 baud rate, and the applicable COM port to see the -list of options. +Import Code into compiler from here. Instructions on how to import code are here: https://os.mbed.com/docs/mbed-os/v5.12/tools/importing-code.html +Compile code. Drag and drop binary into SDP-K1 controller board. Find detailed +instructions here: https://os.mbed.com/docs/mbed-os/v5.12/tools/getting-your-program-on-your-board.html -A detailed user guide on how to use SDP-K1 board on Mbed platform is available -here: https://wiki.analog.com/resources/tools-software/mbed +Refere project wiki page to find detailed guide on how to use firmware: +https://wiki.analog.com/resources/tools-software/product-support-software/ad7606_mbed_iio_application Notes @@ -43,40 +35,4 @@ A detailed user guide on SDP-K1 controller board is available here https://www.analog.com/en/design-center/evaluation-hardware-and-software/evaluation-boards-kits/SDP-K1.html. -License -------- -Copyright (c) 2019 Analog Devices, Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - - Modified versions of the software must be conspicuously marked as such. - - This software is licensed solely and exclusively for use with processors/products - manufactured by or for Analog Devices, Inc. - - This software may not be combined or merged with other code in any manner - that would cause the software to become subject to terms and conditions which - differ from those listed here. - - Neither the name of Analog Devices, Inc. nor the names of its contributors - may be used to endorse or promote products derived from this software without - specific prior written permission. - - The use of this software may or may not infringe the patent rights of one or - more patent holders. This license does not release you from the requirement - that you obtain separate licenses from these patent holders to use this software. - -THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT, -TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, -INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL -PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS -OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -2019-01-10-7CBSD SLA \ No newline at end of file +Copyright (c) 2020 Analog Devices, Inc. All rights reserved. \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_data_capture.c Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,429 @@
+/***************************************************************************//**
+ * @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 ***********************/
+/******************************************************************************/
+
+#if (AD7606X_ADC_RESOLUTION > 16)
+#define BYTES_PER_SAMPLE sizeof(uint32_t)
+#else
+#define BYTES_PER_SAMPLE sizeof(uint16_t)
+#endif
+
+/* Max size of the acquisition buffer (in terms of samples) */
+#define DATA_BUFFER_SIZE (8192)
+
+/******************************************************************************/
+/********************** 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 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 uint16_t num_of_samples = 0;
+
+/* Max available size of buffer */
+static uint16_t max_available_buffer_size = 0;
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+static void adjust_buffer_offset(uint8_t *arr_indx, uint8_t *offset_end,
+ uint8_t *mask);
+
+/******************************************************************************/
+/************************ 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[AD7606X_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 store the number of requested samples from IIO client
+ * @param bytes[in] - Number of bytes corresponding to requested samples
+ * @return none
+ */
+void store_requested_samples_count(size_t bytes)
+{
+ /* 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);
+}
+
+
+/*!
+ * @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(volatile acq_buf_t *input_buffer,
+ 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 = 5000000; // To avoid IIO data request timeout
+ 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 = (int32_t)input_buffer->wr_indx -
+ (int32_t)input_buffer->rd_indx;
+ timeout--;
+ } while (((buff_rd_wr_indx_offset < (int32_t)(samples_to_read))
+ || (input_buffer->wr_indx < input_buffer->rd_indx)) && (timeout > 0));
+
+ if ((timeout == 0) || (input_buffer->wr_indx <= 0)) {
+ /* This returns the empty buffer */
+ return;
+ }
+
+ memcpy(output_buffer,
+ (void const *)&input_buffer->data[input_buffer->rd_indx],
+ bytes);
+ input_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;
+ }
+
+ wait_and_read_new_samples(&acq_buffer, pbuf, samples_to_read);
+
+ /* 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;
+ }
+
+ return bytes;
+}
+
+
+/*!
+ * @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.
+ */
+void do_conversion_callback(void)
+{
+#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
+
+ 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;
+ }
+
+ /* Trigger next conversion */
+ if (ad7606_convst(dev) != SUCCESS) {
+ start_adc_data_capture = false;
+ }
+ } else {
+ start_adc_data_capture = false;
+ }
+ }
+}
+
+
+/*!
+ * @brief Function to trigger bakground ADC conversion for new READBUFF
+ * request from IIO client (for active channels)
+ * @return Conversion start status
+ */
+void start_background_data_capture(uint32_t ch_mask, size_t bytes_count)
+{
+ 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();
+
+ /* 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;
+ }
+
+ /* 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;
+ }
+}
+
+
+/*!
+ * @brief Function to stop background ADC data capture
+ * @return none
+ */
+void stop_background_data_capture(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;
+}
+
+
+/*!
+ * @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;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad7606_data_capture.h Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,46 @@ +/***************************************************************************//** + * @file ad7606_data_capture.h + * @brief Header for AD7606 data capture interfaces +******************************************************************************** + * 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. +*******************************************************************************/ + +#ifndef AD7606_DATA_CAPTURE_H_ +#define AD7606_DATA_CAPTURE_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ +#include <stddef.h> + +#include "ad7606.h" +#include "ad7606_support.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/******************************************************************************/ +/********************** Variables and User Defined Data Types *****************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ 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); +void start_background_data_capture(uint32_t ch_mask, size_t bytes_count); +void stop_background_data_capture(void); + +#endif /* AD7606_DATA_CAPTURE_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_support.c Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,86 @@
+/*************************************************************************//**
+ * @file ad7606_support.c
+ * @brief AD7606 device No-OS driver supports
+******************************************************************************
+* 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 <stdint.h>
+
+#include "app_config.h"
+#include "ad7606_support.h"
+#include "ad7606_data_capture.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/*!
+ * @brief Function to convert adc raw data into equivalent voltage
+ * @param adc_raw[in] - ADC raw data
+ * @param scale[in] - ADC raw to voltage conversion scale
+ * @return equivalent voltage
+ */
+float convert_adc_raw_to_voltage(int32_t adc_raw, float scale)
+{
+ float voltage;
+
+ /* Convert adc data into equivalent voltage.
+ * scale = (chn_range / MAX_ADC_CNT * 1000) as defined in iio_ad7606.c
+ * */
+ voltage = (adc_raw * (scale / 1000));
+
+ return voltage;
+}
+
+
+/*!
+ * @brief Function to get the polarity of analog input
+ * @param chn_range_bits[in] - Bits from the channel range register
+ * @return UNIPOLAR or BIPOLAR
+ */
+polarity_e ad7606_get_input_polarity(uint8_t chn_range_bits)
+{
+ polarity_e polarity;
+
+ if (chn_range_bits >= AD7606C_UNIPOLAR_RANGE_MIN
+ && chn_range_bits <= AD7606C_UNIPOLAR_RANGE_MAX) {
+ polarity = UNIPOLAR;
+ } else {
+ polarity = BIPOLAR;
+ }
+
+ return polarity;
+}
+
+
+/*!
+ * @brief Read the num_of_bytes from previous conversion
+ * @param dev[in]- Device instance
+ * @param num_of_bytes[in] - Number of bytes to read from previous conversion
+ * @return SUCCESS in case of success, FAILURE otherwise
+ */
+int32_t ad7606_read_conversion_data(struct ad7606_dev *dev,
+ uint8_t num_of_bytes)
+{
+ memset(dev->data, 0, sizeof(dev->data));
+ return spi_write_and_read(dev->spi_desc, dev->data, num_of_bytes);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_support.h Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,78 @@
+/***************************************************************************//**
+ * @file ad7606_support.h
+ * @brief Header for AD7606 No-OS driver supports
+********************************************************************************
+ * 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.
+*******************************************************************************/
+
+#ifndef AD7606_SUPPORT_H_
+#define AD7606_SUPPORT_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include "ad7606.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/* Offset b/w two channel selections in CHx_RANGE register */
+#define CHANNEL_RANGE_MSK_OFFSET 4
+
+/* AD7606_REG_OVERSAMPLING */
+#define AD7606_OVERSAMPLING_MSK GENMASK(3,0)
+
+/* Default channel range for AD7606 devices */
+#define DEFAULT_CHN_RANGE (10.0)
+
+/* Diagnostic channels Mux configurations */
+#define AD7606_DIAGN_MUX_CH_MSK(ch) (GENMASK(2, 0) << (3 * ((ch) % 2)))
+#define AD7606_DIAGN_MUX_CH_VAL(ch, val) (val << (3 * ((ch) % 2)))
+
+#define AD7606_OPEN_DETECT_ENABLE_MSK(ch) (GENMASK(7,0) & (~(1 << ch)))
+
+/* Diagnostic channels Mux select bits */
+#define ANALOG_INPUT_MUX 0X00
+#define TEMPERATURE_MUX 0x01
+#define VREF_MUX 0X02
+#define ALDO_MUX 0X03
+#define DLDO_MUX 0X04
+#define VDRIVE_MUX 0x05
+
+/* Diagnostic Mux multiplers */
+#define VREF_MUX_MULTIPLIER 4.0
+
+/* Unipolar inputs range bits for AD7606C */
+#define AD7606C_UNIPOLAR_RANGE_MIN 5
+#define AD7606C_UNIPOLAR_RANGE_MAX 7
+
+/* Number of AD7606 registers */
+#define NUM_OF_REGISTERS 0x2F
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+/* Analog input polarity */
+typedef enum {
+ UNIPOLAR,
+ BIPOLAR
+} polarity_e;
+
+/******************************************************************************/
+/************************ Public Declarations *********************************/
+/******************************************************************************/
+
+float convert_adc_raw_to_voltage(int32_t adc_raw, float scale);
+int32_t ad7606_read_conversion_data(struct ad7606_dev *dev, uint8_t bytes);
+polarity_e ad7606_get_input_polarity(uint8_t chn_range_bits);
+
+#endif /* AD7606_SUPPORT_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/ad7606_user_config.c Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,161 @@
+/*************************************************************************//**
+ * @file ad7606_user_config.c
+ * @brief User configuration file for AD7606 device
+******************************************************************************
+* 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 <stdint.h>
+
+#include "app_config.h"
+#include "ad7606_user_config.h"
+#include "ad7606_support.h"
+#include "spi_extra.h"
+#include "gpio_extra.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+#define USER_CONFIG_RANGE (DEFAULT_CHN_RANGE * 1000)
+
+/******************************************************************************/
+/********************** Variables and User Defined Data Types *****************/
+/******************************************************************************/
+
+struct gpio_init_param gpio_init_reset = {
+ .number = RESET_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_convst = {
+ .number = CONVST_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_busy = {
+ .number = BUSY_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_osr0 = {
+ .number = OSR0_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_osr1 = {
+ .number = OSR1_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_osr2 = {
+ .number = OSR2_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_range= {
+ .number = RANGE_PIN,
+ .extra = NULL
+};
+
+struct gpio_init_param gpio_init_stdby = {
+ .number = STDBY_PIN,
+ .extra = NULL
+};
+
+
+/* Define SPI extra init parameters structure */
+mbed_spi_init_param spi_init_extra_params = {
+ .spi_clk_pin = SPI_SCK,
+ .spi_miso_pin = SPI_MISO,
+ .spi_mosi_pin = SPI_MOSI
+};
+
+/* Initialize the AD7606 device structure */
+struct ad7606_init_param ad7606_init_str = {
+ // Define SPI init parameters structure
+ {
+ .max_speed_hz = 22500000, // Max SPI Speed
+ .chip_select = SPI_SS, // Chip Select
+ .mode = SPI_MODE_2, // CPOL = 1, CPHA = 1
+ .extra = &spi_init_extra_params // SPI extra configurations
+ },
+
+ .gpio_reset = &gpio_init_reset,
+ .gpio_convst = &gpio_init_convst,
+ .gpio_busy = &gpio_init_busy,
+ .gpio_stby_n = &gpio_init_stdby,
+ .gpio_range = &gpio_init_range,
+ .gpio_os0 = &gpio_init_osr0,
+ .gpio_os1 = &gpio_init_osr1,
+ .gpio_os2 = &gpio_init_osr2,
+ .gpio_par_ser = NULL,
+
+ .device_id = ACTIVE_DEVICE,
+ .oversampling = { 0, AD7606_OSR_1 },
+ .sw_mode = true,
+
+ // Below settings (except range) applies only to AD7606B and AD7606C devices
+
+ /* Device Configs */
+ {
+ .op_mode = AD7606_NORMAL,
+ .dout_format = AD7606_1_DOUT,
+ .ext_os_clock = false,
+ .status_header = false
+ },
+
+ /* Diagnostic flags setting */
+ {
+ .rom_crc_err_en = false,
+ .mm_crc_err_en = false,
+ .int_crc_err_en = false,
+ .spi_write_err_en = false,
+ .spi_read_err_en = false,
+ .busy_stuck_high_err_en = false,
+ .clk_fs_os_counter_en = false,
+ .interface_check_en = false
+ },
+
+ /* Default offset for all channels */
+ .offset_ch = { 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ /* Default phase (0x00) for all channels */
+ .phase_ch = { 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ /* Default gain (0x00) for all channels */
+ .gain_ch = { 0, 0, 0, 0, 0, 0, 0, 0 },
+
+ /* Default range for all channels */
+ .range_ch = {
+#if defined(DEV_AD7609)
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, true},
+#else
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false},
+ {-USER_CONFIG_RANGE, USER_CONFIG_RANGE, false}
+#endif
+ }
+};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad7606_user_config.h Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,34 @@ +/*************************************************************************//** + * @file ad7606_user_config.h + * @brief Header for AD7606 user configuration file +****************************************************************************** +* 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. +*****************************************************************************/ + +#ifndef _AD7606_USER_CONFIG_H_ +#define _AD7606_USER_CONFIG_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include <stdint.h> +#include "ad7606.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/******************************************************************************/ +/********************** Variables and User Defined Data Types *****************/ +/******************************************************************************/ + +extern struct ad7606_init_param ad7606_init_str; + +#endif /* end of _AD7606_USER_CONFIG_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/app_config.h Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,124 @@ +/*************************************************************************//** + * @file app_config.h + * @brief Configuration file for AD7606 device applications +****************************************************************************** +* 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. +*****************************************************************************/ + +#ifndef _APP_CONFIG_H_ +#define _APP_CONFIG_H_ + +#include <stdint.h> +#include <PinNames.h> + +// **** Note for User: ACTIVE_DEVICE selection ****// +/* Define the device type here from the list of below device type defines + * (one at a time. Defining more than one device can result into compile error). + * e.g. #define DEV_AD7606B -> This will make AD7606B as an ACTIVE_DEVICE. + * The ACTIVE_DEVICE is default set to AD7606B if device type is not defined. + * */ + +//#define DEV_AD7606B + +#if defined(DEV_AD7605_4) +#define ACTIVE_DEVICE ID_AD7605_4 +#define ACTIVE_DEVICE_NAME "AD7605-4-phy" +#elif defined(DEV_AD7606_4) +#define ACTIVE_DEVICE ID_AD7606_4 +#define ACTIVE_DEVICE_NAME "AD7606-4-phy" +#elif defined(DEV_AD7606_6) +#define ACTIVE_DEVICE ID_AD7606_6 +#define ACTIVE_DEVICE_NAME "AD7606-6-phy" +#elif defined(DEV_AD7606_8) +#define ACTIVE_DEVICE ID_AD7606_8 +#define ACTIVE_DEVICE_NAME "AD7606-8-phy" +#elif defined(DEV_AD7606B) +#define ACTIVE_DEVICE ID_AD7606B +#define ACTIVE_DEVICE_NAME "AD7606B-phy" +#elif defined(DEV_AD7606C_16) +#define ACTIVE_DEVICE ID_AD7606C_16 +#define ACTIVE_DEVICE_NAME "AD7606C-16-phy" +#elif defined(DEV_AD7606C_18) +#define ACTIVE_DEVICE ID_AD7606C_18 +#define ACTIVE_DEVICE_NAME "AD7606C-18-phy" +#elif defined(DEV_AD7608) +#define ACTIVE_DEVICE ID_AD7608 +#define ACTIVE_DEVICE_NAME "AD7608-phy" +#elif defined(DEV_AD7609) +#define ACTIVE_DEVICE ID_AD7609 +#define ACTIVE_DEVICE_NAME "AD7609-phy" +#else +#warning No/Unsupported ADxxxxy symbol defined. AD7606B defined +#define DEV_AD7606B +#define ACTIVE_DEVICE ID_AD7606B +#define ACTIVE_DEVICE_NAME "AD7606B-phy" +#endif + + +#if defined(DEV_AD7605_4) +#define AD7606X_ADC_CHANNELS 4 +#define AD7606X_ADC_RESOLUTION 16 +#elif defined(DEV_AD7606_4) +#define AD7606X_ADC_CHANNELS 4 +#define AD7606X_ADC_RESOLUTION 16 +#elif defined(DEV_AD7606_6) +#define AD7606X_ADC_CHANNELS 6 +#define AD7606X_ADC_RESOLUTION 16 +#elif defined(DEV_AD7606_8) +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 16 +#elif defined(DEV_AD7606B) +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 16 +#elif defined(DEV_AD7606C_16) +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 16 +#elif defined(DEV_AD7606C_18) +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 18 +#elif defined(DEV_AD7608) +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 18 +#elif defined(DEV_AD7609) +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 18 +#else +/* Default config for AD7606B */ +#define AD7606X_ADC_CHANNELS 8 +#define AD7606X_ADC_RESOLUTION 16 +#endif + +/* ADC max count (full scale value) for unipolar inputs */ +#define ADC_MAX_COUNT_UNIPOLAR (uint32_t)((1 << AD7606X_ADC_RESOLUTION) - 1) + +/* ADC max count (full scale value) for bipolar inputs */ +#define ADC_MAX_COUNT_BIPOLAR (uint32_t)(1 << (AD7606X_ADC_RESOLUTION-1)) + +// Pin mapping of AD7606 w.r.t Arduino (reference: PinNames.h) +#define SPI_SS D10 +#define SPI_MOSI D11 +#define SPI_MISO D12 +#define SPI_SCK D13 + +#define UART_TX USBTX +#define UART_RX USBRX + +#define OSR0_PIN D2 +#define OSR1_PIN D3 +#define OSR2_PIN D4 +#define RESET_PIN D5 +#define CONVST_PIN D6 +#define BUSY_PIN D7 +#define RANGE_PIN D8 +#define STDBY_PIN D9 + +#define LED_GREEN LED3 + + +#endif //_APP_CONFIG_H_
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_ad7606.c Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,1851 @@
+/***************************************************************************//**
+ * @file iio_ad7606.c
+ * @brief Implementation of AD7606 IIO application interfaces
+ * @details This module acts as an interface for AD7606 IIO application
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * 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 <inttypes.h>
+#include <string.h>
+#include <errno.h>
+#include <math.h>
+
+#include "app_config.h"
+
+#include "tinyiiod.h"
+#include "iio_ad7606.h"
+#include "iio_ad7606_attr.h"
+#include "iio_app.h"
+#include "iio_transport.h"
+
+#include "platform_support.h"
+#include "spi_extra.h"
+#include "gpio_extra.h"
+#include "uart_extra.h"
+#include "irq_extra.h"
+
+#include "ad7606.h"
+#include "ad7606_data_capture.h"
+#include "ad7606_support.h"
+#include "ad7606_user_config.h"
+
+/******************************************************************************/
+/************************ Macros/Constants ************************************/
+/******************************************************************************/
+
+/* ADC data to Voltage conversion scale factor for IIO client */
+#define DEFAULT_SCALE ((DEFAULT_CHN_RANGE / ADC_MAX_COUNT_BIPOLAR) * 1000)
+
+/* LSB Threshold to entry into open wire detection as per datasheet */
+#define OPEN_DETECT_ENTRY_THRESHOLD 350
+
+/* Open detect LSB threshold @50K Rpd as per datasheet */
+#define OPEN_DETECT_THRESHOLD_RPD50K 15
+
+/* Maximum ADC calibration gain value */
+#define ADC_CALIBRATION_GAIN_MAX 64.0
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/**
+* IIO application instance descriptor.
+*/
+static struct iio_app_desc *iio_app_desc;
+
+/**
+ * Device name.
+ */
+static const char dev_name[] = ACTIVE_DEVICE_NAME;
+
+/**
+ * Pointer to the struct representing the AD7606 IIO device
+ */
+static struct ad7606_dev *p_ad7606_dev = NULL;
+
+
+/* Device attributes with default values */
+
+/* Power down mode values string representation (possible values specified in datasheet) */
+static char *operating_mode_str[] = {
+ "0 (Normal Mode)",
+ "1 (Standby Mode)",
+ "2 (Auto Standby Mode)",
+ "3 (Shutdown Mode)"
+};
+
+/* Bandwidth values string */
+static char *bandwidth_str[] = {
+ "0 (Low)",
+ "1 (High)"
+};
+
+/* Channel range values string representation (possible values specified in datasheet) */
+static char *chn_range_str[] = {
+#if defined(DEV_AD7606B)
+ "0 (+/-2.5V SE)", "1 (+/-5.0V SE)", "2 (+/-10.0V SE)", "3 (+/-10.0V SE)",
+ "4 (+/-10.0V SE)", "5 (+/-10.0V SE)", "6 (+/-10.0V SE)", "7 (+/-10.0V SE)",
+ "8 (+/-10.0V SE)", "9 (+/-10.0V SE)", "10 (+/-10.0V SE)", "11 (+/-10.0V SE)",
+#elif defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+ "0 (+/-2.5V SE)", "1 (+/-5.0V SE)", "2 (+/-6.25V SE)", "3 (+/-10.0V SE)",
+ "4 (+/-12.5V SE)", "5 (+5.0V SE)", "6 (+10.0V SE)", "7 (+12.5V SE)",
+ "8 (+/-5.0V DE)", "9 (+/-10.0V DE)", "10 (+/-12.5V DE)", "11 (+/-20.0V DE)"
+#elif defined(DEV_AD7609)
+ "0 (+/-10.0V SE)", "1 (+/-20.0V SE)"
+#else
+ "0 (+/-5.0V SE)", "1 (+/-10.0V SE)"
+#endif
+};
+
+/* Oversampling values string representation (possible values specified in datasheet) */
+static char *oversampling_val_str[] = {
+ "0 (no oversampling)", "1 (oversampling by 2)", "2 (oversampling by 4)",
+ "3 (oversampling by 8)", "4 (oversampling by 16)", "5 (oversampling by 32)",
+ "6 (oversampling by 64)", "7 (oversampling by 128)", "8 (oversampling by 256)"
+};
+
+
+/* Channel range values string representation (possible values specified in datasheet) */
+static float chn_range_val[] = {
+#if defined(DEV_AD7606B)
+ 2.5, 5.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0, 10.0
+#elif defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+ 2.5, 5.0, 6.25, 10.0, 12.5, 5.0, 10.0, 12.5, 5.0, 10.0, 12.5, 20.0
+#elif defined(DEV_AD7609)
+ 10.0, 20.0
+#else
+ 5.0, 10.0
+#endif
+};
+
+/* Range value per channel */
+static float attr_chn_range[AD7606X_ADC_CHANNELS] = {
+ DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE,
+ DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE, DEFAULT_CHN_RANGE
+};
+
+/* Scale value per channel */
+static float attr_scale_val[AD7606X_ADC_CHANNELS] = {
+ DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE,
+ DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE, DEFAULT_SCALE
+};
+
+/* Scale value per channel */
+static polarity_e attr_polarity_val[AD7606X_ADC_CHANNELS] = {
+ BIPOLAR, BIPOLAR, BIPOLAR, BIPOLAR,
+ BIPOLAR, BIPOLAR, BIPOLAR, BIPOLAR
+};
+
+/* Channel range */
+typedef enum {
+ LOW,
+ HIGH
+} range_e;
+
+/* Open detect auto mode QUEUE register count */
+static uint8_t open_detect_queue_cnts[AD7606X_ADC_CHANNELS] = {
+ 0
+};
+
+/* ADC gain calibration Rfilter value (in Kohms) */
+static uint8_t gain_calibration_reg_val[AD7606X_ADC_CHANNELS] = {
+ 0
+};
+
+/* Device register value */
+static uint8_t device_reg_val;
+
+/* GPIO LED descriptor and init structure */
+static struct gpio_desc *gpio_led;
+
+/* Flag to trigger new background conversion and capture when READBUFF command is issued */
+static bool adc_background_data_capture_started = false;
+
+/******************************************************************************/
+/************************ Functions Prototypes ********************************/
+/******************************************************************************/
+
+static float get_vltg_conv_scale_factor(float chn_range, polarity_e polarity);
+static void save_local_attributes(void);
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/*!
+ * @brief Getter/Setter for the scale attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_chn_scale(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ return (ssize_t) sprintf(buf, "%f", attr_scale_val[channel->ch_num - 1]);
+}
+
+ssize_t set_chn_scale(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float scale;
+
+ (void)sscanf(buf, "%f", &scale);
+
+ if (scale > 0.0) {
+ attr_scale_val[channel->ch_num - 1] = scale;
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the raw attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_chn_raw(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ int32_t adc_data_raw;
+
+ /* Capture the raw adc data */
+ adc_data_raw = single_data_read(device, channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ return (ssize_t) sprintf(buf, "%d", adc_data_raw);
+}
+
+ssize_t set_chn_raw(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ /* NA- Can't set raw value */
+ return len;
+}
+
+
+/*!
+ * @brief Getter/Setter for the operating mode attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_operating_mode(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t read_val;
+ uint8_t operating_mode_value;
+
+ if (ad7606_spi_reg_read(device, AD7606_REG_CONFIG, &read_val) == SUCCESS) {
+ operating_mode_value = (read_val & AD7606_CONFIG_OPERATION_MODE_MSK);
+
+ if (operating_mode_value < sizeof(operating_mode_str) / sizeof(
+ operating_mode_str[0])) {
+ return (ssize_t)sprintf(buf, "%s", operating_mode_str[operating_mode_value]);
+ }
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_operating_mode(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t operating_mode_value;
+
+ (void)sscanf(buf, "%d", &operating_mode_value);
+
+ if (operating_mode_value < sizeof(operating_mode_str) / sizeof(
+ operating_mode_str[0])) {
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_CONFIG,
+ AD7606_CONFIG_OPERATION_MODE_MSK,
+ operating_mode_value) == SUCCESS) {
+ return len;
+ }
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the power down mode attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available for all devices except AD7606B and AD7606C
+ */
+ssize_t get_power_down_mode(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t gpio_stby_val;
+ uint8_t gpio_range_val;
+
+ if (gpio_get_value(((struct ad7606_dev *)device)->gpio_stby_n,
+ &gpio_stby_val) == SUCCESS) {
+ if (gpio_get_value(((struct ad7606_dev *)device)->gpio_range,
+ &gpio_range_val) == SUCCESS) {
+
+ if (gpio_stby_val) {
+ return sprintf(buf, "%s", operating_mode_str[AD7606_NORMAL]);
+ } else {
+ if (gpio_range_val) {
+ return sprintf(buf, "%s", operating_mode_str[AD7606_STANDBY]);
+ } else {
+ return sprintf(buf, "%s", operating_mode_str[AD7606_SHUTDOWN]);
+ }
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_power_down_mode(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t power_down_mode_value;
+ static enum ad7606_op_mode prev_power_down_mode = AD7606_NORMAL;
+ struct ad7606_config dev_config;
+
+ sscanf(buf, "%d", &power_down_mode_value);
+
+ if (power_down_mode_value < (sizeof(operating_mode_str) / sizeof(
+ operating_mode_str[0]))) {
+
+ dev_config.op_mode = power_down_mode_value;
+
+ switch (power_down_mode_value) {
+ case AD7606_NORMAL:
+ if (ad7606_set_config(device, dev_config) == SUCCESS) {
+ /* Reset the device if previous power down mode was either standby
+ * or shutdown */
+ if (prev_power_down_mode != AD7606_NORMAL) {
+
+ /* Power-up wait time */
+ mdelay(1);
+
+ /* Toggle reset pin */
+ if (gpio_set_value(((struct ad7606_dev *)device)->gpio_reset,
+ GPIO_HIGH) == SUCCESS) {
+ mdelay(1);
+
+ if (gpio_set_value(((struct ad7606_dev *)device)->gpio_reset,
+ GPIO_LOW) == SUCCESS) {
+ prev_power_down_mode = AD7606_NORMAL;
+ return len;
+ }
+ }
+ }
+ }
+ break;
+
+ case AD7606_STANDBY:
+ if (ad7606_set_config(device, dev_config) == SUCCESS) {
+ prev_power_down_mode = AD7606_STANDBY;
+ return len;
+ }
+ break;
+
+ case AD7606_SHUTDOWN:
+ if (ad7606_set_config(device, dev_config) == SUCCESS) {
+ prev_power_down_mode = AD7606_SHUTDOWN;
+ return len;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the range attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available for all devices except AD7606B and AD7606C
+ */
+ssize_t get_range(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t gpio_range_val;
+ struct ad7606_dev *dev = device;
+
+ if (gpio_get_value(dev->gpio_range, &gpio_range_val) == SUCCESS) {
+ if (gpio_range_val) {
+ return sprintf(buf, "%s", chn_range_str[HIGH]);
+ } else {
+ return sprintf(buf, "%s", chn_range_str[LOW]);
+ }
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_range(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t range_value;
+ struct ad7606_dev *dev = device;
+
+ (void)sscanf(buf, "%d", &range_value);
+
+ if (range_value < (sizeof(chn_range_str) / sizeof(chn_range_str[0]))) {
+ if (range_value == LOW) {
+ if (gpio_set_value(dev->gpio_range, GPIO_LOW) == SUCCESS) {
+ return len;
+ }
+ } else {
+ if (gpio_set_value(dev->gpio_range, GPIO_HIGH) == SUCCESS) {
+ return len;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the oversampling attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available for all devices except AD7606B and AD7606C
+ */
+ssize_t get_oversampling(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t oversampling_value;
+ uint8_t read_val;
+ uint8_t gpio_osr0_val;
+ uint8_t gpio_osr1_val;
+ uint8_t gpio_osr2_val;
+ struct ad7606_dev *dev = device;
+
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+ if (ad7606_spi_reg_read(device,
+ AD7606_REG_OVERSAMPLING,
+ &read_val) == SUCCESS) {
+ oversampling_value = (read_val & AD7606_OVERSAMPLING_MSK);
+
+ if (oversampling_value < sizeof(oversampling_val_str) / sizeof(
+ oversampling_val_str[0])) {
+ return (ssize_t)sprintf(buf, "%s", oversampling_val_str[oversampling_value]);
+ }
+ }
+#else
+ if (gpio_get_value(dev->gpio_os0, &gpio_osr0_val) == SUCCESS) {
+ if (gpio_get_value(dev->gpio_os1, &gpio_osr1_val) == SUCCESS) {
+ if (gpio_get_value(dev->gpio_os2, &gpio_osr2_val) == SUCCESS) {
+ oversampling_value = (gpio_osr2_val << 2) | (gpio_osr1_val << 1) |
+ gpio_osr0_val;
+
+ if (oversampling_value < (sizeof(oversampling_val_str) / sizeof(
+ oversampling_val_str[0]))) {
+ return sprintf(buf, "%s", oversampling_val_str[oversampling_value]);
+ }
+ }
+ }
+ }
+#endif
+
+ return -EINVAL;
+}
+
+ssize_t set_oversampling(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t oversampling_value;
+ struct ad7606_oversampling oversampling_cfg;
+
+ (void)sscanf(buf, "%d", &oversampling_value);
+
+ if (oversampling_value < (sizeof(oversampling_val_str) / sizeof(
+ oversampling_val_str[0]))) {
+
+ oversampling_cfg.os_pad = 0;
+ oversampling_cfg.os_ratio = oversampling_value;
+
+ ad7606_set_oversampling(device, oversampling_cfg);
+
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the bandwidth attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available for only AD7606C
+ */
+ssize_t get_bandwidth(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t bw_value;
+ uint8_t read_val;
+
+ if (ad7606_spi_reg_read(device,
+ AD7606_REG_BANDWIDTH,
+ &read_val) == SUCCESS) {
+ bw_value = (read_val >> (channel->ch_num - 1)) & 0x1;
+
+ if (bw_value < sizeof(bandwidth_str) / sizeof(
+ bandwidth_str[0])) {
+ return (ssize_t)sprintf(buf, "%s", bandwidth_str[bw_value]);
+ }
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_bandwidth(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t bw_value;
+ uint8_t read_val;
+
+ (void)sscanf(buf, "%d", &bw_value);
+
+ if (bw_value < sizeof(bandwidth_str) / sizeof(
+ bandwidth_str[0])) {
+ if (ad7606_spi_reg_read(device,
+ AD7606_REG_BANDWIDTH,
+ &read_val) == SUCCESS) {
+ if (bw_value) {
+ read_val |= (1 << (channel->ch_num - 1));
+ } else {
+ read_val &= (~(1 << (channel->ch_num - 1)));
+ }
+
+ if (ad7606_spi_reg_write(device,
+ AD7606_REG_BANDWIDTH,
+ read_val) == SUCCESS) {
+ return len;
+ }
+ }
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel range attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_range(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t read_val;
+ uint8_t chn_range;
+
+ if (ad7606_spi_reg_read(device, AD7606_REG_RANGE_CH_ADDR(channel->ch_num-1),
+ &read_val) == SUCCESS) {
+ if (((channel->ch_num - 1) % 2) != 0) {
+ read_val >>= CHANNEL_RANGE_MSK_OFFSET;
+ chn_range = read_val;
+ } else {
+ chn_range = (read_val & AD7606_RANGE_CH_MSK(channel->ch_num - 1));
+ }
+
+ if (chn_range < sizeof(chn_range_str) / sizeof(chn_range_str[0])) {
+ attr_chn_range[channel->ch_num - 1] = chn_range_val[chn_range];
+ attr_polarity_val[channel->ch_num - 1] = ad7606_get_input_polarity(chn_range);
+
+ return (ssize_t)sprintf(buf, "%s", chn_range_str[chn_range]);
+ }
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_range(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t chn_range;
+
+ (void)sscanf(buf, "%d", &chn_range);
+
+ if (chn_range < sizeof(chn_range_val) / sizeof(chn_range_val[0])) {
+
+ /* Get the polarity of channel */
+ attr_polarity_val[channel->ch_num - 1] = ad7606_get_input_polarity(chn_range);
+
+ attr_chn_range[channel->ch_num - 1] = chn_range_val[chn_range];
+ attr_scale_val[channel->ch_num - 1] = get_vltg_conv_scale_factor(
+ chn_range_val[chn_range],
+ attr_polarity_val[channel->ch_num - 1]);
+
+ if (((channel->ch_num - 1) % 2) != 0) {
+ chn_range <<= CHANNEL_RANGE_MSK_OFFSET;
+ }
+
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_RANGE_CH_ADDR(channel->ch_num-1),
+ AD7606_RANGE_CH_MSK(channel->ch_num-1),
+ chn_range) == SUCCESS) {
+ return len;
+ }
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel offset attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_offset(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t chn_offset_value;
+
+ if (ad7606_spi_reg_read(device, AD7606_REG_OFFSET_CH(channel->ch_num-1),
+ &chn_offset_value) == SUCCESS) {
+ return (ssize_t)sprintf(buf, "%d", chn_offset_value);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_offset(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t chn_offset_value = 0;
+
+ (void)sscanf(buf, "%d", &chn_offset_value);
+
+ if (ad7606_set_ch_offset(device, channel->ch_num - 1,
+ chn_offset_value) == SUCCESS) {
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel pahse offset attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_phase_offset(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t chn_phase_offset_value;
+
+ if (ad7606_spi_reg_read(device,
+ AD7606_REG_PHASE_CH(channel->ch_num - 1),
+ &chn_phase_offset_value) == SUCCESS) {
+ return (ssize_t)sprintf(buf, "%d", chn_phase_offset_value);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_phase_offset(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t chn_phase_offset_value = 0;
+
+ (void)sscanf(buf, "%d", &chn_phase_offset_value);
+
+ if (ad7606_set_ch_phase(device, channel->ch_num - 1,
+ chn_phase_offset_value) == SUCCESS) {
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel temperature attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_temperature(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ int32_t adc_chn_data = 0;
+ float temperature;
+ float voltage;
+
+ /* Configure the channel multiplexer to select temperature read */
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ TEMPERATURE_MUX)) == SUCCESS) {
+
+ /* Allow to settle Mux channel */
+ udelay(100);
+
+ /* Sample the channel and read conversion result */
+ adc_chn_data = single_data_read(device, channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Convert ADC data into equivalent voltage */
+ voltage = convert_adc_raw_to_voltage(adc_chn_data,
+ attr_scale_val[channel->ch_num - 1]);
+
+ /* Obtain the temperature using equation specified in device datasheet */
+ temperature = ((voltage - 0.69068) / 0.019328) + 25.0;
+
+ /* Change channel mux back to analog input */
+ (void)ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ ANALOG_INPUT_MUX));
+
+ return (ssize_t)sprintf(buf, "%f", temperature);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_temperature(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set temperature
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel Vref attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_vref(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float vref_voltge;
+ int32_t adc_chn_data;
+
+ /* Configure the channel multiplexer to select Vref read */
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ VREF_MUX)) == SUCCESS) {
+
+ /* Allow to settle Mux channel */
+ udelay(100);
+
+ /* Sample the channel and read conversion result */
+ adc_chn_data = single_data_read(device, channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Convert ADC data into equivalent voltage */
+ vref_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+ attr_scale_val[channel->ch_num - 1]);
+
+ /* Divide by 4 since Vref Mux has 4x multiplier on it */
+ vref_voltge /= VREF_MUX_MULTIPLIER;
+
+ /* Change channel mux back to analog input */
+ (void)ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ ANALOG_INPUT_MUX));
+
+ return (ssize_t)sprintf(buf, "%f", vref_voltge);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_vref(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set Vref
+ return - EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel Vdrive attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_vdrive(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float vdrive_voltge;
+ int32_t adc_chn_data;
+
+ /* Configure the channel multiplexer to select Vdrive read */
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ VDRIVE_MUX)) == SUCCESS) {
+
+ /* Allow to settle Mux channel */
+ udelay(100);
+
+ /* Sample the channel and read conversion result */
+ adc_chn_data = single_data_read(device, channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Convert ADC data into equivalent voltage */
+ vdrive_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+ attr_scale_val[channel->ch_num - 1]);
+
+ /* Change channel mux back to analog input */
+ (void)ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ ANALOG_INPUT_MUX));
+
+ return (ssize_t)sprintf(buf, "%f", vdrive_voltge);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_vdrive(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set Vdrive
+ return - EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel ALDO attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_aldo(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float aldo_voltge;
+ int32_t adc_chn_data;
+
+ /* Configure the channel multiplexer to select ALDO read */
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ ALDO_MUX)) == SUCCESS) {
+
+ /* Allow to settle Mux channel */
+ udelay(100);
+
+ /* Sample the channel and read conversion result */
+ adc_chn_data = single_data_read(device, channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Convert ADC data into equivalent voltage */
+ aldo_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+ attr_scale_val[channel->ch_num - 1]);
+
+ /* Divide by 4 since ALDO Mux has 4x multiplier on it */
+ aldo_voltge /= VREF_MUX_MULTIPLIER;
+
+ /* Change channel mux back to analog input */
+ (void)ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ ANALOG_INPUT_MUX));
+
+ return (ssize_t)sprintf(buf, "%f", aldo_voltge);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_aldo(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set ALDO
+ return - EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel DLDO attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ * @note Available only for AD7606B and AD7606C
+ */
+ssize_t get_chn_dldo(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float dldo_voltge;
+ int32_t adc_chn_data;
+
+ /* Configure the channel multiplexer to select DLDO read */
+ if (ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ DLDO_MUX)) == SUCCESS) {
+
+ /* Allow to settle Mux channel */
+ udelay(100);
+
+ /* Sample the channel and read conversion result */
+ adc_chn_data = single_data_read(device,
+ channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Convert ADC data into equivalent voltage */
+ dldo_voltge = convert_adc_raw_to_voltage(adc_chn_data,
+ attr_scale_val[channel->ch_num - 1]);
+
+ /* Divide by 4 since ALDO Mux has 4x multiplier on it */
+ dldo_voltge /= VREF_MUX_MULTIPLIER;
+
+ /* Change channel mux back to analog input */
+ (void)ad7606_spi_write_mask(device,
+ AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_MSK(channel->ch_num - 1),
+ AD7606_DIAGN_MUX_CH_VAL((channel->ch_num - 1),
+ ANALOG_INPUT_MUX));
+
+ return (ssize_t)sprintf(buf, "%f", dldo_voltge);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_dldo(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set DLDO
+ return - EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel open wire detect manual attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_chn_open_wire_detect_manual(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ static volatile int32_t data[2];
+ uint8_t open_detect_flag = false;
+ int32_t rw_status = FAILURE;
+
+ /* Read the ADC on selected channel (before open wire detection start) */
+ data[0] = single_data_read(device,
+ channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Enter into manual open wire detect mode */
+ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 1) == SUCCESS) {
+ /* Set common mode high (enabling open wire detect on selected channel) */
+ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_ENABLE,
+ (1 << ((channel->ch_num) - 1))) == SUCCESS) {
+ /* Read the ADC on selected chnnel (post open wire detection) */
+ data[1] = single_data_read(device, channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Check for up shift in common mode output voltage */
+ if ((data[1] - data[0]) > OPEN_DETECT_THRESHOLD_RPD50K) {
+ /* Set common mode low (disabling open wire detect on channels) */
+ if (ad7606_spi_reg_write(device,
+ AD7606_REG_OPEN_DETECT_ENABLE,
+ 0) == SUCCESS) {
+
+ /* Let channel settle down */
+ mdelay(1);
+
+ /* Read the ADC output after open wire detection */
+ data[1] = single_data_read(device,
+ channel->ch_num - 1,
+ attr_polarity_val[channel->ch_num - 1]);
+
+ /* Check if code returns back to original (with some threshold) */
+ if (abs(data[1] - data[0]) <= OPEN_DETECT_THRESHOLD_RPD50K) {
+ open_detect_flag = true;
+ }
+ }
+ }
+
+ rw_status = SUCCESS;
+ }
+ }
+
+ /* Disable open detect mode */
+ (void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 0);
+
+ if (rw_status == SUCCESS) {
+ if (open_detect_flag) {
+ strcpy(buf, "Open Wire Detected");
+ } else {
+ strcpy(buf, "Open Wire Not Detected");
+ }
+
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_open_wire_detect_manual(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set open wire detect
+ return - EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the channel open wire detect auto attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_chn_open_wire_detect_auto(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t open_detect_flag = false;
+ int32_t rw_status = FAILURE;
+ uint8_t conv_cnts;
+
+ if (open_detect_queue_cnts[channel->ch_num-1] <= 1) {
+ strcpy(buf, "Err: OPEN_DETECT_QUEUE Invalid");
+ return len;
+ }
+
+ /* Enter into auto open detect mode */
+ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE,
+ open_detect_queue_cnts[channel->ch_num-1]) == SUCCESS) {
+ /* Enable open wire detection on selected channel */
+ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_ENABLE,
+ (1 << ((channel->ch_num) - 1))) == SUCCESS) {
+ /* Monitor the open detect flag for max N (open detect queue count) conversions.
+ * Note: In ideal scenario, the open detect flash should be monitored continuously while
+ * background N conversions are in progress */
+ for (conv_cnts = 0; conv_cnts < open_detect_queue_cnts[channel->ch_num - 1];
+ conv_cnts++) {
+ if (ad7606_convst(device) == SUCCESS) {
+ udelay(100);
+
+ /* Monitor the open detect flag */
+ if (ad7606_spi_reg_read(device,
+ AD7606_REG_OPEN_DETECTED,
+ &open_detect_flag) == SUCCESS) {
+ open_detect_flag >>= (channel->ch_num - 1);
+ open_detect_flag &= 0x1;
+
+ rw_status = SUCCESS;
+ if (open_detect_flag) {
+ break;
+ }
+ } else {
+ rw_status = FAILURE;
+ break;
+ }
+ } else {
+ rw_status = FAILURE;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Disable open detect mode */
+ (void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 0);
+
+ if (rw_status == SUCCESS) {
+ if (open_detect_flag) {
+ strcpy(buf, "Open Wire Detected");
+ } else {
+ strcpy(buf, "Open Wire Not Detected");
+ }
+
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_open_wire_detect_auto(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t data;
+
+ (void)sscanf(buf, "%d", &data);
+
+ if (data > 1) {
+ open_detect_queue_cnts[channel->ch_num - 1] = data;
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the adc offset calibration
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_chn_calibrate_adc_offset(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float lsb_voltage;
+ float adc_voltage;
+ polarity_e polarity = attr_polarity_val[channel->ch_num - 1];
+ int32_t adc_data;
+ int8_t chn_offset;
+
+ /* Perform the system offset calibration */
+
+ if (polarity == UNIPOLAR) {
+ lsb_voltage = attr_chn_range[channel->ch_num - 1] / ADC_MAX_COUNT_UNIPOLAR;
+ } else {
+ lsb_voltage = attr_chn_range[channel->ch_num - 1] / ADC_MAX_COUNT_BIPOLAR;
+ }
+
+ /* Sample and read the ADC channel */
+ adc_data = single_data_read(device, channel->ch_num - 1,
+ polarity);
+
+ /* Get an equivalent ADC voltage */
+ adc_voltage = convert_adc_raw_to_voltage(adc_data,
+ attr_scale_val[channel->ch_num - 1]);
+
+ /* Calculate the channel offset and write it to offset register */
+ chn_offset = -(adc_voltage / lsb_voltage);
+
+ if (ad7606_set_ch_offset(device, channel->ch_num - 1,
+ chn_offset) == SUCCESS) {
+ return sprintf(buf, "%s", "ADC Calibration Done");
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_calibrate_adc_offset(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ // NA- Can't set open wire detect
+ return - EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the adc gain calibration
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_chn_calibrate_adc_gain(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t chn_gain;
+
+ /* Perform the gain calibration */
+ chn_gain = gain_calibration_reg_val[channel->ch_num - 1];
+
+ if (ad7606_set_ch_gain(device,
+ channel->ch_num - 1,
+ chn_gain) == SUCCESS) {
+ return sprintf(buf, "Calibration Done (Rfilter=%d K)", chn_gain);
+ }
+
+ return -EINVAL;
+}
+
+ssize_t set_chn_calibrate_adc_gain(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ float data;
+
+ (void)sscanf(buf, "%f", &data);
+
+ if (data < ADC_CALIBRATION_GAIN_MAX) {
+ /* Get the nearest value of unsigned integer */
+ gain_calibration_reg_val[channel->ch_num - 1] = (uint8_t)(round(data));
+ return len;
+ }
+
+ return -EINVAL;
+}
+
+
+/*!
+ * @brief Getter/Setter for the direct register access attribute value
+ * @param device- pointer to IIO device structure
+ * @param buf- pointer to buffer holding attribute value
+ * @param len- length of buffer string data
+ * @param channel- pointer to IIO channel structure
+ * @return Number of characters read/written
+ */
+ssize_t get_direct_reg_access(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ return (ssize_t)sprintf(buf, "%d", device_reg_val);
+}
+
+ssize_t set_direct_reg_access(void *device,
+ char *buf,
+ size_t len,
+ const struct iio_ch_info *channel)
+{
+ uint8_t reg_address;
+ char *token;
+ uint8_t offset = strlen("0x");
+ char str[10] = "";
+ uint8_t i=0;
+ uint8_t reg_data;
+
+ if (buf[1] == 'x') {
+ /* Write a data to device */
+
+ /* Extract the register address from received string */
+ strcpy(str, buf);
+ token = strtok(str, " ");
+ (void)sscanf(token + offset, "%x", ®_address);
+
+ /* Extract the register data from received string */
+ i = (strlen(str) + 1) + offset;
+ (void)sscanf(str + i, "%x", ®_data);
+
+ if (reg_address <= NUM_OF_REGISTERS) {
+ if ((ad7606_spi_reg_write(device, reg_address, reg_data) == SUCCESS)) {
+ save_local_attributes();
+ return len;
+ }
+ }
+ } else {
+ /* Read the data from device */
+ (void)sscanf(buf, "%d", ®_address);
+ if ((ad7606_spi_reg_read(device, reg_address, &device_reg_val) == SUCCESS)) {
+ return len;
+ }
+ }
+
+ return -EINVAL;
+}
+
+
+/**
+ * @brief Get xml corresponding to an AD7606 device.
+ * @param xml - Xml containing description of a device.
+ * @param iio_dev - Structure describing a device, channels and attributes.
+ * @return SUCCESS in case of success or negative value otherwise.
+ */
+static ssize_t iio_ad7606_get_xml(char **xml, struct iio_device *iio_dev)
+{
+ *xml = (char*)calloc(1, strlen(ad7606_phy_xml) + 1);
+ if (!(*xml)) {
+ return -ENOMEM;
+ }
+
+ memcpy(*xml, ad7606_phy_xml, strlen(ad7606_phy_xml));
+
+ return SUCCESS;
+}
+
+
+/**
+ * @brief Read buffer data corresponding to AD7606 IIO device
+ * @param dev_instance[in] - IIO device instance
+ * @param pbuf[out] - Pointer to output data buffer
+ * @return SUCCESS in case of success or negative value otherwise
+ */
+static ssize_t iio_ad7606_read_data(void *dev_instance,
+ char *pbuf,
+ size_t offset,
+ size_t bytes_count,
+ uint32_t ch_mask)
+{
+ if (adc_background_data_capture_started == false) {
+ start_background_data_capture(ch_mask, bytes_count);
+ adc_background_data_capture_started = true;
+ }
+
+ /* Read the buffered data */
+ return (ssize_t)buffered_data_read(pbuf, bytes_count, offset, ch_mask);
+}
+
+
+/**
+ * @brief Read requested samples count
+ * @param dev_instance[in] - IIO device instance
+ * @param pbuf[out] - Pointer to output data buffer
+ * @return SUCCESS in case of success or negative value otherwise
+ */
+static ssize_t iio_ad7606_get_samples_count(void *dev_instance,
+ size_t bytes_count,
+ uint32_t ch_mask)
+{
+ store_requested_samples_count(bytes_count);
+ return SUCCESS;
+}
+
+
+/**
+ * @brief Create structure describing a device, channels and attributes
+ * @param device_name[in] - Device name
+ * @return iio_device or NULL, in case of failure
+ */
+static struct iio_device *iio_ad7606_create_device(const char *device_name)
+{
+ struct iio_device *iio_ad7606_device;
+
+ iio_ad7606_device = calloc(1, sizeof(struct iio_device));
+ if (!iio_ad7606_device) {
+ return NULL;
+ }
+
+ iio_ad7606_device->name = device_name;
+ iio_ad7606_device->num_ch = sizeof(iio_ad7606_channels) / sizeof(
+ iio_ad7606_channels[0]);
+ iio_ad7606_device->channels = iio_ad7606_channels;
+ iio_ad7606_device->attributes = global_attributes;
+
+ return iio_ad7606_device;
+}
+
+
+/**
+ * @brief Delete IIO device.
+ * @param iio_device - Structure describing a device, channels and attributes
+ * @return SUCCESS in case of success or negative value otherwise
+ */
+static ssize_t iio_ad7606_delete_device(struct iio_device *iio_device)
+{
+ if (!iio_device) {
+ return FAILURE;
+ }
+
+ free(iio_device);
+
+ return SUCCESS;
+}
+
+
+/**
+ * @brief Init for reading/writing and parameterization of a
+ * ad7606 IIO device
+ * @param desc[in,out] - IIO device descriptor
+ * @param init[in] - Configuration structure
+ * @return SUCCESS in case of success, FAILURE otherwise
+ */
+int32_t iio_ad7606_init(struct iio_ad7606_desc **desc,
+ struct iio_ad7606_init_param *init)
+{
+ int32_t status;
+ struct iio_interface *iio_interface;
+
+ iio_interface = (struct iio_interface *)calloc(1, sizeof(struct iio_interface));
+ if (!iio_interface) {
+ return -ENOMEM;
+ }
+
+ *iio_interface = (struct iio_interface) {
+ .name = dev_name,
+ .dev_instance = init->ad7606_phy,
+ .iio = iio_ad7606_create_device(dev_name),
+ .get_xml = iio_ad7606_get_xml,
+ .transfer_dev_to_mem = iio_ad7606_get_samples_count,
+ .transfer_mem_to_dev = NULL,
+ .read_data = iio_ad7606_read_data,
+ .write_data = NULL,
+ };
+
+ status = iio_register(iio_interface);
+ if (status < 0) {
+ free(iio_interface);
+ return FAILURE;
+ }
+
+ *desc = calloc(1, sizeof(struct iio_ad7606_desc));
+ if (!(*desc)) {
+ iio_unregister(iio_interface);
+ free(iio_interface);
+ return FAILURE;
+ }
+
+ (*desc)->iio_interface = iio_interface;
+
+ return SUCCESS;
+}
+
+
+/**
+ * @brief Release resources allocated for IIO device
+ * @param desc[in] - IIO device descriptor
+ * @return SUCCESS in case of success, FAILURE otherwise
+ */
+int32_t iio_ad7606_remove(struct iio_ad7606_desc *desc)
+{
+ int32_t status;
+
+ if (!desc) {
+ return FAILURE;
+ }
+
+ status = iio_unregister(desc->iio_interface);
+ if (status < 0) {
+ return FAILURE;
+ }
+
+ status = iio_ad7606_delete_device(desc->iio_interface->iio);
+ if (status < 0) {
+ return FAILURE;
+ }
+
+ free(desc->iio_interface);
+ free(desc);
+
+ return SUCCESS;
+}
+
+
+/*!
+ * @brief Get scale factor for adc data to voltage conversion for IIO client
+ * @param chn_range[in] - Current channel voltage range
+ * @param chn_range_bits[in] - Channel range register bits
+ * @return scale
+ * @details This function samples and capture the new data when previous data
+ * is transmitted to IIO client
+ */
+static float get_vltg_conv_scale_factor(float chn_range, polarity_e polarity)
+{
+ float scale;
+
+ /* Get the scale factor for voltage conversion from range */
+ if (polarity == UNIPOLAR) {
+ scale = (chn_range / ADC_MAX_COUNT_UNIPOLAR) * 1000;
+ } else {
+ scale = (chn_range / ADC_MAX_COUNT_BIPOLAR) * 1000;
+ }
+
+ return scale;
+}
+
+
+/**
+ * @brief Save local variables
+ * @return none
+ * @details This function saves the local parameters with updated device values
+ */
+static void save_local_attributes(void)
+{
+ char buf[50];
+ struct iio_ch_info channel;
+
+ for (uint8_t chn = 1; chn <= AD7606X_ADC_CHANNELS; chn++) {
+ channel.ch_num = chn;
+
+ /* Get channel range */
+ (void)get_chn_range(p_ad7606_dev, buf, 0, &channel);
+
+ /* Get scale */
+ attr_scale_val[channel.ch_num - 1] = get_vltg_conv_scale_factor(
+ attr_chn_range[channel.ch_num - 1],
+ attr_polarity_val[channel.ch_num - 1]);
+ }
+}
+
+
+/**
+ * @brief Initialize the IRQ contoller
+ * @param uart_desc[in] - UART descriptor for UART Rx IRQ event init
+ * @return none
+ * @details This function initialize the interrupt controller
+ */
+static int32_t iio_interrupt_handler_init(mbed_uart_desc *uart_desc)
+{
+ /* Pin to generate external interrupt */
+ PinName ext_int_pin = BUSY_PIN;
+
+ /* External interrupt descriptor */
+ struct irq_ctrl_desc *external_int_desc;
+
+ /* Define external interrupt platform specific parameters structure */
+ mbed_irq_init_param mbed_ext_int_init_param = {
+ .int_mode = EXT_IRQ_FALL,
+ .int_obj_type = &ext_int_pin
+ };
+
+ /* External interrupt init parameters */
+ struct irq_init_param external_int_init_param = {
+ .irq_ctrl_id = EXTERNAL_INT_ID,
+ .extra = &mbed_ext_int_init_param
+ };
+
+ /* External interrupt callback descriptor */
+ struct callback_desc external_int_callback_desc = {
+ &do_conversion_callback,
+ NULL,
+ NULL
+ };
+
+ /* UART Rx interrupt descriptor */
+ struct irq_ctrl_desc *uart_rx_int_desc;
+
+ /* Define external interrupt platform specific parameters structure */
+ mbed_irq_init_param mbed_uart_rx_int_init_param = {
+ .int_mode = 0,
+ .int_obj_type = uart_desc->uart_port
+ };
+
+ /* UART Rx interrupt init parameters */
+ struct irq_init_param uart_rx_int_init_param = {
+ .irq_ctrl_id = UART_RX_INT_ID,
+ .extra = &mbed_uart_rx_int_init_param
+ };
+
+ /* UART Rx interrupt callback descriptor */
+ struct callback_desc uart_rx_int_callback_desc = {
+ &iio_uart_rx_callback,
+ NULL,
+ NULL
+ };
+
+ /* Init interrupt controller for external interrupt */
+ if (irq_ctrl_init(&external_int_desc, &external_int_init_param) == FAILURE) {
+ return FAILURE;
+ }
+
+ /* Init interrupt controller for UART Rx interrupt */
+ if (irq_ctrl_init(&uart_rx_int_desc, &uart_rx_int_init_param) == FAILURE) {
+ return FAILURE;
+ }
+
+ /* Register a callback function for external interrupt */
+ if (irq_register_callback(external_int_desc, EXTERNAL_INT_ID,
+ &external_int_callback_desc) == FAILURE) {
+ return FAILURE;
+ }
+
+ /* Register a callback function for UART Rx interrupt */
+ if (irq_register_callback(uart_rx_int_desc, UART_RX_INT_ID,
+ &uart_rx_int_callback_desc) == FAILURE) {
+ return FAILURE;
+ }
+
+ return SUCCESS;
+}
+
+
+/**
+ * @brief Initialize the IIO interface for AD7606 IIO device
+ * @return none
+ * @return SUCCESS in case of success, FAILURE otherwise
+ */
+int32_t ad7606_iio_initialize(void)
+{
+ int32_t init_status;
+
+ /**
+ * AD7606 IIO instance descriptor
+ */
+ struct iio_ad7606_desc *piio_ad7606_desc;
+
+ /**
+ * AD7606 IIO init parameters
+ */
+ struct iio_ad7606_init_param iio_ad7606_init_param;
+
+ /**
+ * IIO application init parameters
+ */
+ struct iio_app_init_param iio_app_init_par;
+
+ /**
+ * UART serial interface read/write callback
+ */
+ struct iio_server_ops uart_iio_server_ops;
+
+ /*
+ * UART Mbed init extra parameters structure
+ */
+ mbed_uart_init_param uart_extra_init_param;
+
+ /*
+ * UART init parameters structure
+ */
+ struct uart_init_param uart_init_param;
+
+ /**
+ * IIO application UART descriptor
+ */
+ struct uart_desc *uart_desc = NULL;
+
+ /*
+ * GPIO LED Init parameters structure
+ */
+ struct gpio_init_param gpio_init_led;
+
+ iio_ad7606_init_param = (struct iio_ad7606_init_param) {
+ .ad7606_phy = NULL,
+ };
+
+ uart_extra_init_param = (mbed_uart_init_param) {
+ .uart_tx_pin = UART_TX,
+ .uart_rx_pin = UART_RX
+ };
+
+ uart_init_param = (struct uart_init_param ) {
+ .device_id = NULL,
+ .baud_rate = IIO_UART_BAUD_RATE,
+ .extra = &uart_extra_init_param
+ };
+
+ uart_iio_server_ops = (struct iio_server_ops) {
+ .read = iio_uart_read,
+ .write = iio_uart_write,
+ };
+
+ gpio_init_led = (struct gpio_init_param) {
+ .number = LED_GREEN,
+ .extra = NULL
+ };
+
+ iio_app_init_par = (struct iio_app_init_param) {
+ .iio_server_ops = &uart_iio_server_ops,
+ };
+
+ /* Initialize AD7606 device and peripheral interface */
+ init_status = ad7606_init(&p_ad7606_dev, &ad7606_init_str);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+
+ /* Initialize the LED GPIO descriptor */
+ init_status = gpio_get_optional(&gpio_led, &gpio_init_led);
+ if (init_status != SUCCESS) {
+ return init_status;
+ } else {
+ init_status = gpio_direction_output(gpio_led, GPIO_HIGH);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+ }
+
+ /* Get the AD7606 IIO device instance */
+ iio_ad7606_init_param.ad7606_phy = p_ad7606_dev;
+
+ /* Initialize the UART interface for IIO application */
+ init_status = iio_uart_init(&uart_desc, &uart_init_param);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+
+ /* Initialize the IIO application interface */
+ init_status = iio_app_init(&iio_app_desc, &iio_app_init_par);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+
+ /* Register and initialize the AD7606 device into IIO interface */
+ init_status = iio_ad7606_init(&piio_ad7606_desc, &iio_ad7606_init_param);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+
+ /* Init the data capture for AD7606 IIO app */
+ init_status = iio_data_capture_init(p_ad7606_dev);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+
+ /* Init the interrupt event handler for AD7606 IIO app */
+ init_status = iio_interrupt_handler_init(uart_desc->extra);
+ if (init_status != SUCCESS) {
+ return init_status;
+ }
+
+ return init_status;
+}
+
+
+/**
+ * @brief Run the AD7606 IIO event handler
+ * @return none
+ * @details This function monitors the new IIO client event
+ */
+void ad7606_iio_event_handler(void)
+{
+ /* Handle new IIO command */
+ if (is_new_iio_command_detected()) {
+ /* Stop the background data capture if it is running before and any
+ * iio command except READBUF is received */
+ if (adc_background_data_capture_started) {
+ if (!check_iio_cmd("READBUF", 7)) {
+ stop_background_data_capture();
+ adc_background_data_capture_started = false;
+ }
+ }
+
+ /* Run the IIO interface when new command is detected */
+ (void)iio_app(iio_app_desc);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_ad7606.h Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,70 @@
+/***************************************************************************//**
+* @file iio_ad7606.h
+* @brief Header file of iio_ad7606
+********************************************************************************
+* 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.
+*******************************************************************************/
+#ifndef IIO_AD7606_H_
+#define IIO_AD7606_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include "iio.h"
+#include "iio_types.h"
+
+/******************************************************************************/
+/****************************** Macros ****************************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/**
+ * @struct iio_ad7606_init_param
+ * @brief Device configuration structure.
+ */
+struct iio_ad7606_init_param {
+ /** ad7606 device instance pointer */
+ struct ad7606_dev *ad7606_phy;
+};
+
+/**
+ * @struct iio_ad7606_desc
+ * @brief Structure holding IIO descriptor.
+ */
+struct iio_ad7606_desc {
+ /** iio_interface instance pointer */
+ struct iio_interface *iio_interface;
+};
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/* Init AD7606 IIO interface */
+int32_t iio_ad7606_init(struct iio_ad7606_desc **desc,
+ struct iio_ad7606_init_param *init);
+
+/* Free the resources allocated for IIO device */
+int32_t iio_ad7606_remove(struct iio_ad7606_desc *desc);
+
+/* Init the IIO interface */
+int32_t ad7606_iio_initialize(void);
+
+/* Run the IIO event handler */
+void ad7606_iio_event_handler(void);
+
+/* Init the IIO application */
+int32_t ad7606_app_initialize(void);
+
+#endif /* IIO_AD7606_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_ad7606_attr.h Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,510 @@
+/***************************************************************************//**
+* @file iio_ad7606_attr.h
+* @brief File for AD7606 IIO Attributes
+********************************************************************************
+* 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.
+*******************************************************************************/
+#ifndef IIO_AD7606_ATTR_H_
+#define IIO_AD7606_ATTR_H_
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+
+#include <stdio.h>
+#include <stdbool.h>
+
+#include "app_config.h"
+#include "iio.h"
+#include "iio_types.h"
+
+/******************************************************************************/
+/****************************** Macros ****************************************/
+/******************************************************************************/
+
+extern ssize_t get_chn_scale(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_scale(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_range(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_range(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_offset(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_offset(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_phase_offset(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_phase_offset(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_temperature(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_temperature(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_vref(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_vref(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_vdrive(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_vdrive(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_aldo(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_aldo(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_dldo(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_dldo(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_bandwidth(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_bandwidth(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_open_wire_detect_manual(void *device, char *buf,
+ size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_open_wire_detect_manual(void *device, char *buf,
+ size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_open_wire_detect_auto(void *device, char *buf,
+ size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_open_wire_detect_auto(void *device, char *buf,
+ size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_calibrate_adc_offset(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_calibrate_adc_offset(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_calibrate_adc_gain(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_calibrate_adc_gain(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_chn_raw(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_chn_raw(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_operating_mode(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_operating_mode(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_power_down_mode(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_power_down_mode(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_range(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_range(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_oversampling(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_oversampling(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+extern ssize_t get_direct_reg_access(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+extern ssize_t set_direct_reg_access(void *device, char *buf, size_t len,
+ const struct iio_ch_info *channel);
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+#if defined(DEV_AD7605_4)
+#define AD7606X_DEVICE_ID "<device id=\"AD7605-4-phy\" name=\"ID_AD7605-4-phy\" >"
+#elif defined(DEV_AD7606_4)
+#define AD7606X_DEVICE_ID "<device id=\"AD7606-4-phy\" name=\"AD7606-4-phy\" >"
+#elif defined(DEV_AD7606_6)
+#define AD7606X_DEVICE_ID "<device id=\"AD7606-6-phy\" name=\"AD7606-6-phy\" >"
+#elif defined(DEV_AD7606_8)
+#define AD7606X_DEVICE_ID "<device id=\"AD7606-8-phy\" name=\"AD7606-8-phy\" >"
+#elif defined(DEV_AD7606B)
+#define AD7606X_DEVICE_ID "<device id=\"AD7606B-phy\" name=\"AD7606B-phy\" >"
+#elif defined(DEV_AD7606C_16)
+#define AD7606X_DEVICE_ID "<device id=\"AD7606C-phy\" name=\"AD7606C-16-phy\" >"
+#elif defined(DEV_AD7606C_18)
+#define AD7606X_DEVICE_ID "<device id=\"AD7606C-phy\" name=\"AD7606C-18-phy\" >"
+#elif defined(DEV_AD7608)
+#define AD7606X_DEVICE_ID "<device id=\"AD7608-phy\" name=\"AD7608-phy\" >"
+#elif defined(DEV_AD7609)
+#define AD7606X_DEVICE_ID "<device id=\"AD7609-phy\" name=\"AD7609-phy\" >"
+#else
+#endif
+
+#define AD7606X_COMMON_ATTRB "<attribute name=\"raw\" />" \
+ "<attribute name=\"scale\" />"
+
+#if defined(DEV_AD7606B)
+#define AD7606X_CHANNELS_ATTRB "<attribute name=\"chn_range\" />" \
+ "<attribute name=\"chn_offset\" />" \
+ "<attribute name=\"Temperature\" />" \
+ "<attribute name=\"Vref\" />" \
+ "<attribute name=\"Vdrive\" />" \
+ "<attribute name=\"ALDO\" />" \
+ "<attribute name=\"DLDO\" />" \
+ "<attribute name=\"open_wire_detect_manual\" />" \
+ "<attribute name=\"open_wire_detect_auto\" />" \
+ "<attribute name=\"calibrate_adc_offset\" />" \
+ "<attribute name=\"calibrate_adc_gain\" />"
+#elif defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+#define AD7606X_CHANNELS_ATTRB "<attribute name=\"chn_range\" />" \
+ "<attribute name=\"chn_offset\" />" \
+ "<attribute name=\"Temperature\" />" \
+ "<attribute name=\"Vref\" />" \
+ "<attribute name=\"Vdrive\" />" \
+ "<attribute name=\"ALDO\" />" \
+ "<attribute name=\"DLDO\" />" \
+ "<attribute name=\"open_wire_detect_manual\" />" \
+ "<attribute name=\"open_wire_detect_auto\" />" \
+ "<attribute name=\"calibrate_adc_offset\" />" \
+ "<attribute name=\"calibrate_adc_gain\" />" \
+ "<attribute name=\"bandwidth\" />"
+#endif
+
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+#define AD7606X_GLOBAL_ATTRB "<attribute name=\"operating_mode\" />" \
+ "<attribute name=\"oversampling\" />" \
+ "<debug-attribute name =\"direct_reg_access\" />"
+#else
+#define AD7606X_GLOBAL_ATTRB "<attribute name=\"power_down_mode\" />" \
+ "<attribute name=\"range\" />"
+#endif
+
+
+// XML describes the IIO context hierarchy for AD7606 family devices
+static const char * const ad7606_phy_xml =
+ AD7606X_DEVICE_ID
+ "<channel id=\"voltage1\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"0\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"0\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+ "<channel id=\"voltage2\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"1\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"1\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+ "<channel id=\"voltage3\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"2\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"2\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+ "<channel id=\"voltage4\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"3\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"3\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+#if (AD7606X_ADC_CHANNELS > 4)
+ "<channel id=\"voltage5\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"4\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"4\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+ "<channel id=\"voltage6\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"5\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"5\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+#endif
+#if (AD7606X_ADC_CHANNELS > 6)
+ "<channel id=\"voltage7\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"6\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"6\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+ "<channel id=\"voltage8\" type=\"input\" >"
+#if (AD7606X_ADC_RESOLUTION == 18)
+ "<scan-element scale=\"0.1525\" format=\"le:s18/18>>0\" index = \"7\" />"
+#else
+ "<scan-element scale=\"0.1525\" format=\"le:s16/16>>0\" index = \"7\" />"
+#endif
+ AD7606X_COMMON_ATTRB
+ AD7606X_CHANNELS_ATTRB
+ "</channel>"
+#endif
+ AD7606X_GLOBAL_ATTRB
+ "</device>";
+
+
+/* Channels IIO attribute structures */
+
+static struct iio_attribute iio_attr_chn_scale = {
+ .name = "scale",
+ .show = get_chn_scale,
+ .store = set_chn_scale,
+};
+
+static struct iio_attribute iio_attr_chn_raw = {
+ .name = "raw",
+ .show = get_chn_raw,
+ .store = set_chn_raw,
+};
+
+static struct iio_attribute iio_attr_chn_range = {
+ .name = "chn_range",
+ .show = get_chn_range,
+ .store = set_chn_range,
+};
+
+static struct iio_attribute iio_attr_chn_offset = {
+ .name = "chn_offset",
+ .show = get_chn_offset,
+ .store = set_chn_offset,
+};
+
+static struct iio_attribute iio_attr_chn_phase_offset = {
+ .name = "chn_phase offset",
+ .show = get_chn_phase_offset,
+ .store = set_chn_phase_offset,
+};
+
+static struct iio_attribute iio_attr_chn_temperature = {
+ .name = "Temperature",
+ .show = get_chn_temperature,
+ .store = set_chn_temperature,
+};
+
+static struct iio_attribute iio_attr_chn_vref = {
+ .name = "Vref",
+ .show = get_chn_vref,
+ .store = set_chn_vref,
+};
+
+static struct iio_attribute iio_attr_chn_vdrive = {
+ .name = "Vdrive",
+ .show = get_chn_vdrive,
+ .store = set_chn_vdrive,
+};
+
+static struct iio_attribute iio_attr_chn_aldo = {
+ .name = "ALDO",
+ .show = get_chn_aldo,
+ .store = set_chn_aldo,
+};
+
+static struct iio_attribute iio_attr_chn_dldo = {
+ .name = "DLDO",
+ .show = get_chn_dldo,
+ .store = set_chn_dldo,
+};
+
+static struct iio_attribute iio_attr_bandwidth = {
+ .name = "bandwidth",
+ .show = get_bandwidth,
+ .store = set_bandwidth,
+};
+
+static struct iio_attribute iio_attr_chn_open_wire_detect_manual = {
+ .name = "open_wire_detect_manual",
+ .show = get_chn_open_wire_detect_manual,
+ .store = set_chn_open_wire_detect_manual,
+};
+
+static struct iio_attribute iio_attr_chn_open_wire_detect_auto = {
+ .name = "open_wire_detect_auto",
+ .show = get_chn_open_wire_detect_auto,
+ .store = set_chn_open_wire_detect_auto,
+};
+
+static struct iio_attribute iio_attr_calibrate_adc_offset= {
+ .name = "calibrate_adc_offset",
+ .show = get_chn_calibrate_adc_offset,
+ .store = set_chn_calibrate_adc_offset,
+};
+
+static struct iio_attribute iio_attr_calibrate_adc_gain = {
+ .name = "calibrate_adc_gain",
+ .show = get_chn_calibrate_adc_gain,
+ .store = set_chn_calibrate_adc_gain,
+};
+
+
+struct iio_attribute *channel_input_attributes[] = {
+ &iio_attr_chn_raw,
+ &iio_attr_chn_scale,
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+ &iio_attr_chn_range,
+ &iio_attr_chn_offset,
+ &iio_attr_chn_phase_offset,
+ &iio_attr_chn_temperature,
+ &iio_attr_chn_vref,
+ &iio_attr_chn_vdrive,
+ &iio_attr_chn_aldo,
+ &iio_attr_chn_dldo,
+ &iio_attr_chn_open_wire_detect_manual,
+ &iio_attr_chn_open_wire_detect_auto,
+ &iio_attr_calibrate_adc_offset,
+ &iio_attr_calibrate_adc_gain,
+#if defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+ &iio_attr_bandwidth
+#endif
+#endif
+};
+
+
+/* Device IIO attribute structures */
+
+static struct iio_attribute iio_attr_operating_mode = {
+ .name = "operating_mode",
+ .show = get_operating_mode,
+ .store = set_operating_mode,
+};
+
+static struct iio_attribute iio_attr_power_down_mode = {
+ .name = "power_down_mode",
+ .show = get_power_down_mode,
+ .store = set_power_down_mode,
+};
+
+static struct iio_attribute iio_attr_range = {
+ .name = "range",
+ .show = get_range,
+ .store = set_range,
+};
+
+static struct iio_attribute iio_attr_oversampling = {
+ .name = "oversampling",
+ .show = get_oversampling,
+ .store = set_oversampling,
+};
+
+static struct iio_attribute iio_attr_direct_reg_access = {
+ .name = "direct_reg_access",
+ .show = get_direct_reg_access,
+ .store = set_direct_reg_access,
+};
+
+static struct iio_attribute *global_attributes[] = {
+#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16)
+ &iio_attr_operating_mode,
+ &iio_attr_oversampling,
+ &iio_attr_direct_reg_access,
+#else
+ &iio_attr_power_down_mode,
+ &iio_attr_range,
+#endif
+};
+
+
+static struct iio_channel iio_channel_ch1_in = {
+ .name = "voltage1",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch2_in = {
+ .name = "voltage2",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch3_in = {
+ .name = "voltage3",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch4_in = {
+ .name = "voltage4",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch5_in = {
+ .name = "voltage5",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch6_in = {
+ .name = "voltage6",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch7_in = {
+ .name = "voltage7",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+static struct iio_channel iio_channel_ch8_in = {
+ .name = "voltage8",
+ .attributes = channel_input_attributes,
+ .ch_out = false,
+};
+
+
+static struct iio_channel *iio_ad7606_channels[] = {
+ &iio_channel_ch1_in,
+ &iio_channel_ch2_in,
+ &iio_channel_ch3_in,
+ &iio_channel_ch4_in,
+#if (AD7606X_ADC_CHANNELS > 4)
+ &iio_channel_ch5_in,
+ &iio_channel_ch6_in,
+#endif
+#if (AD7606X_ADC_CHANNELS > 6)
+ &iio_channel_ch7_in,
+ &iio_channel_ch8_in,
+#endif
+};
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+#endif /* IIO_AD7606_ATTR_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/iio_transport.c Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,184 @@
+/***************************************************************************//**
+ * @file iio_transport.c
+ * @brief Implementation of iio transport layer interface for AD7606
+********************************************************************************
+ * Copyright (c) 2020 Analog Devices, Inc.
+ *
+ * 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 "iio_transport.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definition ***********************/
+/******************************************************************************/
+
+/* Max buffer length to hold IIO client data/command */
+#define IIO_CMD_DATA_BUFF_SIZE (100)
+
+/******************************************************************************/
+/*************************** Types Declarations *******************************/
+/******************************************************************************/
+
+/* UART descriptor to read/write UART peripheral data */
+static struct uart_desc *uart_desc = NULL;
+
+/* IIO command buffer */
+static volatile char iio_cmd_buffer[IIO_CMD_DATA_BUFF_SIZE];
+
+/* IIO data buffer */
+static volatile char iio_data_buffer[IIO_CMD_DATA_BUFF_SIZE];
+
+/* New IIO command detect flag */
+static volatile bool new_iio_cmd_detected = false;
+
+/* Data buffer index */
+volatile static uint8_t data_buff_indx = 0;
+
+/* Command buffer index */
+volatile static uint8_t cmd_buff_indx = 0;
+
+/******************************************************************************/
+/************************ Functions Declarations ******************************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/**
+ * @brief IIO Wrapper to initialize the UART peripheral
+ * @param desc- Pointer UART descriptor structure
+ * @param param- Pointer to UART init param structure
+ * @return uart init status (SUCCESS/FAILURE)
+ */
+int32_t iio_uart_init(struct uart_desc **desc, struct uart_init_param *param)
+{
+ if (uart_init(desc, param) == SUCCESS) {
+ /* Save the descriptor for data read/write operation */
+ uart_desc = *desc;
+
+ return SUCCESS;
+ } else {
+ return FAILURE;
+ }
+}
+
+
+/**
+ * @brief IIO Wrapper to wrire data to UART peripheral
+ * @param buf- Pointer to buffer containing data
+ * @param len- Number of bytes to write
+ * @return bytes len in case of success, 0 otherwise
+ */
+ssize_t iio_uart_write(const char *buf, size_t len)
+{
+ if (uart_write(uart_desc, (uint8_t *)buf, len) == SUCCESS) {
+ return len;
+ } else {
+ return 0;
+ }
+}
+
+
+/**
+ * @brief IIO Wrapper to read iio data/command from UART peripheral
+ * @param buf- Pointer to buffer containing data
+ * @param len- Number of bytes to read
+ * @return bytes len in case of success, 0 otherwise
+ */
+ssize_t iio_uart_read(char *buf, size_t len)
+{
+ size_t i = 0;
+
+ if (len > 1) {
+ do {
+ /* Wait until new data of expected length is received
+ * from UART Rx interrupt event */
+ } while (data_buff_indx < len);
+
+ /* Get the data into local buffer (entire data) */
+ while (i < len) {
+ buf[i] = iio_data_buffer[i];
+ i++;
+ }
+ data_buff_indx = 0;
+ } else {
+ /* Get the iio command into local buffer (1 character at a time) */
+ buf[i] = iio_cmd_buffer[cmd_buff_indx];
+
+ /* Reset buffer index after reading whole command */
+ if (iio_cmd_buffer[cmd_buff_indx] == '\n') {
+ cmd_buff_indx = 0;
+ } else {
+ cmd_buff_indx++;
+ }
+ }
+
+ return len;
+}
+
+
+/*!
+ * @brief Callback function to receive IIO command
+ * @return None
+ * @details This function is an UART Rx ISR registered by IIO application
+ * to invoke upon receipt og new character over UART link.
+ */
+void iio_uart_rx_callback(void)
+{
+ uint8_t rx_char;
+
+ if (uart_read(uart_desc, &rx_char, 1) == SUCCESS) {
+
+ iio_data_buffer[data_buff_indx++] = rx_char;
+
+ if (rx_char == '\n') {
+ /* The iio command is identified with new line character */
+ memcpy(iio_cmd_buffer, iio_data_buffer, data_buff_indx);
+ data_buff_indx = 0;
+ new_iio_cmd_detected = true;
+ }
+ }
+}
+
+
+/*!
+ * @brief Function to check for newer IIO command
+ * @return IIO command status (true/false)
+ */
+bool is_new_iio_command_detected(void)
+{
+ if (new_iio_cmd_detected) {
+ new_iio_cmd_detected = false;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+
+/*!
+ * @brief Function to check for expected IIO command
+ * @param cmd_str[in] - Expected IIO command string
+ * @param len[in] - Length of IIO command
+ * @return IIO command status (true/false)
+ */
+bool check_iio_cmd(const char *cmd_str, uint8_t len)
+{
+ int ret;
+
+ ret = strncmp(cmd_str, iio_cmd_buffer, len);
+ if (ret == 0) {
+ /* String matches, return true */
+ return true;
+ }
+
+ return false;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/iio_transport.h Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,56 @@ +/***************************************************************************//** + * @file iio_transport.h + * @brief Header file of iio_transport. + * @author +******************************************************************************** + * Copyright (c) 2020 Analog Devices, Inc. + * + * 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. +*******************************************************************************/ + +#ifndef IIO_TRANSPORT_H_ +#define IIO_TRANSPORT_H_ + +/******************************************************************************/ +/***************************** Include Files **********************************/ +/******************************************************************************/ + +#include "iio.h" +#include "platform_drivers.h" + +/******************************************************************************/ +/********************** Macros and Constants Definition ***********************/ +/******************************************************************************/ + +/* Baud rate for IIO UART interface */ +#define IIO_UART_BAUD_RATE (230400U) + +/******************************************************************************/ +/*************************** Types Declarations *******************************/ +/******************************************************************************/ + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +/* UART peripheral init wrapper */ +int32_t iio_uart_init(struct uart_desc **desc, struct uart_init_param *param); + +/* UART data write wrapper */ +ssize_t iio_uart_write(const char *buf, size_t len); + +/* UART data read wrapper */ +ssize_t iio_uart_read(char *buf, size_t len); + +/* IIO command detect monitor */ +bool is_new_iio_command_detected(void); + +/* Check for specific IIO command */ +bool check_iio_cmd(const char *cmd_str, uint8_t len); + +/* IIO UART receive interrupt callback function */ +void iio_uart_rx_callback(void); + +#endif /* IIO_TRANSPORT_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/app/main.c Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,50 @@
+/***************************************************************************//**
+ * @file main.c
+ * @brief Main module for AD7606 IIO application
+ * @details This module invokes the AD7606 IIO interfaces
+ * through forever loop.
+********************************************************************************
+ * 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 <stdio.h>
+#include <stdint.h>
+#include <assert.h>
+
+#include "platform_support.h"
+#include "iio_ad7606.h"
+#include "error.h"
+
+/******************************************************************************/
+/********************** Macros and Constants Definitions **********************/
+/******************************************************************************/
+
+/******************************************************************************/
+/************************ Functions Definitions *******************************/
+/******************************************************************************/
+
+/**
+ * @brief Main entry point to application
+ * @return none
+ */
+int main(void)
+{
+ /* Initialize the AD7606 IIO interface */
+ if (ad7606_iio_initialize() == FAILURE) {
+ assert(false);
+ }
+
+ while (1) {
+ /* Monitor the IIO client events */
+ ad7606_iio_event_handler();
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iio.lib Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/AnalogDevices/code/iio/ \ No newline at end of file
--- a/main.cpp Thu Aug 06 19:49:32 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/* Copyright (c) 2019 Analog Devices, Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
- - Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- - Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
- - Modified versions of the software must be conspicuously marked as such.
- - This software is licensed solely and exclusively for use with processors/products
- manufactured by or for Analog Devices, Inc.
- - This software may not be combined or merged with other code in any manner
- that would cause the software to become subject to terms and conditions which
- differ from those listed here.
- - Neither the name of Analog Devices, Inc. nor the names of its contributors
- may be used to endorse or promote products derived from this software without
- specific prior written permission.
- - The use of this software ma y or may not infringe the patent rights of one or
- more patent holders. This license does not release you from the requirement
- that you obtain separate licenses from these patent holders to use this software.
-
-THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, NON-INFRINGEMENT,
-TITLE, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
-NO EVENT SHALL ANALOG DEVICES, INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF INTELLECTUAL
-PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
-OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
-EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-2019-01-10-7CBSD SLA
-
-*/
-
-/***Libraries***/
-#include <stdio.h> /*Standard Library*/
-#include "mbed.h" /*mbed header file*/
-
-/***Defines for UART Protocol***/
-#define BAUD_RATE 115200 /*Baud Rate*/
-
-/*Configure and instantiate UART protocol
- and baud rate*/
-Serial port(USBTX, USBRX, BAUD_RATE);
-
-/***Function Declarations***/
-
-/*Print Information about Program's purpose*/
-static void print_title(void);
-
-/*Print Instructions on how to use Program*/
-static void print_prompt(void);
-
-int main()
-{
- uint8_t user_command; /*User input variable*/
- uint8_t connected = 1; /*Initialize SPI*/
-
- print_title();
-
- while(connected == 1) {
- print_prompt();
- port.scanf("%2d", (int *) &user_command);
- switch (user_command) {
- case 1:
- port.printf("Case 1\n\n");
- break;
-
- case 2:
- port.printf("Case 2\n\n");
- //menu_item_1_conversion_read(dev);
- break;
-
- default:
- port.printf(" ***Illegal Entry****\n\n");
- break;
-
- }
- }
- return 0;
-}
-
-/***Function Definitions***/
-
-
-/*Function to print the title block when program first starts.
- Parameters: None
- Return Value: None*/
-void print_title()
-{
- port.printf("\n*****************************************************************\n");
- port.printf("* EVAL-AD1234 Demonstration Program *\n");
- port.printf("* *\n");
- port.printf("* This program demonstrates how to measure strain gauge or *\n");
- port.printf("* other form of a Wheatstone bridge sensors with the AD1234 *\n");
- port.printf("* *\n");
- port.printf("* *\n");
- port.printf("* Set the baud rate to 115200 and select the newline terminator.*\n");
- port.printf("* *\n");
- port.printf("*****************************************************************\n");
-}
-
-/*Function to Print Command Summary
- Parameters: None
- Return Value: None */
-static void print_prompt() {
- port.printf("Command Summary\n");
- port.printf(" 1 - Select ADC\n");
- port.printf(" 2 - Select Power Mode\n");
- port.printf(" x - Put More Menu Items Here\n");
-}
-
-void menu_1_function1()
-{
- port.printf("In function 1\n");
-}
-
-void menu_2_function2()
-{
- port.printf("In function 2\n");
-}
-
--- a/mbed-os.lib Thu Aug 06 19:49:32 2020 +0000 +++ b/mbed-os.lib Mon Oct 05 13:45:15 2020 +0530 @@ -1,1 +1,1 @@ -https://github.com/ARMmbed/mbed-os/#3a57ec7401a77b8b98f6356a1498cb154229483f +https://github.com/ARMmbed/mbed-os/#a6207cadad0acd1876f436dc6baeddf46c42af06
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_app.json Mon Oct 05 13:45:15 2020 +0530
@@ -0,0 +1,9 @@
+{
+ "requires": ["bare-metal"],
+ "target_overrides": {
+ "*": {
+ "platform.default-serial-baud-rate": 115200,
+ "target.printf_lib": "std"
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform_drivers.lib Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/AnalogDevices/code/platform_drivers/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tinyiiod.lib Mon Oct 05 13:45:15 2020 +0530 @@ -0,0 +1,1 @@ +https://os.mbed.com/teams/AnalogDevices/code/Tinyiiod/ \ No newline at end of file