Example program for AD717x and AD411x family of products.
Dependencies: adi_console_menu platform_drivers
Diff: app/ad717x_console_app.c
- Revision:
- 1:48914f9593f1
- Child:
- 3:6c7324997606
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/app/ad717x_console_app.c Tue Mar 31 03:25:23 2020 +0000 @@ -0,0 +1,1758 @@ +/*! + ***************************************************************************** + @file: ad717x_console_app.c + + @brief: Implementation of the menu functions which handles the + functionality of AD717x and AD411x family of devices. + + @details: This file is specific to AD717x/AD411x console menu application handle. + The functions defined in this file performs the action + based on user selected console menu. + ----------------------------------------------------------------------------- + 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 <string.h> +#include <stdbool.h> +#include <ctype.h> + +#include "app_config.h" + +#include "ad717x.h" +#include "platform_support.h" +#include "platform_drivers.h" +#include "spi_extra.h" + +#include "ad717x_console_app.h" +#include "ad717x_menu_defines.h" +#include "ad717x_support.h" + +/******************************************************************************/ +/********************** Macros and Constants Definitions **********************/ +/******************************************************************************/ + +// Include the device register address map headers and device register map based +// on the user selected device (default is AD4111) +#if (defined(DEV_AD4111) || defined(DEV_AD4112) || \ + defined(DEV_AD4114) || defined(DEV_AD4115) || \ + defined(DEV_AD4116)) +#include <ad411x_regs.h> +static ad717x_st_reg *ad717x_device_map = ad4111_regs; +static uint8_t ad717x_reg_count = sizeof(ad4111_regs) / sizeof(ad4111_regs[0]); +#elif defined(DEV_AD7172_2) +#include <ad7172_2_regs.h> +static ad717x_st_reg *ad717x_device_map = ad7172_2_regs; +static uint8_t ad717x_reg_count = sizeof(ad7172_2_regs) / sizeof( + ad7172_2_regs[0]); +#elif defined(DEV_AD7172_4) +#include <ad7172_4_regs.h> +static ad717x_st_reg *ad717x_device_map = ad7172_4_regs; +static uint8_t ad717x_reg_count = sizeof(ad7172_4_regs) / sizeof( + ad7172_4_regs[0]); +#elif defined(DEV_AD7173_8) +#include <ad7173_8_regs.h> +static ad717x_st_reg *ad717x_device_map = ad7173_8_regs; +static uint8_t ad717x_reg_count = sizeof(ad7173_8_regs) / sizeof( + ad7173_8_regs[0]); +#elif defined(DEV_AD7175_2) +#include <ad7175_2_regs.h> +static ad717x_st_reg *ad717x_device_map = ad7175_2_regs; +static uint8_t ad717x_reg_count = sizeof(ad7175_2_regs) / sizeof( + ad7175_2_regs[0]); +#elif defined(DEV_AD7175_8) +#include <ad7175_8_regs.h> +static ad717x_st_reg *ad717x_device_map = ad7175_8_regs; +static uint8_t ad717x_reg_count = sizeof(ad7175_8_regs) / sizeof( + ad7175_8_regs[0]); +#elif defined(DEV_AD7176_2) +#include <ad7176_2_regs.h> +static ad717x_st_reg *ad717x_device_map = ad7176_2_regs; +static uint8_t ad717x_reg_count = sizeof(ad7176_2_regs) / sizeof( + ad7176_2_regs[0]); +#else +#include <ad411x_regs.h> +static ad717x_st_reg *ad717x_device_map = ad4111_regs; +static uint8_t ad717x_reg_count = sizeof(ad4111_regs) / sizeof(ad4111_regs[0]); +#endif + + +#define SHOW_ALL_CHANNELS false +#define SHOW_ENABLED_CHANNELS true + +#define DISPLAY_DATA_TABULAR 0 +#define DISPLAY_DATA_STREAM 1 + +/******************************************************************************/ +/********************** Variables and User Defined Data Types *****************/ +/******************************************************************************/ + +// Pointer to the struct representing the AD717x device +static ad717x_dev *pad717x_dev = NULL; + +// Device setup +static ad717x_setup_config device_setup; + +// User selected input (pair/positive/negative) +static uint8_t input_to_select; + +// Last Sampled values for All ADC channels +static uint32_t channel_samples[NUMBER_OF_CHANNELS] = { 0 }; + +// How many times a given channel is sampled in total for one sample run +static uint32_t channel_samples_count[NUMBER_OF_CHANNELS] = { 0 }; + +/******************************************************************************/ +/************************ Functions Declarations ******************************/ +/******************************************************************************/ + +static bool was_escape_key_pressed(void); + +/******************************************************************************/ +/************************ Functions Definitions *******************************/ +/******************************************************************************/ + +/*! + * @brief Initialize the AD717x device and associated low level peripherals + * @return SUCCESS(0) Or FAILURE(negative) + */ +int32_t ad717x_app_initialize(void) +{ + // Init SPI extra 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 + }; + + // Used to create the ad717x device + ad717x_init_param ad717x_init = { + // spi_init_param type + { + 2500000, // Max SPI Speed + SPI_SS_A, // Chip Select pin + SPI_MODE_3, // CPOL = 1, CPHA =1 + &spi_init_extra_params, // SPI extra configurations + }, + ad717x_device_map, // pointer to device register map + ad717x_reg_count, // number of device registers + }; + + // Initialze the device + return (AD717X_Init(&pad717x_dev, ad717x_init)); +} + + +/*! + * @brief determines if the Escape key was pressed + * @return bool- key press status + */ +static bool was_escape_key_pressed(void) +{ + char rxChar; + bool wasPressed = false; + + // Check for Escape key pressed + if ((rxChar = getchar_noblock()) > 0) { + if (rxChar == ESCAPE_KEY_CODE) { + wasPressed = true; + } + } + + return (wasPressed); +} + + +/* @brief Perform the channel selection + * @return uint8- Selected channel + **/ +static uint8_t get_channel_selection(void) +{ + uint32_t current_channel = 0; + bool current_selection_done = false; + + do { + printf(EOL "\tEnter Channel Value <0-%d>: ", NUMBER_OF_CHANNELS-1); + current_channel = adi_get_decimal_int(sizeof(current_channel)); + + if (current_channel < NUMBER_OF_CHANNELS) { + current_selection_done = true; + } else { + printf(EOL "\tInvalid channel selection!!" EOL); + } + } while (current_selection_done == false); + + return current_channel; +} + + +/* @brief Perform the setup selection + * @return uint8- Selected setup + **/ +static uint8_t get_setup_selection(void) +{ + uint32_t current_setup = 0; + bool current_selection_done = false; + + do { + printf(EOL "\tEnter Setup Selection <0-%d>: ", NUMBER_OF_SETUPS-1); + current_setup = adi_get_decimal_int(sizeof(current_setup)); + + if (current_setup < NUMBER_OF_SETUPS) { + current_selection_done = true; + } else { + printf(EOL "\tInvalid setup selection!!" EOL); + } + } while (current_selection_done == false); + + return current_setup; +} + + +/* @brief Assign setup to adc channel + * @param uint8_t setup- setup to be assigned + **/ +static void assign_setup_to_channel(uint8_t setup) +{ + uint8_t current_channel; // channel to be assigned with setup + ad717x_st_reg *device_chnmap_reg; // pointer to channel map register + + adi_clear_console(); + + // Get the channel selection + current_channel = get_channel_selection(); + + // Get the pointer to channel map register structure + device_chnmap_reg = AD717X_GetReg(pad717x_dev, + AD717X_CHMAP0_REG + current_channel); + + // Load the setup value + device_chnmap_reg->value = + ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_SETUP_SEL_MSK) | + AD717X_CHMAP_REG_SETUP_SEL(setup)); + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_CHMAP0_REG + current_channel) != SUCCESS) { + printf(EOL "\tError in setup assignment!!" EOL); + } else { + printf(EOL "\tSetup %d is assigned to channel %d successfully..." EOL, + setup, + current_channel); + } + + adi_press_any_key_to_continue(); +} + + +/* @brief Select adc channel to be assigned to setup + * @return none + **/ +static void select_chn_assignment(void) +{ + bool current_selection_done = false; + char rx_char; + + do { + printf(EOL EOL "\tDo you want to assign setup to a channel (y/n)?: "); + rx_char = toupper(getchar()); + + if (rx_char == 'Y') { + assign_setup_to_channel(device_setup.setup); + current_selection_done = true; + } else if (rx_char == 'N') { + current_selection_done = true; + } else { + printf(EOL "\tInvalid entry!!"); + } + } while (current_selection_done == false); +} + + +/*! + * @brief Display the header info for main menu + * @return None + */ +void display_main_menu_header(void) +{ + // Display the device name + printf(EOL "\tDevice: %s" EOL, ACTIVE_DEVICE_NAME); +} + + +/*! + * @brief Handle the menu to read device ID + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_read_id(uint32_t menu_id) +{ + ad717x_st_reg *device_id_reg; // Pointer to register + + device_id_reg = AD717X_GetReg(pad717x_dev, AD717X_ID_REG); + if (!device_id_reg) { + printf(EOL EOL "\tError reading device ID!!" EOL); + } else { + if (AD717X_ReadRegister(pad717x_dev, AD717X_ID_REG) != SUCCESS) { + printf(EOL EOL "\tError reading device ID!!" EOL); + } else { + printf(EOL EOL "\tDevice ID: 0x%lx" EOL, device_id_reg->value); + } + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/*! + * @brief Handle the menu to read device status register + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_read_status(uint32_t menu_id) +{ + ad717x_st_reg *device_status_reg; // Pointer to register + + device_status_reg = AD717X_GetReg(pad717x_dev, AD717X_STATUS_REG); + if (!device_status_reg) { + printf(EOL EOL "\tError reading status register!!" EOL); + } else { + if (AD717X_ReadRegister(pad717x_dev, AD717X_STATUS_REG) != SUCCESS) { + printf(EOL EOL "\tError reading status register!!" EOL); + } else { + printf(EOL EOL "\tStatus Register: 0x%lx" EOL, device_status_reg->value); + } + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/* + * @brief helper function get the bipolar setting for an ADC channel + * + * @param dev The device structure. + * + * @param channel ADC channel to get bipolar mode for. + * + * @return value of bipolar field in the setup for an ADC channel. + */ +static bool ad717x_get_channel_bipolar(ad717x_dev *dev, uint8_t channel) +{ + ad717x_st_reg *device_setup_reg; // Pointer to device setup register + ad717x_st_reg *device_chnmap_reg; // Pointer to device channelmap register + uint8_t polarity; // Polarity status flag + uint8_t setup; // Current setup + + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + channel); + (void)AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + channel); + + // Read the setup value for the current channel + setup = AD717X_CHMAP_REG_SETUP_SEL_RD(device_chnmap_reg->value); + + device_setup_reg = AD717X_GetReg(pad717x_dev, AD717X_SETUPCON0_REG + setup); + (void)AD717X_ReadRegister(pad717x_dev, AD717X_SETUPCON0_REG + setup); + + // Get the polarity bit for current setup + polarity = AD717X_SETUP_CONF_REG_BI_UNIPOLAR_RD(device_setup_reg->value); + + if (polarity == BIPOLAR) { + return true; + } else { + return false; + } +} + + +/* + * @brief converts ADC sample value to voltage based on gain setting + * + * @param dev The device structure. + * + * @param channel ADC channel to get Setup for. + * + * @param sample Raw ADC sample + * + * @return Sample ADC value converted to voltage. + * + * @note The conversion equation is implemented for simplicity, + * not for accuracy or performance + * + */ +static float ad717x_convert_sample_to_voltage(ad717x_dev *dev, + uint8_t channel, + uint32_t sample) +{ + float converted_value; + bool is_bipolar = ad717x_get_channel_bipolar(dev, channel); + + if (is_bipolar) { + converted_value = (((float)sample / (1 << (ADC_RESOLUTION - 1))) - 1) * + ADC_REF_VOLTAGE; + } else { + converted_value = (((float)sample * ADC_REF_VOLTAGE) / (1 << ADC_RESOLUTION)); + } + + return (converted_value); +} + + +/*! + * @brief displays the current sample value for a ADC channels + * + * @param showOnlyEnabledChannels only channels that are enabled are displayed + * + */ +static void dislay_channel_samples(bool showOnlyEnabledChannels, + uint8_t console_mode) +{ + ad717x_st_reg *device_chnmap_reg; // Pointer to channel map register + bool channel_printed = false; // Channel print status flag + + switch (console_mode) { + case DISPLAY_DATA_TABULAR: + printf("\tCh\tValue\t\tCount\t\tVoltage" EOL); + for (uint8_t chn = 0; chn < NUMBER_OF_CHANNELS; chn++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn); + + // if showing all channels, or channel is enabled + if ((showOnlyEnabledChannels == false) + || (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN)) { + printf("\t%-2d\t%-10ld\t%ld\t\t% .6f" EOL, + chn, + channel_samples[chn], + channel_samples_count[chn], + ad717x_convert_sample_to_voltage(pad717x_dev, chn, channel_samples[chn])); + } + } + break; + + case DISPLAY_DATA_STREAM: + // Output a CSV list of the sampled channels as voltages on a single line + for (uint8_t chn = 0 ; chn < NUMBER_OF_CHANNELS; chn++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn); + + // if showing all channels, or channel is enabled + if ((showOnlyEnabledChannels == false) || + (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN)) { + /* + * add the comma before we output the next channel but + * only if at least one channel has been printed + */ + if (channel_printed) { + printf(", "); + } + + printf("%.6f", ad717x_convert_sample_to_voltage(pad717x_dev, chn, + channel_samples[chn])); + + channel_printed = true; + } + } + printf(EOL); + break; + + default: + break; + } +} + + +/*! + * @brief resets the channelSampleCounts to zero + * + * @details + */ +static void clear_channel_samples(void) +{ + for (uint8_t i = 0; i < NUMBER_OF_CHANNELS; i++) { + channel_samples[i] = 0; + channel_samples_count[i] = 0; + } +} + + +/*! + * @brief Continuously acquires samples in Continuous Conversion mode + * + * @details The ADC is run in continuous mode, and all samples are acquired + * and assigned to the channel they come from. Escape key an be used + * to exit the loop + */ +static int32_t do_continuous_conversion(uint8_t display_mode) +{ + int32_t error_code; + int32_t sample_data; + ad717x_st_reg *device_mode_reg; + ad717x_st_reg *device_chnmap_reg; + ad717x_st_reg *device_status_reg; + + // Get the pointer to mode register + device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG); + + // Clear the ADC CTRL MODE bits, has the effect of selecting continuous mode + device_mode_reg->value &= ~(AD717X_ADCMODE_REG_MODE(0xf)); + + if ((error_code = AD717X_WriteRegister(pad717x_dev, + AD717X_ADCMODE_REG)) != SUCCESS) { + printf("Error (%ld) setting AD717x Continuous conversion mode." EOL, + error_code); + + adi_press_any_key_to_continue(); + return (MENU_CONTINUE); + } + + clear_channel_samples(); + + /* + * If displaying data in stream form, want to output a channel header + */ + if (display_mode == DISPLAY_DATA_STREAM) { + bool channel_printed = false; + + for (uint8_t chn = 0; chn < NUMBER_OF_CHANNELS; chn++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn); + + // if showing all channels, or channel is enabled + if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) { + /* + * add the comma before we output the next channel but + * only if at least one channel has been printed + */ + if (channel_printed) { + printf(", "); + } + printf("%d", chn); + } + channel_printed = true; + } + printf(EOL); + } + + // Continuously read the channels, and store sample values + while (was_escape_key_pressed() != true) { + if (display_mode == DISPLAY_DATA_TABULAR) { + adi_clear_console(); + printf("Running continuous conversion mode...\r\nPress Escape to stop" EOL EOL); + } + + /* + * this polls the status register READY/ bit to determine when conversion is done + * this also ensures the STATUS register value is up to date and contains the + * channel that was sampled as well. + * Generally, no need to read STATUS separately, but for faster sampling + * enabling the DATA_STATUS bit means that status is appended to ADC data read + * so the channel being sampled is read back (and updated) as part of the same frame + */ + if ((error_code = AD717X_WaitForReady(pad717x_dev, 10000)) != SUCCESS) { + printf("Error/Timeout waiting for conversion ready %ld" EOL EOL, error_code); + continue; + } + + if ((error_code = AD717X_ReadData(pad717x_dev, &sample_data)) != SUCCESS) { + printf("Error reading ADC Data (%ld)." EOL, error_code); + continue; + } + + /* + * No error, need to process the sample, what channel has been read? update that channelSample + */ + device_status_reg = AD717X_GetReg(pad717x_dev, AD717X_STATUS_REG); + uint8_t channelRead = device_status_reg->value & 0x0000000F; + + if (channelRead < NUMBER_OF_CHANNELS) { + channel_samples[channelRead] = sample_data; + channel_samples_count[channelRead]++; + } else { + printf("Channel Read was %d, which is not < %d" EOL, + channelRead, + NUMBER_OF_CHANNELS); + } + + dislay_channel_samples(SHOW_ENABLED_CHANNELS, display_mode); + } + + // All done, ADC put into standby mode + // 2 = sleep/standby mode + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(2)); + + if ((error_code = AD717X_WriteRegister(pad717x_dev, + AD717X_ADCMODE_REG)) != SUCCESS) { + printf("Error (%ld) setting ADC into standby mode." EOL, error_code); + adi_press_any_key_to_continue(); + } + + return (MENU_CONTINUE); +} + + +/*! + * @brief Samples all enabled channels and displays in tabular form + * + * @details + */ +int32_t menu_continuous_conversion_tabular(uint32_t channel_id) +{ + do_continuous_conversion(DISPLAY_DATA_TABULAR); + + adi_clear_console(); + printf("Continuous Conversion completed..." EOL EOL); + dislay_channel_samples(SHOW_ALL_CHANNELS, DISPLAY_DATA_TABULAR); + adi_press_any_key_to_continue(); + + return (MENU_CONTINUE); +} + + +/*! + * @brief Samples all enabled channels and displays on the console + * + * @details + */ +int32_t menu_continuous_conversion_stream(uint32_t channel_id) +{ + do_continuous_conversion(DISPLAY_DATA_STREAM); + printf("Continuous Conversion completed..." EOL EOL); + + adi_press_any_key_to_continue(); + return (MENU_CONTINUE); +} + + +/*! + * @brief Samples all enabled channels once in Single Conversion mode + * + * @details This stores all channels that are enabled in a bitmask, and then + * runs the ADC in single conversion mode, which acquires one channel + * of data at a time. After capture, that channel is disabled, and + * single conversion run again, until no channels are enabled. + * The original enable state of each channel is then restored. + */ +int32_t menu_single_conversion(uint32_t channel_id) +{ + int32_t error_code; + uint16_t channel_enable_mask = 0; + uint8_t channel_count = 0; + int32_t sample_data; + ad717x_st_reg *device_chnmap_reg; + ad717x_st_reg *device_mode_reg; + ad717x_st_reg *device_status_reg; + + // Need to store which channels are enabled in this config so it can be restored + for (uint8_t chn = 0 ; chn < NUMBER_OF_CHANNELS; chn++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn); + + if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) { + channel_enable_mask |= (1 << chn); + channel_count++; + } + } + + clear_channel_samples(); + + adi_clear_console(); + printf("Running Single conversion mode...\r\nPress Escape to stop" EOL EOL); + + // Get the pointer to mode register + device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG); + + // Clear the ADC CTRL MODE bits, selecting continuous mode + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(0)); + + // read the channels, and store sample values + for(uint8_t loopCount = 0 ; ((was_escape_key_pressed() != true) + && (loopCount < channel_count)) ; loopCount++) { + + // 1 = single conversion mode + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(1)); + + if ((error_code = AD717X_WriteRegister(pad717x_dev, + AD717X_ADCMODE_REG)) != SUCCESS) { + printf("Error (%ld) setting AD717x Single conversion mode." EOL, error_code); + adi_press_any_key_to_continue(); + continue; + } + + /* + * this polls the status register READY/ bit to determine when conversion is done + * this also ensures the STATUS register value is up to date and contains the + * channel that was sampled as well. No need to read STATUS separately + */ + if ((error_code = AD717X_WaitForReady(pad717x_dev, 10000)) != SUCCESS) { + printf("Error/Timeout waiting for conversion ready %ld" EOL, error_code); + continue; + } + + if ((error_code = AD717X_ReadData(pad717x_dev, &sample_data)) != SUCCESS) { + printf("Error reading ADC Data (%ld)." EOL, error_code); + continue; + } + + /* + * No error, need to process the sample, what channel has been read? update that channelSample + */ + device_status_reg = AD717X_GetReg(pad717x_dev, AD717X_STATUS_REG); + uint8_t channelRead = device_status_reg->value & 0x0000000F; + + if (channelRead < NUMBER_OF_CHANNELS) { + channel_samples[channelRead] = sample_data; + channel_samples_count[channelRead]++; + + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + channelRead); + + /* also need to clear the channel enable bit so the next single conversion cycle will sample the next channel */ + device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN); + if ((error_code = AD717X_WriteRegister(pad717x_dev, + AD717X_CHMAP0_REG + channelRead)) != SUCCESS) { + printf("Error (%ld) Clearing channel %d Enable bit." EOL, + error_code, + channelRead); + + adi_press_any_key_to_continue(); + continue; + } + } else { + printf("Channel Read was %d, which is not < AD717x_CHANNEL_COUNT" EOL, + channelRead); + } + } + + // All done, ADC put into standby mode + // 2 = sleep/standby mode + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(2)); + + // Need to restore the channels that were disabled during acquisition + for(uint8_t chn = 0 ; chn < NUMBER_OF_CHANNELS ; chn++) { + if (channel_enable_mask & (1 << chn)) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn); + + device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN; + + if ((error_code = AD717X_WriteRegister(pad717x_dev, + AD717X_CHMAP0_REG + chn)) != SUCCESS) { + printf("Error (%ld) Setting channel %d Enable bit" EOL EOL, error_code, chn); + + adi_press_any_key_to_continue(); + return (MENU_CONTINUE); + } + } + } + + printf("Single Conversion completed..." EOL EOL); + dislay_channel_samples(SHOW_ENABLED_CHANNELS, DISPLAY_DATA_TABULAR); + + adi_press_any_key_to_continue(); + return (MENU_CONTINUE); +} + + +/*! + * @brief Handle the menu to sample the channels + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_sample_channels(uint32_t menu_id) +{ + return adi_do_console_menu(&acquisition_menu); +} + + +/* @brief Enable or disable adc channels + * @param uint32_t action- channel ENABLE/DISABLE action + * @return MENU_CONTINUE + **/ +int32_t menu_channels_enable_disable(uint32_t action) +{ + char rx_char; // received character from the serial port + uint8_t current_channel; // channel to be enabled + ad717x_st_reg *device_chnmap_reg; // Pointer to channel map register + + do { + // Get the channel selection + current_channel = get_channel_selection(); + + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, + AD717X_CHMAP0_REG + current_channel); + + if (action == SELECT_ENABLE) { + // Enable the selected channel + device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN; + printf("\tChannel %d is Enabled ", current_channel); + } else { + // Disable the selected channel + device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN); + printf("\tChannel %d is Disabled ", current_channel); + } + + // Write to ADC channel register + if (AD717X_WriteRegister(pad717x_dev, + AD717X_CHMAP0_REG + current_channel) != SUCCESS) { + printf("\tError in channel Enable/Disable!!" EOL); + break; + } + + printf(EOL EOL "\tDo you want to continue (y/n)?: "); + rx_char = toupper(getchar()); + + if ((rx_char != 'N') && (rx_char != 'Y')) { + printf("Invalid entry!!" EOL); + } else { + // Print the entered character back on console window (serial port) + printf("%c" EOL, rx_char); + } + } while (rx_char != 'N'); + + return MENU_CONTINUE; +} + + +/*! + * @brief Display the menu to enable/disable channel selection + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_chn_enable_disable_display(uint32_t menu_id) +{ + return adi_do_console_menu(&chn_enable_disable_menu); +} + + +/*! + * @brief Handle the menu to connect input to channel + * @param uint32_t user_analog_input- analog input to be connected + * @return MENU_CONTINUE + */ +int32_t menu_analog_input_connect(uint32_t user_analog_input) +{ + uint8_t current_channel; // current channel + ad717x_st_reg *device_chnmap_reg; // Pointer to channel map register + + adi_clear_console(); + + // Get the channel selection + current_channel = get_channel_selection(); + + if (input_to_select == POS_ANALOG_INP_SELECT) { + printf(EOL "\tSelect Positive Analog Input" EOL); + device_setup.pos_analog_input = user_analog_input; + } else if (input_to_select == NEG_ANALOG_INP_SELECT) { + printf(EOL "\tSelect Negative Analog Input" EOL); + device_setup.neg_analog_input = user_analog_input; + } else { + device_setup.pos_analog_input = AD717X_CHMAP_REG_AINPOS_RD(user_analog_input); + device_setup.neg_analog_input = AD717X_CHMAP_REG_AINNEG_RD(user_analog_input); + } + + // Get the pointer to channel map register structure + device_chnmap_reg = AD717X_GetReg(pad717x_dev, + AD717X_CHMAP0_REG + current_channel); + +#if defined(DEV_AD4111) || defined(DEV_AD4112) + // Select analog input pair + device_chnmap_reg->value = + ((device_chnmap_reg->value & ~AD4111_CHMAP_REG_INPUT_MSK) | + AD4111_CHMAP_REG_INPUT(user_analog_input)); +#elif + // Select positive analog input + device_chnmap_reg->value = + ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_AINPOS_MSK) | + AD717X_CHMAP_REG_AINPOS(device_setup.pos_analog_input)); + + // Select negative analog input + device_chnmap_reg->value = + ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_AINNEG_MSK) | + AD717X_CHMAP_REG_AINNEG(device_setup.neg_analog_input)); +#endif + + // Write to ADC channel register + if (AD717X_WriteRegister(pad717x_dev, + AD717X_CHMAP0_REG + current_channel) != SUCCESS) { + printf(EOL "\tError in analog input connection!!" EOL); + } else { + printf(EOL "\t%s is connected to INP+ and %s is connectd to INP- for channel %d" + EOL + EOL, + input_pin_map[device_setup.pos_analog_input], + input_pin_map[device_setup.neg_analog_input], + current_channel); + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/*! + * @brief Display the menu selections to connect analog input pins to a channel + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_input_chn_connect_display(uint32_t menu_id) +{ +#if defined(DEV_AD4111) || defined(DEV_AD4112) + input_to_select = ANALOG_INP_PAIR_SELECT; + adi_do_console_menu(&analog_input_connect_menu); +#else + input_to_select = POS_ANALOG_INP_SELECT; + adi_do_console_menu(&analog_input_connect_menu); + + input_to_select = NEG_ANALOG_INP_SELECT; + adi_do_console_menu(&analog_input_connect_menu); +#endif + + return MENU_CONTINUE; +} + + +/*! + * @brief Handle the menu to select the filter type + * @param uint32_t filter_type- user selected filter type + * @return MENU_DONE + */ +int32_t menu_filter_select(uint32_t user_input_filter_type) +{ + ad717x_st_reg *device_filter_config_reg; // Pointer to filter config register + + // Get the pointer to filter config register structure + device_filter_config_reg = AD717X_GetReg(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup); + + device_setup.filter = user_input_filter_type; + + device_filter_config_reg->value = + ((device_filter_config_reg->value & ~AD717X_FILT_CONF_REG_ORDER_MSK) | + AD717X_FILT_CONF_REG_ORDER(device_setup.filter)); + + if (device_setup.filter == SINC3_FILTER) { + device_filter_config_reg->value |= AD717X_FILT_CONF_REG_SINC3_MAP; + } else { + device_filter_config_reg->value &= (~AD717X_FILT_CONF_REG_SINC3_MAP); + } + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Filter Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to enable/disable the post filter + * @param uint32_t user_action- user selected action + * @return MENU_DONE + */ +int32_t menu_postfiler_enable_disable(uint32_t user_action) +{ + ad717x_st_reg *device_filter_config_reg; // Pointer to filter config register + + // Get the pointer to filter config register structure + device_filter_config_reg = AD717X_GetReg(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup); + + if (user_action == SELECT_ENABLE) { + device_setup.post_filter_enabled = SELECT_ENABLE; + device_filter_config_reg->value |= AD717X_FILT_CONF_REG_ENHFILTEN; + } else { + device_setup.post_filter_enabled = SELECT_DISBLE; + device_filter_config_reg->value &= (~AD717X_FILT_CONF_REG_ENHFILTEN); + } + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Enabling/Disabling Postfilter!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to select the post filter + * @param uint32_t user_action- user selected post filter type + * @return MENU_DONE + */ +int32_t menu_postfiler_select(uint32_t user_input_post_filter_type) +{ + ad717x_st_reg *device_filter_config_reg; // Pointer to filter config register + + // Get the pointer to filter config register structure + device_filter_config_reg = AD717X_GetReg(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup); + + device_setup.postfilter = user_input_post_filter_type; + + device_filter_config_reg->value = + ((device_filter_config_reg->value & ~AD717X_FILT_CONF_REG_ENHFILT_MSK) | + AD717X_FILT_CONF_REG_ENHFILT(device_setup.postfilter)); + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Post-Filter Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to select the ODR value + * @param uint32_t user_input_odr_val- user selected ODR + * @return MENU_DONE + */ +int32_t menu_odr_select(uint32_t user_input_odr_val) +{ + ad717x_st_reg *device_filter_config_reg; // Pointer to filter config register + + // Get the pointer to filter config register structure + device_filter_config_reg = AD717X_GetReg(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup); + + device_setup.odr_bits = user_input_odr_val; + + device_filter_config_reg->value = + ((device_filter_config_reg->value & ~AD717X_FILT_CONF_REG_ODR_MSK) | + AD717X_FILT_CONF_REG_ODR(device_setup.odr_bits)); + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in ODR Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to select the polarity + * @param uint32_t user_input_polarity- user selected polarity + * @return MENU_DONE + */ +int32_t menu_polarity_select(uint32_t user_input_polarity) +{ + ad717x_st_reg *device_setup_control_reg; // Pointer to setup control register + + // Get the pointer to setup control register structure + device_setup_control_reg = AD717X_GetReg(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup); + + if (user_input_polarity == BIPOLAR) { + device_setup.polarity = BIPOLAR; + device_setup_control_reg->value |= AD717X_SETUP_CONF_REG_BI_UNIPOLAR; + } else { + device_setup.polarity = UNIPOLAR; + device_setup_control_reg->value &= (~AD717X_SETUP_CONF_REG_BI_UNIPOLAR); + } + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Polarity Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to select the reference source + * @param uint32_t user_input_reference- user selected reference source + * @return MENU_DONE + */ +int32_t menu_reference_source_select(uint32_t user_input_reference) +{ + ad717x_st_reg *device_setup_control_reg; // Pointer to setup control register + ad717x_st_reg *device_mode_reg; // Pointer to adc mode register + + device_setup.reference = user_input_reference; + + // Get the pointer to device mode register structure + device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG); + + if (device_setup.reference == INTERNAL) { + device_mode_reg->value |= AD717X_ADCMODE_REG_REF_EN; + } else { + device_mode_reg->value &= (~AD717X_ADCMODE_REG_REF_EN); + } + + if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) { + printf(EOL "\tError in Polarity Selection!!" EOL); + adi_press_any_key_to_continue(); + return MENU_CONTINUE; + } + + // Get the pointer to setup control register structure + device_setup_control_reg = AD717X_GetReg(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup); + + device_setup_control_reg->value = + ((device_setup_control_reg->value & ~AD717X_SETUP_CONF_REG_REF_SEL_MSK) | + AD717X_SETUP_CONF_REG_REF_SEL(device_setup.reference)); + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Polarity Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to enable/disable the reference buffers + * @param uint32_t user_action- user selected action + * @return MENU_DONE + */ +int32_t menu_ref_buffer_enable_disable(uint32_t user_action) +{ + ad717x_st_reg *device_setup_control_reg; // Pointer to setup control register + + // Get the pointer to setup control register structure + device_setup_control_reg = AD717X_GetReg(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup); + + device_setup.reference_buffers = user_action; + + if (user_action == SELECT_ENABLE) { + // Enable ref buffers (+ve/-ve) + device_setup_control_reg->value |= + (AD717X_SETUP_CONF_REG_REFBUF_P | + AD717X_SETUP_CONF_REG_REFBUF_N); + } else { + // Disable ref buffers (+ve/-ve) + device_setup_control_reg->value &= + (~(AD717X_SETUP_CONF_REG_REFBUF_P | + AD717X_SETUP_CONF_REG_REFBUF_N)); + } + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Reference Buffer Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to enable/disable the input buffers + * @param uint32_t user_action- user selected action + * @return MENU_DONE + */ +int32_t menu_input_buffer_enable_disable(uint32_t user_action) +{ + ad717x_st_reg *device_setup_control_reg; // Pointer to setup control register + + // Get the pointer to setup control register structure + device_setup_control_reg = AD717X_GetReg(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup); + + device_setup.input_buffers = user_action; + + if (user_action == SELECT_ENABLE) { + // Enable ref buffers (+ve/-ve) + device_setup_control_reg->value |= + (AD717X_SETUP_CONF_REG_AINBUF_P | + AD717X_SETUP_CONF_REG_AINBUF_N); + } else { + // Disable input buffers (+ve/-ve) + device_setup_control_reg->value &= + (~(AD717X_SETUP_CONF_REG_AINBUF_P | + AD717X_SETUP_CONF_REG_AINBUF_N)); + } + + if (AD717X_WriteRegister(pad717x_dev, + AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) { + printf(EOL "\tError in Reference Buffer Selection!!" EOL); + adi_press_any_key_to_continue(); + } + + return MENU_DONE; +} + + +/*! + * @brief Handle the menu to configure and assign the device setup + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_config_and_assign_setup(uint32_t menu_id) +{ + float filter_odr; // filter ODR value + + adi_clear_console(); + + // Get the current setup selection + device_setup.setup = get_setup_selection(); + + // Select the filter type + adi_do_console_menu(&filter_select_menu); + + if (device_setup.filter == SINC5_SINC1_FILTER) { + // Select the post filter parameters + adi_do_console_menu(&postfilter_enable_disable_menu); + + if (device_setup.post_filter_enabled == SELECT_ENABLE) { + // Select the post filter type + adi_do_console_menu(&postfilter_select_menu); + } + + // Select the SINC+SINC1 filter ODR + adi_do_console_menu(&sinc5_1_data_rate_select_menu); + filter_odr = sinc5_sinc1_odr_map[device_setup.odr_bits]; + } else { + // Select the SINC3 filter ODR + adi_do_console_menu(&sinc3_data_rate_select_menu); + filter_odr = sinc3_odr_map[device_setup.odr_bits]; + } + + // Select the polarity + adi_do_console_menu(&polarity_select_menu); + + // Select the reference source + adi_do_console_menu(&reference_select_menu); + + // Select the reference buffer + adi_do_console_menu(&ref_buffer_enable_disable_menu); + + // Select the input buffer + adi_do_console_menu(&input_buffer_enable_disable_menu); + + // Print selections + printf(EOL EOL "\tSetup %ld is configured successfully =>" EOL, + device_setup.setup); + printf(EOL "\tFilter Type: %s", filter_name[device_setup.filter]); + + if (device_setup.filter == SINC5_SINC1_FILTER + && device_setup.post_filter_enabled) { + printf("\r\n\tPost Filter Type: %s", postfilter_name[device_setup.postfilter]); + } + + printf(EOL "\tData Rate: %f", filter_odr); + printf(EOL "\tPolarity: %s", polarity_status[device_setup.polarity]); + printf(EOL "\tReference: %s", reference_name[device_setup.reference]); + printf(EOL "\tReference Buffers: %s", + enable_disable_status[device_setup.reference_buffers]); + printf(EOL "\tInput Buffers: %s", + enable_disable_status[device_setup.input_buffers]); + printf(EOL); + + // Select and assign the channel + select_chn_assignment(); + + return MENU_CONTINUE; +} + + +/* @brief Get the data rate based on data rate FS value and vice a versa + * @param uint32_t filter- Filter Type + * @param uint32_t odr_reg_val- Filter data rate register value/bits + * @return float data_rate- Actual Data Rate + **/ +static float get_data_rate(uint32_t filter, uint32_t odr_reg_val) +{ + float data_rate; // filter data rate + + if (filter == SINC5_SINC1_FILTER) { + data_rate = sinc5_sinc1_odr_map[odr_reg_val]; + } else { + data_rate = sinc3_odr_map[odr_reg_val]; + } + + return data_rate; +} + + +/*! + * @brief Handle the menu to display device setup + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_display_setup(uint32_t menu_id) +{ + float filter_data_rate; // Filter data rate in SPS + uint8_t setup_cnt; // setup counter + uint8_t chn_cnt; // channel counter + ad717x_st_reg *device_chnmap_reg; // Pointer to channel map register + ad717x_st_reg *device_setupcon_reg; // Pointer to setup control register + ad717x_st_reg *device_filtercon_reg; // Pointer to filter control register + + printf(EOL); + printf("\t---------------------------------------" EOL); + printf("\tChannel# | Status | Setup | INP0 | INP1" EOL); + printf("\t---------------------------------------" EOL); + + for (chn_cnt = 0; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt); + if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + printf(EOL "Error reading setup!!" EOL); + break; + } + + // Extract the channel parameters from device register read value + device_setup.channel_enabled = AD717X_CHMAP_REG_CH_EN_RD( + device_chnmap_reg->value); + device_setup.setup_assigned = AD717X_CHMAP_REG_SETUP_SEL_RD( + device_chnmap_reg->value); + device_setup.pos_analog_input = AD717X_CHMAP_REG_AINPOS_RD( + device_chnmap_reg->value); + device_setup.neg_analog_input = AD717X_CHMAP_REG_AINNEG_RD( + device_chnmap_reg->value); + + // Channel# | Status | Setup | INP0 | INP1 + printf("\t%4d %13s %4ld %8s %6s" EOL, + chn_cnt, + enable_disable_status[device_setup.channel_enabled], + device_setup.setup_assigned, + input_pin_map[device_setup.pos_analog_input], + input_pin_map[device_setup.neg_analog_input]); + } + + printf(EOL); + printf("\t-------------------------------------------------------------------------------------------------------------" + EOL); + printf("\tSetup# | Filter | Post Filter | Data Rate | INPBUF+ | INPBUF- | REFBUF+ | REFBUF- | Polarity | Ref Source" + EOL); + printf("\t-------------------------------------------------------------------------------------------------------------" + EOL); + + for (setup_cnt = 0; setup_cnt < NUMBER_OF_SETUPS; setup_cnt++) { + // Get the pointer to filter control register + device_filtercon_reg = AD717X_GetReg(pad717x_dev, + AD717X_FILTCON0_REG + setup_cnt); + if (AD717X_ReadRegister(pad717x_dev, + AD717X_FILTCON0_REG + setup_cnt) != SUCCESS) { + printf("\r\nError reading setup!!\r\n"); + break; + } + + /* Extract the setup parameters from device register read value */ + device_setup.filter = AD717X_FILT_CONF_REG_ORDER_RD( + device_filtercon_reg->value); + device_setup.odr_bits = AD717X_FILT_CONF_REG_ODR_RD( + device_filtercon_reg->value); + device_setup.post_filter_enabled = AD717X_FILT_CONF_REG_ENHFILTEN_RD( + device_filtercon_reg->value); + device_setup.postfilter = AD717X_FILT_CONF_REG_ENHFILT_RD( + device_filtercon_reg->value); + + if (device_setup.filter == SINC3_FILTER) { + // Post filter unavailable for SINC3 type filter + device_setup.post_filter_enabled = SELECT_DISBLE; + device_setup.postfilter = POST_FILTER_NA; + } + + // Get the pointer to setup control register + device_setupcon_reg = AD717X_GetReg(pad717x_dev, + AD717X_SETUPCON0_REG + setup_cnt); + if (AD717X_ReadRegister(pad717x_dev, + AD717X_SETUPCON0_REG + setup_cnt) != SUCCESS) { + printf("\r\nError reading setup!!\r\n"); + break; + } + +#if defined(DEV_AD4111) || defined(DEV_AD4112) + device_setup.input_buffers = + AD4111_SETUP_CONF_REG_AIN_BUF_RD(device_setupcon_reg->value); + device_setup.reference_buffers = + (AD4111_SETUP_CONF_REG_REFPOS_BUF_RD(device_setupcon_reg->value) << 1 | + AD4111_SETUP_CONF_REG_REFNEG_BUF_RD(device_setupcon_reg->value)); +#elif defined(DEV_AD7172_2) || defined(DEV_AD7172_4) || defined(DEV_AD7175_8) + device_setup.input_buffers = + (AD717X_SETUP_CONF_REG_AINBUF_P_RD(device_setupcon_reg->value) << 1) | + (AD717X_SETUP_CONF_REG_AINBUF_N_RD(device_setupcon_reg->value)); + + device_setup.reference_buffers = + (AD717X_SETUP_CONF_REG_REFBUF_P_RD(device_setupcon_reg->value) << 1) | + (AD717X_SETUP_CONF_REG_REFBUF_N_RD(device_setupcon_reg->value)); +#elif defined(DEV_AD7173_8) + device_setup.input_buffers = + AD717X_SETUP_CONF_REG_AIN_BUF_RD(device_setupcon_reg->value); + device_setup.reference_buffers = + AD717X_SETUP_CONF_REG_REF_BUF_RD(device_setupcon_reg->value); +#endif + + device_setup.polarity = AD717X_SETUP_CONF_REG_BI_UNIPOLAR_RD( + device_setupcon_reg->value); + device_setup.reference = AD717X_SETUP_CONF_REG_REF_SEL_RD( + device_setupcon_reg->value); + + // Get the actual data rate based on the filter selection + filter_data_rate = get_data_rate(device_setup.filter, + device_setup.odr_bits); + + // Setup# | Filter | Post Filter | Data Rate | INPBUF+ | INPBUF- | REFBUF+ | REFBUF- | Polarity | Ref Source + printf("\t%4d %11s %8s(%6s) %10.2f %9s %9s %9s %9s %10s %10s" EOL, + setup_cnt, + filter_name[device_setup.filter], + postfilter_name[device_setup.postfilter], + enable_disable_status[device_setup.post_filter_enabled], + filter_data_rate, + enable_disable_status[(device_setup.input_buffers >> 1) & 0x01], + enable_disable_status[(device_setup.input_buffers & 0x01)], + enable_disable_status[(device_setup.reference_buffers >> 1) & 0x01], + enable_disable_status[device_setup.reference_buffers & 0x01], + polarity_status[device_setup.polarity], + reference_name[device_setup.reference]); + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/*! + * @brief Handle the menu to read die temperature of device + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_read_temperature(uint32_t menu_id) +{ + uint8_t chn_cnt; // current channel + uint16_t chn_mask = 0; // channels enable mask + ad717x_st_reg *device_mode_reg; // Pointer to device mode register + ad717x_st_reg *device_chnmap_reg; // Pointer to channel map register + ad717x_st_reg *device_setup_control_reg; // Pointer to setup control register + int32_t sample_data; // ADC sample result + float temperature = 0.00; // Temperature in Celcius + float conversion_result; // raw sample data to voltage conversion result + int32_t prev_adc_reg_values[3]; // Holds the previous register values + bool temperature_read_error; // Temperature read error status + + temperature_read_error = false; + + // Disable the other enabled channels to read temperature from only 0th channel + for (chn_cnt = 1; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt); + if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + temperature_read_error = true; + break; + } + + if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) { + // Save enabled channel + chn_mask |= (1 << chn_cnt); + + // Disable the curent channel + device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN); + + // Write to ADC channel register + if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + temperature_read_error = true; + break; + } + } + } + + if (temperature_read_error == false) { + // Get the pointer to device registers + device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG); + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG); + device_setup_control_reg = AD717X_GetReg(pad717x_dev, AD717X_SETUPCON0_REG); + + // Save the previous values of below registers in order to not disturb + // the user configured setup. + // *Note: This step is not required for someone who intended to just + // read temperature. It is an application specific functionality. + prev_adc_reg_values[0] = device_mode_reg->value; + prev_adc_reg_values[1] = device_chnmap_reg->value; + prev_adc_reg_values[2] = device_setup_control_reg->value; + + // Configure the channel map 0 register + // AINP = Temp + , AINM = Temp - , Setup = 0, CHN Enabled = True + device_chnmap_reg->value = + (AD717X_CHMAP_REG_AINPOS(TEMP_SENSOR_POS_INP_BITS) | + AD717X_CHMAP_REG_AINNEG(TEMP_SENSOR_NEG_INP_BITS) | + AD717X_CHMAP_REG_SETUP_SEL(0) | + AD717X_CHMAP_REG_CH_EN); + + if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG) != SUCCESS) { + printf(EOL EOL "\tError Reading Temperature!!"); + adi_press_any_key_to_continue(); + return MENU_CONTINUE; + } + + // Configure the setup control 0 register + // Polarity: Bipolar, Input Buffers: Enable, Ref: Internal + device_setup_control_reg->value = + (AD717X_SETUP_CONF_REG_BI_UNIPOLAR | + AD717X_SETUP_CONF_REG_AINBUF_P | + AD717X_SETUP_CONF_REG_AINBUF_N | + AD717X_SETUP_CONF_REG_REF_SEL(INTERNAL)); + + if (AD717X_WriteRegister(pad717x_dev, AD717X_SETUPCON0_REG) != SUCCESS) { + printf(EOL EOL "\tError Reading Temperature!!"); + adi_press_any_key_to_continue(); + return MENU_CONTINUE; + } + + // Configure the device mode register + // Internal Ref: Enable, Mode: Single Conversion (1) + device_mode_reg->value |= AD717X_ADCMODE_REG_REF_EN; + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(1)); + + if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) { + printf(EOL EOL "\tError Reading Temperature!!"); + adi_press_any_key_to_continue(); + return MENU_CONTINUE; + } + + for (uint8_t samples = 0; samples < 2; samples++) { + // Wait for conversion to complete, then obtain sample + AD717X_WaitForReady(pad717x_dev, 10000); + + if (AD717X_ReadData(pad717x_dev, &sample_data) != SUCCESS) { + temperature_read_error = true; + break; + } + } + + if (temperature_read_error == false) { + conversion_result = (((float)sample_data / (1 << (ADC_RESOLUTION - 1))) - 1) * + ADC_REF_VOLTAGE; + + // Calculate the temparture in degree celcius (sensitivity: 477uV/K) + // *Below equation is referred from the device datasheet + temperature = ((float)conversion_result / 0.000477) - 273.15; + + // All done, restore previous state of device registers + // *Note: This step is not required for someone who intended to just + // read temperature. It is an application specific functionality. + device_mode_reg->value = prev_adc_reg_values[0]; + (void)AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG); + + device_chnmap_reg->value = prev_adc_reg_values[1]; + (void)AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG); + + device_setup_control_reg->value = prev_adc_reg_values[2]; + (void)AD717X_WriteRegister(pad717x_dev, AD717X_SETUPCON0_REG); + + // Need to restore the channels those were disabled during temperaure read + for (uint8_t i = 0 ; i < NUMBER_OF_CHANNELS ; i++) { + if (chn_mask & (1 << i)) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + i); + device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN; + + if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + i) != SUCCESS) { + // continue with other channels + } + } + } + } + } + + if (temperature_read_error == false) { + printf(EOL EOL "\tTemperature: %.2f Celcius", temperature); + } else { + printf(EOL EOL "\tError Reading Temperature!!"); + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/*! + * @brief Handle the menu to calibrate the device + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_calibrate_adc(uint32_t menu_id) +{ + uint8_t chn_cnt; // Current channel + uint16_t chn_mask = 0; // Channel enable mask + ad717x_st_reg *device_chnmap_reg; // Pointer to channel map register + ad717x_st_reg *device_mode_reg; // Pointer to device mode register + bool calibration_error; // Calibration error flag + + calibration_error = false; + + for (chn_cnt = 0; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt); + if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + calibration_error = true; + break; + } + + if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) { + // Save enabled channel + chn_mask |= (1 << chn_cnt); + + // Disable the curent channel + device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN); + + if(AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + calibration_error = true; + break; + } + } + } + + if (calibration_error == false) { + // Calibrate all the channels + for (chn_cnt = 0 ; chn_cnt < NUMBER_OF_CHANNELS ; chn_cnt++) { + printf(EOL "\tCalibrating Channel %d => " EOL, chn_cnt); + + // Enable current channel + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt); + device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN; + + if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + calibration_error = true; + break; + } + + device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG); + + // Start full scale internal (gain) calibration (mode: 5) + printf("\tRunning full-scale internal calibration..." EOL); + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(5)); + + if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) { + calibration_error = true; + break; + } + + // Wait for calibration to over + if (AD717X_WaitForReady(pad717x_dev, 10000) != SUCCESS) { + calibration_error = true; + break; + } else { + // Start zero scale internal (offset) calibration (mode: 4) + printf("\tRunning zero-scale internal calibration..." EOL); + device_mode_reg->value = + ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) | + AD717X_ADCMODE_REG_MODE(4)); + + if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) { + calibration_error = true; + break; + } + + // Wait for calibration to over + if (AD717X_WaitForReady(pad717x_dev, 10000) != SUCCESS) { + printf("\tError in channel calibration..." EOL); + } else { + printf("\tCalibration Successful..." EOL); + } + } + + // Disable current channel + device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN); + + if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + calibration_error = true; + break; + } + } + } + + // Need to restore the channels that were disabled during calibration + for (chn_cnt = 0 ; chn_cnt < NUMBER_OF_CHANNELS ; chn_cnt++) { + if (chn_mask & (1 << chn_cnt)) { + // Get the pointer to channel register + device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt); + device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN; + + if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) { + // continue with other channels + } + } + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/* @brief Console menu to read/write the adc register + * @param rw_id- Read/Write ID/Operation + * @return int32_t- menu status constant + **/ +int32_t menu_rw_ad717x_register(uint32_t rw_id) +{ + uint32_t reg_address; + uint32_t reg_data; + ad717x_st_reg *device_data_reg; // Pointer to data register + + printf(EOL "\tEnter the register address (in hex): "); + reg_address = adi_get_hex_integer(sizeof(reg_address)); + + // Get the pointer to data register + device_data_reg = AD717X_GetReg(pad717x_dev, reg_address); + + if ((uint32_t)DEVICE_REG_READ_ID == rw_id) { + // Read from ADC channel register + if (AD717X_ReadRegister(pad717x_dev, reg_address) != SUCCESS) { + printf(EOL "Error reading setup!!" EOL); + } else { + reg_data = device_data_reg->value; + printf(EOL "\tRead Value: 0x%lx", reg_data); + } + } else { + printf(EOL "\tEnter the register data (in hex): "); + reg_data = adi_get_hex_integer(sizeof(reg_data)); + + device_data_reg->value = reg_data; + + if (AD717X_WriteRegister(pad717x_dev, reg_address) != SUCCESS) { + printf(EOL "\tError in writing adc register!!" EOL); + } else { + printf(EOL "\tWrite Successful..." EOL); + } + } + + adi_press_any_key_to_continue(); + return MENU_CONTINUE; +} + + +/*! + * @brief Handle the menu to read/write device registers + * @param uint32_t menu_id- (Optional parameter) + * @return MENU_CONTINUE + */ +int32_t menu_read_write_device_regs(uint32_t menu_id) +{ + return (adi_do_console_menu(®_read_write_menu)); +}