Example program for AD717x and AD411x family of products.

Dependencies:   adi_console_menu platform_drivers

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(&reg_read_write_menu));
+}