Example Program for EVAL-AD7606
Dependencies: platform_drivers
Diff: app/iio_ad7606.c
- Revision:
- 6:32de160dce43
- Parent:
- 3:83b3133f544a
- Child:
- 7:054dbd5e1f45
--- a/app/iio_ad7606.c Mon Oct 19 07:54:56 2020 +0000 +++ b/app/iio_ad7606.c Wed Jul 21 11:16:56 2021 +0100 @@ -3,7 +3,7 @@ * @brief Implementation of AD7606 IIO application interfaces * @details This module acts as an interface for AD7606 IIO application ******************************************************************************** - * Copyright (c) 2020 Analog Devices, Inc. + * Copyright (c) 2020-2021 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 @@ -20,18 +20,13 @@ #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 "error.h" #include "ad7606.h" #include "ad7606_data_capture.h" @@ -73,21 +68,12 @@ #define OFFSET_REG_RESOLUTION 1 #endif -/* Default sampling frequency for AD7606 (in SPS) to define IIO client timeout period. - * Note: The actual sampling frequncy is much higher (~30KSPS per channel), however the - * data transmission back to IIO client is limited by the serial (UART) link, which - * can provide max transmission rate of ~3-4KSPS. Hence sampling frequency is set to 1Khz - * for safer side */ -#define AD7606_DEFLT_SAMPLING_FREQEUNCY (1000) - /******************************************************************************/ /*************************** Types Declarations *******************************/ /******************************************************************************/ -/** -* IIO application instance descriptor. -*/ -static struct iio_app_desc *iio_app_desc; +/* IIO interface descriptor */ +static struct iio_desc *p_ad7606_iio_desc; /** * Device name. @@ -97,7 +83,7 @@ /** * Pointer to the struct representing the AD7606 IIO device */ -static struct ad7606_dev *p_ad7606_dev = NULL; +static struct ad7606_dev *p_ad7606_dev_inst = NULL; /* Device attributes with default values */ @@ -188,14 +174,8 @@ 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; +static bool adc_data_capture_started = false; /* Gain calibration status */ static bool gain_calibration_done = false; @@ -205,9 +185,6 @@ static bool open_circuit_detection_error = false; static bool open_circuit_detect_read_done = false; -/* Sampling frequency of device */ -static uint16_t sampling_frequency = AD7606_DEFLT_SAMPLING_FREQEUNCY; - /******************************************************************************/ /************************ Functions Prototypes ********************************/ /******************************************************************************/ @@ -227,25 +204,27 @@ * @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) +static ssize_t get_chn_scale(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { - return (ssize_t) sprintf(buf, "%f", attr_scale_val[channel->ch_num - 1]); + return (ssize_t) sprintf(buf, "%f", attr_scale_val[channel->ch_num]); } -ssize_t set_chn_scale(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_scale(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { float scale; (void)sscanf(buf, "%f", &scale); if (scale > 0.0) { - attr_scale_val[channel->ch_num - 1] = scale; + attr_scale_val[channel->ch_num] = scale; return len; } @@ -266,18 +245,20 @@ * e.g. if sampling frequency = 1KSPS and requested samples = 400 * Timeout = (400 * 0.001) + 1 = 1.4sec */ -ssize_t get_sampling_frequency(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t get_sampling_frequency(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { - return (ssize_t) sprintf(buf, "%d", sampling_frequency); + return (ssize_t) sprintf(buf, "%d", SAMPLING_RATE); } -ssize_t set_sampling_frequency(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_sampling_frequency(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { /* NA- Can't set sampling frequency value */ return len; @@ -292,24 +273,26 @@ * @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) +static ssize_t get_chn_raw(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { 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]); + adc_data_raw = single_data_read(device, channel->ch_num, + attr_polarity_val[channel->ch_num]); 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) +static ssize_t set_chn_raw(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { /* NA- Can't set raw value */ return len; @@ -325,10 +308,11 @@ * @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) +static ssize_t get_operating_mode(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t read_val; uint8_t operating_mode_value; @@ -345,10 +329,11 @@ return -EINVAL; } -ssize_t set_operating_mode(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_operating_mode(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t operating_mode_value; @@ -377,10 +362,11 @@ * @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) +static ssize_t get_power_down_mode(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t gpio_stby_val; uint8_t gpio_range_val; @@ -405,10 +391,11 @@ return -EINVAL; } -ssize_t set_power_down_mode(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_power_down_mode(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t power_down_mode_value; static enum ad7606_op_mode prev_power_down_mode = AD7606_NORMAL; @@ -478,10 +465,11 @@ * @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) +static ssize_t get_range(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t gpio_range_val; struct ad7606_dev *dev = device; @@ -497,10 +485,11 @@ return -EINVAL; } -ssize_t set_range(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_range(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t range_value; struct ad7606_dev *dev = device; @@ -532,10 +521,11 @@ * @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) +static ssize_t get_oversampling(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t oversampling_value; uint8_t read_val; @@ -574,10 +564,11 @@ return -EINVAL; } -ssize_t set_oversampling(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_oversampling(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t oversampling_value; struct ad7606_oversampling oversampling_cfg; @@ -608,10 +599,11 @@ * @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) +static ssize_t get_bandwidth(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t bw_value; uint8_t read_val; @@ -619,7 +611,7 @@ if (ad7606_spi_reg_read(device, AD7606_REG_BANDWIDTH, &read_val) == SUCCESS) { - bw_value = (read_val >> (channel->ch_num - 1)) & 0x1; + bw_value = (read_val >> (channel->ch_num)) & 0x1; if (bw_value < sizeof(bandwidth_str) / sizeof( bandwidth_str[0])) { @@ -630,10 +622,11 @@ return -EINVAL; } -ssize_t set_bandwidth(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_bandwidth(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t bw_value; uint8_t read_val; @@ -646,9 +639,9 @@ AD7606_REG_BANDWIDTH, &read_val) == SUCCESS) { if (bw_value) { - read_val |= (1 << (channel->ch_num - 1)); + read_val |= (1 << (channel->ch_num)); } else { - read_val &= (~(1 << (channel->ch_num - 1))); + read_val &= (~(1 << (channel->ch_num))); } if (ad7606_spi_reg_write(device, @@ -672,26 +665,27 @@ * @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) +static ssize_t get_chn_range(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t read_val; uint8_t chn_range; - if (ad7606_spi_reg_read(device, AD7606_REG_RANGE_CH_ADDR(channel->ch_num-1), + if (ad7606_spi_reg_read(device, AD7606_REG_RANGE_CH_ADDR(channel->ch_num), &read_val) == SUCCESS) { - if (((channel->ch_num - 1) % 2) != 0) { + if (((channel->ch_num) % 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)); + chn_range = (read_val & AD7606_RANGE_CH_MSK(channel->ch_num)); } 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); + attr_chn_range[channel->ch_num] = chn_range_val[chn_range]; + attr_polarity_val[channel->ch_num] = ad7606_get_input_polarity(chn_range); return (ssize_t)sprintf(buf, "%s", chn_range_str[chn_range]); } @@ -700,10 +694,11 @@ return -EINVAL; } -ssize_t set_chn_range(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_range(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t chn_range; @@ -712,20 +707,20 @@ 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_polarity_val[channel->ch_num] = 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( + attr_chn_range[channel->ch_num] = chn_range_val[chn_range]; + attr_scale_val[channel->ch_num] = get_vltg_conv_scale_factor( chn_range_val[chn_range], - attr_polarity_val[channel->ch_num - 1]); + attr_polarity_val[channel->ch_num]); - if (((channel->ch_num - 1) % 2) != 0) { + if (((channel->ch_num) % 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), + AD7606_REG_RANGE_CH_ADDR(channel->ch_num), + AD7606_RANGE_CH_MSK(channel->ch_num), chn_range) == SUCCESS) { return len; } @@ -744,14 +739,15 @@ * @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) +static ssize_t get_chn_offset(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t chn_offset_value; - if (ad7606_spi_reg_read(device, AD7606_REG_OFFSET_CH(channel->ch_num-1), + if (ad7606_spi_reg_read(device, AD7606_REG_OFFSET_CH(channel->ch_num), &chn_offset_value) == SUCCESS) { return (ssize_t)sprintf(buf, "%d", chn_offset_value); } @@ -759,16 +755,17 @@ return -EINVAL; } -ssize_t set_chn_offset(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_offset(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t chn_offset_value = 0; (void)sscanf(buf, "%d", &chn_offset_value); - if (ad7606_set_ch_offset(device, channel->ch_num - 1, + if (ad7606_set_ch_offset(device, channel->ch_num, chn_offset_value) == SUCCESS) { return len; } @@ -786,15 +783,16 @@ * @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) +static ssize_t get_chn_phase_offset(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t chn_phase_offset_value; if (ad7606_spi_reg_read(device, - AD7606_REG_PHASE_CH(channel->ch_num - 1), + AD7606_REG_PHASE_CH(channel->ch_num), &chn_phase_offset_value) == SUCCESS) { return (ssize_t)sprintf(buf, "%d", chn_phase_offset_value); } @@ -802,16 +800,17 @@ return -EINVAL; } -ssize_t set_chn_phase_offset(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_phase_offset(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { 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, + if (ad7606_set_ch_phase(device, channel->ch_num, chn_phase_offset_value) == SUCCESS) { return len; } @@ -829,10 +828,11 @@ * @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) +static ssize_t get_chn_temperature(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { int32_t adc_chn_data = 0; float temperature; @@ -840,30 +840,30 @@ /* 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), 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]); + adc_chn_data = single_data_read(device, channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Convert ADC data into equivalent voltage */ voltage = convert_adc_raw_to_voltage(adc_chn_data, - attr_scale_val[channel->ch_num - 1]); + attr_scale_val[channel->ch_num]); /* 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), ANALOG_INPUT_MUX)); return (ssize_t)sprintf(buf, "%f", temperature); @@ -872,10 +872,11 @@ return -EINVAL; } -ssize_t set_chn_temperature(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_temperature(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set temperature return -EINVAL; @@ -891,40 +892,41 @@ * @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) +static ssize_t get_chn_vref(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), 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]); + adc_chn_data = single_data_read(device, channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Convert ADC data into equivalent voltage */ vref_voltge = convert_adc_raw_to_voltage(adc_chn_data, - attr_scale_val[channel->ch_num - 1]); + attr_scale_val[channel->ch_num]); /* 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), ANALOG_INPUT_MUX)); return (ssize_t)sprintf(buf, "%f", vref_voltge); @@ -933,10 +935,11 @@ return -EINVAL; } -ssize_t set_chn_vref(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_vref(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set Vref return - EINVAL; @@ -952,37 +955,38 @@ * @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) +static ssize_t get_chn_vdrive(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), 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]); + adc_chn_data = single_data_read(device, channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Convert ADC data into equivalent voltage */ vdrive_voltge = convert_adc_raw_to_voltage(adc_chn_data, - attr_scale_val[channel->ch_num - 1]); + attr_scale_val[channel->ch_num]); /* 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), ANALOG_INPUT_MUX)); return (ssize_t)sprintf(buf, "%f", vdrive_voltge); @@ -991,10 +995,11 @@ return -EINVAL; } -ssize_t set_chn_vdrive(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_vdrive(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set Vdrive return - EINVAL; @@ -1010,40 +1015,41 @@ * @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) +static ssize_t get_chn_aldo(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), 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]); + adc_chn_data = single_data_read(device, channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Convert ADC data into equivalent voltage */ aldo_voltge = convert_adc_raw_to_voltage(adc_chn_data, - attr_scale_val[channel->ch_num - 1]); + attr_scale_val[channel->ch_num]); /* 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), ANALOG_INPUT_MUX)); return (ssize_t)sprintf(buf, "%f", aldo_voltge); @@ -1052,10 +1058,11 @@ return -EINVAL; } -ssize_t set_chn_aldo(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_aldo(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set ALDO return - EINVAL; @@ -1071,19 +1078,20 @@ * @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) +static ssize_t get_chn_dldo(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), DLDO_MUX)) == SUCCESS) { /* Allow to settle Mux channel */ @@ -1091,21 +1099,21 @@ /* 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]); + channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Convert ADC data into equivalent voltage */ dldo_voltge = convert_adc_raw_to_voltage(adc_chn_data, - attr_scale_val[channel->ch_num - 1]); + attr_scale_val[channel->ch_num]); /* 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), + AD7606_REG_DIAGNOSTIC_MUX_CH(channel->ch_num), + AD7606_DIAGN_MUX_CH_MSK(channel->ch_num), + AD7606_DIAGN_MUX_CH_VAL((channel->ch_num), ANALOG_INPUT_MUX)); return (ssize_t)sprintf(buf, "%f", dldo_voltge); @@ -1114,10 +1122,11 @@ return -EINVAL; } -ssize_t set_chn_dldo(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_dldo(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set DLDO return - EINVAL; @@ -1132,10 +1141,11 @@ * @param channel- pointer to IIO channel structure * @return Number of characters read/written */ -ssize_t get_chn_open_circuit_detect_manual(void *device, +static ssize_t get_chn_open_circuit_detect_manual(void *device, char *buf, size_t len, - const struct iio_ch_info *channel) + const struct iio_ch_info *channel, + intptr_t id) { int32_t prev_adc_code, curr_adc_code; bool open_detect_flag = false; @@ -1147,8 +1157,8 @@ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 1) == SUCCESS) { /* Read the ADC on selected chnnel (first reading post open circuit detection start) */ prev_adc_code = single_data_read(device, - channel->ch_num - 1, - attr_polarity_val[channel->ch_num - 1]); + channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Perform N conversions and monitor the code delta */ for (cnt = 0; cnt < MANUAL_OPEN_DETECT_CONV_CNTS; cnt++) { @@ -1156,8 +1166,8 @@ if (prev_adc_code >= 0 && prev_adc_code < MANUAL_OPEN_DETECT_ENTRY_TRHLD) { /* Perform next conversion and read the result */ curr_adc_code = single_data_read(device, - channel->ch_num - 1, - attr_polarity_val[channel->ch_num - 1]); + channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Check if delta b/w current and previus reading is within 10 LSB code */ if (abs(curr_adc_code - prev_adc_code) > MANUAL_OPEN_DETECT_CONV_TRSHLD) { @@ -1180,14 +1190,14 @@ /* Set common mode high (enabling open circuit detect on selected channel) */ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_ENABLE, - (1 << ((channel->ch_num) - 1))) == SUCCESS) { + (1 << (channel->ch_num))) == SUCCESS) { /* Perform next conversions (~2-3) and read the result (with common mode set high) */ for (cnt = 0; cnt < MANUAL_OPEN_DETECT_CM_CNV_CNT; cnt++) { udelay(100); curr_adc_code = single_data_read(device, - channel->ch_num - 1, - attr_polarity_val[channel->ch_num - 1]); + channel->ch_num, + attr_polarity_val[channel->ch_num]); } /* Check if delta b/w common mode high code and previous N conversion code is > threshold */ @@ -1209,8 +1219,8 @@ 0) == SUCCESS) { /* Perform next conversion and read the result (with common mode set low) */ curr_adc_code = single_data_read(device, - channel->ch_num - 1, - attr_polarity_val[channel->ch_num - 1]); + channel->ch_num, + attr_polarity_val[channel->ch_num]); /* Check if delta b/w common mode low code and previous N conversion code is < threshold */ if (abs(curr_adc_code - prev_adc_code) < MANUAL_OPEN_DETECT_THRESHOLD_RPD50K) { @@ -1241,10 +1251,11 @@ return -EINVAL; } -ssize_t set_chn_open_circuit_detect_manual(void *device, +static ssize_t set_chn_open_circuit_detect_manual(void *device, char *buf, size_t len, - const struct iio_ch_info *channel) + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set open circuit detect return - EINVAL; @@ -1259,10 +1270,11 @@ * @param channel- pointer to IIO channel structure * @return Number of characters read/written */ -ssize_t get_chn_open_circuit_detect_auto(void *device, +static ssize_t get_chn_open_circuit_detect_auto(void *device, char *buf, size_t len, - const struct iio_ch_info *channel) + const struct iio_ch_info *channel, + intptr_t id) { if (open_circuit_detect_read_done) { open_circuit_detect_read_done = false; @@ -1281,13 +1293,14 @@ } return (ssize_t)sprintf(buf, "OPEN_DETECT_QUEUE: %d", - open_detect_queue_cnts[channel->ch_num - 1]); + open_detect_queue_cnts[channel->ch_num]); } -ssize_t set_chn_open_circuit_detect_auto(void *device, +static ssize_t set_chn_open_circuit_detect_auto(void *device, char *buf, size_t len, - const struct iio_ch_info *channel) + const struct iio_ch_info *channel, + intptr_t id) { uint8_t data; uint8_t open_detect_flag = false; @@ -1299,21 +1312,21 @@ if ((data > 1 && data <= AUTO_OPEN_DETECT_QUEUE_MAX_CNT) && (buf[0] >= '0' && buf[0] <= '9')) { - open_detect_queue_cnts[channel->ch_num - 1] = data; + open_detect_queue_cnts[channel->ch_num] = data; /* Enter into open circuit auto open detect mode */ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, - open_detect_queue_cnts[channel->ch_num - 1]) == SUCCESS) { + open_detect_queue_cnts[channel->ch_num]) == SUCCESS) { /* Enable open circuit detection on selected channel */ if (ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_ENABLE, - (1 << ((channel->ch_num) - 1))) == SUCCESS) { + (1 << (channel->ch_num))) == SUCCESS) { /* Monitor the open detect flag for max N+15 (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 < (open_detect_queue_cnts[channel->ch_num] + AUTO_OPEN_DETECT_QUEUE_EXTRA_CONV_CNT); conv_cnts++) { if (ad7606_convst(device) == SUCCESS) { @@ -1323,7 +1336,7 @@ if (ad7606_spi_reg_read(device, AD7606_REG_OPEN_DETECTED, &open_detect_flag) == SUCCESS) { - open_detect_flag >>= (channel->ch_num - 1); + open_detect_flag >>= (channel->ch_num); open_detect_flag &= 0x1; rw_status = SUCCESS; @@ -1346,7 +1359,7 @@ (void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECT_QUEUE, 0); (void)ad7606_spi_reg_write(device, AD7606_REG_OPEN_DETECTED, 0xFF); - open_detect_queue_cnts[channel->ch_num - 1] = 0; + open_detect_queue_cnts[channel->ch_num] = 0; if (rw_status == SUCCESS) { if (open_detect_flag) { @@ -1373,37 +1386,38 @@ * @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) +static ssize_t get_chn_calibrate_adc_offset(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { float lsb_voltage; float adc_voltage; - polarity_e polarity = attr_polarity_val[channel->ch_num - 1]; + polarity_e polarity = attr_polarity_val[channel->ch_num]; 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; + lsb_voltage = attr_chn_range[channel->ch_num] / ADC_MAX_COUNT_UNIPOLAR; } else { - lsb_voltage = attr_chn_range[channel->ch_num - 1] / ADC_MAX_COUNT_BIPOLAR; + lsb_voltage = attr_chn_range[channel->ch_num] / ADC_MAX_COUNT_BIPOLAR; } /* Sample and read the ADC channel */ - adc_data = single_data_read(device, channel->ch_num - 1, + adc_data = single_data_read(device, channel->ch_num, polarity); /* Get an equivalent ADC voltage */ adc_voltage = convert_adc_raw_to_voltage(adc_data, - attr_scale_val[channel->ch_num - 1]); + attr_scale_val[channel->ch_num]); /* Calculate the channel offset and write it to offset register */ chn_offset = -(adc_voltage / lsb_voltage / OFFSET_REG_RESOLUTION); - if (ad7606_set_ch_offset(device, channel->ch_num - 1, + if (ad7606_set_ch_offset(device, channel->ch_num, chn_offset) == SUCCESS) { return sprintf(buf, "%s", "ADC Calibration Done"); } @@ -1411,10 +1425,11 @@ return -EINVAL; } -ssize_t set_chn_calibrate_adc_offset(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_calibrate_adc_offset(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { // NA- Can't set open circuit detect return - EINVAL; @@ -1429,10 +1444,11 @@ * @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) +static ssize_t get_chn_calibrate_adc_gain(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { uint8_t read_val; @@ -1440,25 +1456,26 @@ /* Get calibration status for previous gain value write event */ gain_calibration_done = false; return sprintf(buf, "Calibration Done (Rfilter=%d K)", - gain_calibration_reg_val[channel->ch_num - 1]); + gain_calibration_reg_val[channel->ch_num]); } /* Return gain value when normal read event is triggered */ if (ad7606_spi_reg_read(device, - AD7606_REG_GAIN_CH(channel->ch_num - 1), + AD7606_REG_GAIN_CH(channel->ch_num), &read_val) == SUCCESS) { - gain_calibration_reg_val[channel->ch_num - 1] = (read_val & AD7606_GAIN_MSK); + gain_calibration_reg_val[channel->ch_num] = (read_val & AD7606_GAIN_MSK); return sprintf(buf, "Rfilter= %d K", - gain_calibration_reg_val[channel->ch_num - 1]); + gain_calibration_reg_val[channel->ch_num]); } return -EINVAL; } -ssize_t set_chn_calibrate_adc_gain(void *device, - char *buf, - size_t len, - const struct iio_ch_info *channel) +static ssize_t set_chn_calibrate_adc_gain(void *device, + char *buf, + size_t len, + const struct iio_ch_info *channel, + intptr_t id) { float data; @@ -1467,12 +1484,12 @@ if (data >= 0 && data < ADC_CALIBRATION_GAIN_MAX) { /* Get the nearest value of unsigned integer */ - gain_calibration_reg_val[channel->ch_num - 1] = (uint8_t)(round(data)); + gain_calibration_reg_val[channel->ch_num] = (uint8_t)(round(data)); /* Perform the gain calibration by writing gain value into gain register */ if (ad7606_set_ch_gain(device, - channel->ch_num - 1, - gain_calibration_reg_val[channel->ch_num - 1]) == SUCCESS) { + channel->ch_num, + gain_calibration_reg_val[channel->ch_num]) == SUCCESS) { gain_calibration_done = true; return len; } @@ -1484,79 +1501,42 @@ /*! - * @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 + * @brief Read the debug register value + * @param dev- Pointer to IIO device instance + * @param reg- Register address to read from + * @param readval- Pointer to variable to read data into + * @return SUCCESS in case of success, negative value otherwise */ -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) +int32_t debug_reg_read(void *dev, uint32_t reg, uint32_t *readval) { - 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; + /* Read the data from device */ + if (reg <= NUM_OF_REGISTERS) { + if ((ad7606_spi_reg_read(dev, reg, (uint8_t *)readval) == SUCCESS)) { + return SUCCESS; } } - return -EINVAL; + return FAILURE; } -/** - * @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. +/*! + * @brief Write into the debug register + * @param dev- Pointer to IIO device instance + * @param reg- Register address to write into + * @param writeval- Register value to write + * @return SUCCESS in case of success, negative value otherwise */ -static ssize_t iio_ad7606_get_xml(char **xml, struct iio_device *iio_dev) +int32_t debug_reg_write(void *dev, uint32_t reg, uint32_t writeval) { - *xml = (char*)calloc(1, strlen(ad7606_phy_xml) + 1); - if (!(*xml)) { - return -ENOMEM; + if (reg <= NUM_OF_REGISTERS) { + if ((ad7606_spi_reg_write(dev, reg, (uint8_t)writeval) == SUCCESS)) { + save_local_attributes(); + return SUCCESS; + } } - memcpy(*xml, ad7606_phy_xml, strlen(ad7606_phy_xml)); - - return SUCCESS; + return FAILURE; } @@ -1572,9 +1552,9 @@ size_t bytes_count, uint32_t ch_mask) { - if (adc_background_data_capture_started == false) { + if (adc_data_capture_started == false) { start_background_data_capture(ch_mask, bytes_count); - adc_background_data_capture_started = true; + adc_data_capture_started = true; } /* Read the buffered data */ @@ -1583,60 +1563,287 @@ /** - * @brief Read requested samples count + * @brief Transfer the device data into memory (optional) * @param dev_instance[in] - IIO device instance - * @param pbuf[out] - Pointer to output data buffer + * @param bytes_count[in] - Number of bytes to read + * @param ch_mask[in] - Channels select mask * @return SUCCESS in case of success or negative value otherwise */ -static ssize_t iio_ad7606_get_samples_count(void *dev_instance, +static ssize_t iio_ad7606_transfer_dev_data(void *dev_instance, size_t bytes_count, uint32_t ch_mask) { + /* The function insures that data is first read into memory from the device. + * This function doesn't do any sort of data transfer but it make sure data + * read and it's transfer to memory from device is happening in application through + * iio_ad7606_read_data() function */ + + /* Store the requested samples count value for data capture */ store_requested_samples_count(bytes_count); + + return SUCCESS; +} + + +/** + * @brief Perform tasks before new data transfer + * @param dev_instance[in] - IIO device instance + * @param ch_mask[in] - Channels select mask + * @return SUCCESS in case of success or negative value otherwise + */ +static int32_t iio_ad7606_start_transfer(void *dev_instance, uint32_t ch_mask) +{ 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 + * @brief Perform tasks before end of current data transfer + * @param dev_instance[in] - IIO device instance * @return SUCCESS in case of success or negative value otherwise */ -static ssize_t iio_ad7606_delete_device(struct iio_device *iio_device) +static int32_t iio_ad7606_stop_transfer(void *dev) { - if (!iio_device) { - return FAILURE; - } - - free(iio_device); + adc_data_capture_started = false; + stop_background_data_capture(); return SUCCESS; } +/********************************************************* + * IIO Attributes and Structures + ********************************************************/ + +/* IIOD channels attributes list */ +struct iio_attribute channel_input_attributes[] = { + { + .name = "raw", + .show = get_chn_raw, + .store = set_chn_raw, + }, + { + .name = "scale", + .show = get_chn_scale, + .store = set_chn_scale, + }, +#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16) + { + .name = "chn_range", + .show = get_chn_range, + .store = set_chn_range, + }, + { + .name = "offset", + .show = get_chn_offset, + .store = set_chn_offset, + }, + { + .name = "chn_phase offset", + .show = get_chn_phase_offset, + .store = set_chn_phase_offset, + }, + { + .name = "temperature", + .show = get_chn_temperature, + .store = set_chn_temperature, + }, + { + .name = "vref", + .show = get_chn_vref, + .store = set_chn_vref, + }, + { + .name = "vdrive", + .show = get_chn_vdrive, + .store = set_chn_vdrive, + }, + { + .name = "ALDO", + .show = get_chn_aldo, + .store = set_chn_aldo, + }, + { + .name = "DLDO", + .show = get_chn_dldo, + .store = set_chn_dldo, + }, + { + .name = "open_circuit_detect_manual", + .show = get_chn_open_circuit_detect_manual, + .store = set_chn_open_circuit_detect_manual, + }, + { + .name = "open_circuit_detect_auto", + .show = get_chn_open_circuit_detect_auto, + .store = set_chn_open_circuit_detect_auto, + }, + { + .name = "calibrate_adc_offset", + .show = get_chn_calibrate_adc_offset, + .store = set_chn_calibrate_adc_offset, + }, + { + .name = "calibrate_adc_gain", + .show = get_chn_calibrate_adc_gain, + .store = set_chn_calibrate_adc_gain, + }, +#if defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16) + &iio_attr_bandwidth + { + .name = "bandwidth", + .show = get_bandwidth, + .store = set_bandwidth, + }, +#endif +#endif + + END_ATTRIBUTES_ARRAY +}; + +/* IIOD device (global) attributes list */ +static struct iio_attribute global_attributes[] = { +#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16) + { + .name = "operating_mode", + .show = get_operating_mode, + .store = set_operating_mode, + }, + { + .name = "oversampling_ratio", + .show = get_oversampling, + .store = set_oversampling, + }, +#else + { + .name = "power_down_mode", + .show = get_power_down_mode, + .store = set_power_down_mode, + }, + { + .name = "dev_range", + .show = get_range, + .store = set_range, + }, +#endif + { + .name = "sampling_frequency", + .show = get_sampling_frequency, + .store = set_sampling_frequency, + }, + + END_ATTRIBUTES_ARRAY +}; + +/* IIOD debug attributes list */ +static struct iio_attribute debug_attributes[] = { +#if defined(DEV_AD7606B) || defined(DEV_AD7606C_18) || defined(DEV_AD7606C_16) + { + .name = "direct_reg_access", + .show = NULL, + .store = NULL, + }, +#endif + + END_ATTRIBUTES_ARRAY +}; + +/* IIOD channels configurations */ +struct scan_type chn_scan = { + .sign = 's', +#if (AD7606X_ADC_RESOLUTION == 18) + .realbits = 18, + .storagebits = 18, +#else + .realbits = 16, + .storagebits = 16, +#endif + .shift = 0, + .is_big_endian = false +}; + +static struct iio_channel iio_ad7606_channels[] = { + { + .name = "voltage0", + .ch_type = IIO_VOLTAGE, + .channel = 0, + .scan_index = 0, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true, + }, + { + .name = "voltage1", + .ch_type = IIO_VOLTAGE, + .channel = 1, + .scan_index = 1, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + }, + { + .name = "voltage2", + .ch_type = IIO_VOLTAGE, + .channel = 2, + .scan_index = 2, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + }, + { + .name = "voltage3", + .ch_type = IIO_VOLTAGE, + .channel = 3, + .scan_index = 3, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + }, + { + .name = "voltage4", + .ch_type = IIO_VOLTAGE, + .channel = 4, + .scan_index = 4, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + }, + { + .name = "voltage5", + .ch_type = IIO_VOLTAGE, + .channel = 5, + .scan_index = 5, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + }, + { + .name = "voltage6", + .ch_type = IIO_VOLTAGE, + .channel = 6, + .scan_index = 6, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + }, + { + .name = "voltage7", + .ch_type = IIO_VOLTAGE, + .channel = 7, + .scan_index = 7, + .scan_type = &chn_scan, + .attributes = channel_input_attributes, + .ch_out = false, + .indexed = true + } +}; + /** * @brief Init for reading/writing and parameterization of a @@ -1645,42 +1852,31 @@ * @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) +static int32_t iio_ad7606_init(struct iio_device **desc) { - int32_t status; - struct iio_interface *iio_interface; - - iio_interface = (struct iio_interface *)calloc(1, sizeof(struct iio_interface)); - if (!iio_interface) { - return -ENOMEM; - } + struct iio_device *iio_ad7606_inst; - *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); + iio_ad7606_inst = calloc(1, sizeof(struct iio_device)); + if (!iio_ad7606_inst) { return FAILURE; } - *desc = calloc(1, sizeof(struct iio_ad7606_desc)); - if (!(*desc)) { - iio_unregister(iio_interface); - free(iio_interface); - return FAILURE; - } + iio_ad7606_inst->num_ch = sizeof(iio_ad7606_channels) / sizeof( + iio_ad7606_channels[0]); + iio_ad7606_inst->channels = iio_ad7606_channels; + iio_ad7606_inst->attributes = global_attributes; + iio_ad7606_inst->debug_attributes = debug_attributes; - (*desc)->iio_interface = iio_interface; + iio_ad7606_inst->transfer_dev_to_mem = iio_ad7606_transfer_dev_data; + iio_ad7606_inst->transfer_mem_to_dev = NULL; + iio_ad7606_inst->read_data = iio_ad7606_read_data; + iio_ad7606_inst->write_data = NULL; + iio_ad7606_inst->prepare_transfer = iio_ad7606_start_transfer; + iio_ad7606_inst->end_transfer = iio_ad7606_stop_transfer; + iio_ad7606_inst->debug_reg_read = debug_reg_read; + iio_ad7606_inst->debug_reg_write = debug_reg_write; + + *desc = iio_ad7606_inst; return SUCCESS; } @@ -1691,7 +1887,7 @@ * @param desc[in] - IIO device descriptor * @return SUCCESS in case of success, FAILURE otherwise */ -int32_t iio_ad7606_remove(struct iio_ad7606_desc *desc) +static int32_t iio_ad7606_remove(struct iio_desc *desc) { int32_t status; @@ -1699,19 +1895,11 @@ return FAILURE; } - status = iio_unregister(desc->iio_interface); - if (status < 0) { + status = iio_unregister(desc, (char *)dev_name); + if (status != SUCCESS) { return FAILURE; } - status = iio_ad7606_delete_device(desc->iio_interface->iio); - if (status < 0) { - return FAILURE; - } - - free(desc->iio_interface); - free(desc); - return SUCCESS; } @@ -1749,102 +1937,21 @@ char buf[50]; struct iio_ch_info channel; - for (uint8_t chn = 1; chn <= AD7606X_ADC_CHANNELS; chn++) { + for (uint8_t chn = 0; chn < AD7606X_ADC_CHANNELS; chn++) { channel.ch_num = chn; /* Get channel range */ - (void)get_chn_range(p_ad7606_dev, buf, 0, &channel); + (void)get_chn_range(p_ad7606_dev_inst, buf, 0, &channel, 0); /* 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]); + attr_scale_val[channel.ch_num] = get_vltg_conv_scale_factor( + attr_chn_range[channel.ch_num], + attr_polarity_val[channel.ch_num]); } } /** - * @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 @@ -1853,121 +1960,56 @@ { 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 device descriptor */ + struct iio_device *p_iio_ad7606_dev; /** - * 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, + * IIO interface init parameters + */ + struct iio_init_param iio_init_params = { + .phy_type = USE_UART, + { + &uart_init_params + } }; /* Initialize AD7606 device and peripheral interface */ - init_status = ad7606_init(&p_ad7606_dev, &ad7606_init_str); + init_status = ad7606_init(&p_ad7606_dev_inst, &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); + /* Initialize the IIO interface */ + init_status = iio_init(&p_ad7606_iio_desc, &iio_init_params); 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); + /* Initialize the AD7606 IIO application interface */ + init_status = iio_ad7606_init(&p_iio_ad7606_dev); if (init_status != SUCCESS) { return init_status; } - /* Initialize the IIO application interface */ - init_status = iio_app_init(&iio_app_desc, &iio_app_init_par); + /* Register AD7606 IIO interface */ + init_status = iio_register(p_ad7606_iio_desc, + p_iio_ad7606_dev, + (char *)dev_name, + p_ad7606_dev_inst, + NULL, + NULL); 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); + /* Init the system peripherals */ + init_status = init_system(); 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); + init_status = iio_data_capture_init(&p_ad7606_dev_inst); if (init_status != SUCCESS) { return init_status; } @@ -1983,18 +2025,7 @@ */ 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); + while (1) { + (void)iio_step(p_ad7606_iio_desc); } }