Example program for AD717x and AD411x family of products.

Dependencies:   adi_console_menu platform_drivers

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ad717x_console_app.c Source File

ad717x_console_app.c

Go to the documentation of this file.
00001 /*!
00002  *****************************************************************************
00003   @file:  ad717x_console_app.c
00004 
00005   @brief: Implementation of the menu functions which handles the
00006           functionality of AD717x and AD411x family of devices.
00007 
00008   @details: This file is specific to AD717x/AD411x console menu application handle.
00009             The functions defined in this file performs the action
00010             based on user selected console menu.
00011  -----------------------------------------------------------------------------
00012  Copyright (c) 2020-2021 Analog Devices, Inc.
00013  All rights reserved.
00014 
00015  This software is proprietary to Analog Devices, Inc. and its licensors.
00016  By using this software you agree to the terms of the associated
00017  Analog Devices Software License Agreement.
00018 *****************************************************************************/
00019 
00020 /******************************************************************************/
00021 /***************************** Include Files **********************************/
00022 /******************************************************************************/
00023 
00024 #include <stdio.h>
00025 #include <string.h>
00026 #include <stdbool.h>
00027 #include <ctype.h>
00028 
00029 #include "app_config.h"
00030 
00031 #include "ad717x.h"
00032 #include "platform_support.h"
00033 #include "spi.h"
00034 #include "spi_extra.h"
00035 
00036 #include "ad717x_console_app.h"
00037 #include "ad717x_menu_defines.h"
00038 #include "ad717x_support.h"
00039 
00040 /******************************************************************************/
00041 /********************** Macros and Constants Definitions **********************/
00042 /******************************************************************************/
00043 
00044 // Include the device register address map headers and device register map based
00045 // on the user selected device (default is AD4111)
00046 #if defined(DEV_AD4111) || defined(DEV_AD4112) || defined(DEV_AD4114) || \
00047     defined(DEV_AD4115)
00048 #include <ad411x_regs.h>
00049 static ad717x_st_reg *ad717x_device_map = ad4111_regs;
00050 static uint8_t ad717x_reg_count = sizeof(ad4111_regs) / sizeof(ad4111_regs[0]);
00051 #elif defined(DEV_AD7172_2)
00052 #include <ad7172_2_regs.h>
00053 static ad717x_st_reg *ad717x_device_map = ad7172_2_regs;
00054 static uint8_t ad717x_reg_count = sizeof(ad7172_2_regs) / sizeof(
00055         ad7172_2_regs[0]);
00056 #elif defined(DEV_AD7172_4)
00057 #include <ad7172_4_regs.h>
00058 static ad717x_st_reg *ad717x_device_map = ad7172_4_regs;
00059 static uint8_t ad717x_reg_count = sizeof(ad7172_4_regs) / sizeof(
00060         ad7172_4_regs[0]);
00061 #elif defined(DEV_AD7173_8)
00062 #include <ad7173_8_regs.h>
00063 static ad717x_st_reg *ad717x_device_map = ad7173_8_regs;
00064 static uint8_t ad717x_reg_count = sizeof(ad7173_8_regs) / sizeof(
00065         ad7173_8_regs[0]);
00066 #elif defined(DEV_AD7175_2)
00067 #include <ad7175_2_regs.h>
00068 static ad717x_st_reg *ad717x_device_map = ad7175_2_regs;
00069 static uint8_t ad717x_reg_count = sizeof(ad7175_2_regs) / sizeof(
00070         ad7175_2_regs[0]);
00071 #elif defined(DEV_AD7175_8)
00072 #include <ad7175_8_regs.h>
00073 static ad717x_st_reg *ad717x_device_map = ad7175_8_regs;
00074 static uint8_t ad717x_reg_count = sizeof(ad7175_8_regs) / sizeof(
00075         ad7175_8_regs[0]);
00076 #elif defined(DEV_AD7176_2)
00077 #include <ad7176_2_regs.h>
00078 static ad717x_st_reg *ad717x_device_map = ad7176_2_regs;
00079 static uint8_t ad717x_reg_count = sizeof(ad7176_2_regs) / sizeof(
00080         ad7176_2_regs[0]);
00081 #else
00082 #include <ad411x_regs.h>
00083 static ad717x_st_reg *ad717x_device_map = ad4111_regs;
00084 static uint8_t ad717x_reg_count = sizeof(ad4111_regs) / sizeof(ad4111_regs[0]);
00085 #endif
00086 
00087 
00088 #define SHOW_ALL_CHANNELS      false
00089 #define SHOW_ENABLED_CHANNELS  true
00090 
00091 #define DISPLAY_DATA_TABULAR    0
00092 #define DISPLAY_DATA_STREAM     1
00093 
00094 // Open wire detect ADC count threshold (eqv of 300mv for bipolar mode)
00095 #define OPEN_WIRE_DETECT_THRESHOLD  100000
00096 
00097 /******************************************************************************/
00098 /********************** Variables and User Defined Data Types *****************/
00099 /******************************************************************************/
00100 
00101 // Pointer to the struct representing the AD717x device
00102 static ad717x_dev *pad717x_dev = NULL;
00103 
00104 // Device setup
00105 static ad717x_setup_config device_setup;
00106 
00107 // User selected input (pair/positive/negative)
00108 static uint8_t input_to_select;
00109 
00110 // Last Sampled values for All ADC channels
00111 static uint32_t channel_samples[NUMBER_OF_CHANNELS] = { 0 };
00112 
00113 // How many times a given channel is sampled in total for one sample run
00114 static uint32_t channel_samples_count[NUMBER_OF_CHANNELS] = { 0 };
00115 
00116 // Variables used for open wire detection functionality
00117 static uint32_t analog_input_type;  // Analog input type
00118 static uint32_t channel_pair;       // Channel pair for open wire detection
00119 static int32_t open_wire_detect_sample_data[2]; // Sampled data for channel pair
00120 
00121 /******************************************************************************/
00122 /************************ Functions Declarations ******************************/
00123 /******************************************************************************/
00124 
00125 static bool was_escape_key_pressed(void);
00126 
00127 /******************************************************************************/
00128 /************************ Functions Definitions *******************************/
00129 /******************************************************************************/
00130 
00131 /*!
00132  * @brief      Initialize the AD717x device and associated low level peripherals
00133  * @return     SUCCESS(0) Or FAILURE(negative)
00134  */
00135 int32_t ad717x_app_initialize(void)
00136 {
00137     // Init SPI extra parameters structure
00138     mbed_spi_init_param spi_init_extra_params = {
00139         .spi_clk_pin = SPI_SCK,
00140         .spi_miso_pin = SPI_MISO,
00141         .spi_mosi_pin = SPI_MOSI
00142     };
00143 
00144     // Used to create the ad717x device
00145     ad717x_init_param ad717x_init = {
00146         // spi_init_param type
00147         {
00148             .max_speed_hz = 2500000,            // Max SPI Speed
00149             .chip_select = SPI_SS,              // Chip Select pin
00150             .mode = SPI_MODE_3,                 // CPOL = 1, CPHA =1
00151             .extra = &spi_init_extra_params     // SPI extra configurations
00152         },
00153         ad717x_device_map,      // pointer to device register map
00154         ad717x_reg_count,       // number of device registers
00155     };
00156 
00157     // Initialze the device
00158     return (AD717X_Init(&pad717x_dev, ad717x_init));
00159 }
00160 
00161 
00162 /*!
00163  * @brief      determines if the Escape key was pressed
00164  * @return     key press status
00165  */
00166 static bool was_escape_key_pressed(void)
00167 {
00168     char rxChar;
00169     bool wasPressed = false;
00170 
00171     // Check for Escape key pressed
00172     if ((rxChar = getchar_noblock()) > 0) {
00173         if (rxChar == ESCAPE_KEY_CODE) {
00174             wasPressed = true;
00175         }
00176     }
00177 
00178     return (wasPressed);
00179 }
00180 
00181 
00182 /* @brief  Perform the channel selection
00183  * @return Selected channel
00184  **/
00185 static uint8_t get_channel_selection(void)
00186 {
00187     uint32_t current_channel = 0;
00188     bool current_selection_done = false;
00189 
00190     do {
00191         printf(EOL "\tEnter Channel Value <0-%d>: ", NUMBER_OF_CHANNELS-1);
00192         current_channel = adi_get_decimal_int(sizeof(current_channel));
00193 
00194         if (current_channel < NUMBER_OF_CHANNELS) {
00195             current_selection_done = true;
00196         } else {
00197             printf(EOL "\tInvalid channel selection!!" EOL);
00198         }
00199     } while (current_selection_done == false);
00200 
00201     return current_channel;
00202 }
00203 
00204 
00205 /* @brief  Perform the setup selection
00206  * @return Selected setup
00207  **/
00208 static uint8_t get_setup_selection(void)
00209 {
00210     uint32_t current_setup = 0;
00211     bool current_selection_done = false;
00212 
00213     do {
00214         printf(EOL "\tEnter Setup Selection <0-%d>: ", NUMBER_OF_SETUPS-1);
00215         current_setup = adi_get_decimal_int(sizeof(current_setup));
00216 
00217         if (current_setup < NUMBER_OF_SETUPS) {
00218             current_selection_done = true;
00219         } else {
00220             printf(EOL "\tInvalid setup selection!!" EOL);
00221         }
00222     } while (current_selection_done == false);
00223 
00224     return current_setup;
00225 }
00226 
00227 
00228 /* @brief  Assign setup to adc channel
00229  * @param  setup to be assigned
00230  **/
00231 static void assign_setup_to_channel(uint8_t setup)
00232 {
00233     uint8_t current_channel;       // channel to be assigned with setup
00234     ad717x_st_reg *device_chnmap_reg;   // pointer to channel map register
00235 
00236     adi_clear_console();
00237 
00238     // Get the channel selection
00239     current_channel = get_channel_selection();
00240 
00241     // Get the pointer to channel map register structure
00242     device_chnmap_reg = AD717X_GetReg(pad717x_dev,
00243                       AD717X_CHMAP0_REG + current_channel);
00244 
00245     // Load the setup value
00246     device_chnmap_reg->value =
00247         ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_SETUP_SEL_MSK) |
00248          AD717X_CHMAP_REG_SETUP_SEL(setup));
00249 
00250     if (AD717X_WriteRegister(pad717x_dev,
00251                  AD717X_CHMAP0_REG + current_channel) != SUCCESS) {
00252         printf(EOL "\tError in setup assignment!!" EOL);
00253     } else {
00254         printf(EOL "\tSetup %d is assigned to channel %d successfully..." EOL,
00255                setup,
00256                current_channel);
00257     }
00258 
00259     adi_press_any_key_to_continue();
00260 }
00261 
00262 
00263 /* @brief  Select adc channel to be assigned to setup
00264  * @return  none
00265  **/
00266 static char select_chn_assignment(void)
00267 {
00268     bool current_selection_done = false;
00269     char rx_char;
00270 
00271     do {
00272         printf(EOL EOL "\tDo you want to assign setup to a channel (y/n)?: ");
00273         rx_char = toupper(getchar());
00274 
00275         if (rx_char == 'Y') {
00276             assign_setup_to_channel(device_setup.setup);
00277             current_selection_done = true;
00278         } else if (rx_char == 'N') {
00279             current_selection_done = true;
00280         } else {
00281             printf(EOL "\tInvalid entry!!");
00282         }
00283     } while (current_selection_done == false);
00284 
00285     return rx_char;
00286 }
00287 
00288 
00289 /*!
00290  * @brief      Display the header info for main menu
00291  * @return     None
00292  */
00293 void display_main_menu_header(void)
00294 {
00295     // Display the device name
00296     printf(EOL "\tDevice: %s" EOL, ACTIVE_DEVICE_NAME);
00297 }
00298 
00299 
00300 /*!
00301  * @brief      Handle the menu to read device ID
00302  * @param      menu_id- (Optional parameter)
00303  * @return     MENU_CONTINUE
00304  */
00305 int32_t menu_read_id(uint32_t menu_id)
00306 {
00307     ad717x_st_reg *device_id_reg;   // Pointer to register
00308 
00309     device_id_reg = AD717X_GetReg(pad717x_dev, AD717X_ID_REG);
00310     if (!device_id_reg) {
00311         printf(EOL EOL "\tError reading device ID!!" EOL);
00312     } else {
00313         if (AD717X_ReadRegister(pad717x_dev, AD717X_ID_REG) != SUCCESS) {
00314             printf(EOL EOL "\tError reading device ID!!" EOL);
00315         } else {
00316             printf(EOL EOL "\tDevice ID: 0x%lx" EOL, device_id_reg->value);
00317         }
00318     }
00319 
00320     adi_press_any_key_to_continue();
00321     return MENU_CONTINUE;
00322 }
00323 
00324 
00325 /*!
00326  * @brief      Handle the menu to read device status register
00327  * @param      menu_id- (Optional parameter)
00328  * @return     MENU_CONTINUE
00329  */
00330 int32_t menu_read_status(uint32_t menu_id)
00331 {
00332     ad717x_st_reg *device_status_reg;   // Pointer to register
00333 
00334     device_status_reg = AD717X_GetReg(pad717x_dev, AD717X_STATUS_REG);
00335     if (!device_status_reg) {
00336         printf(EOL EOL "\tError reading status register!!" EOL);
00337     } else {
00338         if (AD717X_ReadRegister(pad717x_dev, AD717X_STATUS_REG) != SUCCESS) {
00339             printf(EOL EOL "\tError reading status register!!" EOL);
00340         } else {
00341             printf(EOL EOL "\tStatus Register: 0x%lx" EOL, device_status_reg->value);
00342         }
00343     }
00344 
00345     adi_press_any_key_to_continue();
00346     return MENU_CONTINUE;
00347 }
00348 
00349 
00350 /*
00351  * @brief helper function get the bipolar setting for an ADC channel
00352  *
00353  * @param dev The device structure.
00354  *
00355  * @param channel ADC channel to get bipolar mode for.
00356  *
00357  * @return value of bipolar field in the setup for an ADC channel.
00358  */
00359 static bool ad717x_get_channel_bipolar(ad717x_dev *dev, uint8_t channel)
00360 {
00361     ad717x_st_reg *device_setup_reg;    // Pointer to device setup register
00362     ad717x_st_reg *device_chnmap_reg;   // Pointer to device channelmap register
00363     uint8_t polarity;                   // Polarity status flag
00364     uint8_t setup;                      // Current setup
00365 
00366     device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + channel);
00367     (void)AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + channel);
00368 
00369     // Read the setup value for the current channel
00370     setup = AD717X_CHMAP_REG_SETUP_SEL_RD(device_chnmap_reg->value);
00371 
00372     device_setup_reg = AD717X_GetReg(pad717x_dev, AD717X_SETUPCON0_REG + setup);
00373     (void)AD717X_ReadRegister(pad717x_dev, AD717X_SETUPCON0_REG + setup);
00374 
00375     // Get the polarity bit for current setup
00376     polarity = AD717X_SETUP_CONF_REG_BI_UNIPOLAR_RD(device_setup_reg->value);
00377 
00378     if (polarity == BIPOLAR) {
00379         return true;
00380     } else {
00381         return false;
00382     }
00383 }
00384 
00385 
00386 /*
00387  * @brief converts ADC sample value to voltage based on gain setting
00388  *
00389  * @param dev The device structure.
00390  *
00391  * @param channel ADC channel to get Setup for.
00392  *
00393  * @param sample Raw ADC sample
00394  *
00395  * @return Sample ADC value converted to voltage.
00396  *
00397  * @note The conversion equation is implemented for simplicity,
00398  *       not for accuracy or performance
00399  *
00400  */
00401 static float ad717x_convert_sample_to_voltage(ad717x_dev *dev,
00402         uint8_t channel,
00403         uint32_t sample)
00404 {
00405     float converted_value;
00406     bool is_bipolar = ad717x_get_channel_bipolar(dev, channel);
00407 
00408     if (is_bipolar) {
00409         converted_value = (((float)sample / (1 << (ADC_RESOLUTION - 1))) - 1) *
00410                   ADC_REF_VOLTAGE;
00411     } else {
00412         converted_value = (((float)sample * ADC_REF_VOLTAGE) / (1 << ADC_RESOLUTION));
00413     }
00414 
00415     return (converted_value);
00416 }
00417 
00418 
00419 /*!
00420  * @brief      displays the current sample value for a ADC channels
00421  *
00422  * @param showOnlyEnabledChannels  only channels that are enabled are displayed
00423  *
00424  */
00425 static void dislay_channel_samples(bool showOnlyEnabledChannels,
00426                    uint8_t console_mode)
00427 {
00428     ad717x_st_reg *device_chnmap_reg;   // Pointer to channel map register
00429     bool channel_printed = false;       // Channel print status flag
00430 
00431     switch (console_mode) {
00432     case DISPLAY_DATA_TABULAR:
00433         printf("\tCh\tValue\t\tCount\t\tVoltage" EOL);
00434         for (uint8_t chn = 0; chn < NUMBER_OF_CHANNELS; chn++) {
00435             // Get the pointer to channel register
00436             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn);
00437 
00438             // if showing all channels, or channel is enabled
00439             if ((showOnlyEnabledChannels == false)
00440                 || (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN)) {
00441                 printf("\t%-2d\t%-10ld\t%ld\t\t% .6f" EOL,
00442                        chn,
00443                        channel_samples[chn],
00444                        channel_samples_count[chn],
00445                        ad717x_convert_sample_to_voltage(pad717x_dev, chn, channel_samples[chn]));
00446             }
00447         }
00448         break;
00449 
00450     case DISPLAY_DATA_STREAM:
00451         // Output a CSV list of the sampled channels as voltages on a single line
00452         for (uint8_t chn = 0 ; chn < NUMBER_OF_CHANNELS; chn++) {
00453             // Get the pointer to channel register
00454             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn);
00455 
00456             // if showing all channels, or channel is enabled
00457             if ((showOnlyEnabledChannels == false) ||
00458                 (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN)) {
00459                 /*
00460                     *  add the comma before we output the next channel but
00461                     *  only if at least one channel has been printed
00462                     */
00463                 if (channel_printed) {
00464                     printf(", ");
00465                 }
00466 
00467                 printf("%.6f", ad717x_convert_sample_to_voltage(pad717x_dev, chn,
00468                         channel_samples[chn]));
00469 
00470                 channel_printed = true;
00471             }
00472         }
00473         printf(EOL);
00474         break;
00475 
00476     default:
00477         break;
00478     }
00479 }
00480 
00481 
00482 /*!
00483  * @brief      resets the channelSampleCounts to zero
00484  *
00485  * @details
00486  */
00487 static void clear_channel_samples(void)
00488 {
00489     for (uint8_t i = 0; i < NUMBER_OF_CHANNELS; i++) {
00490         channel_samples[i] = 0;
00491         channel_samples_count[i] = 0;
00492     }
00493 }
00494 
00495 
00496 /*!
00497  * @brief      Continuously acquires samples in Continuous Conversion mode
00498  *
00499  * @details   The ADC is run in continuous mode, and all samples are acquired
00500  *            and assigned to the channel they come from. Escape key an be used
00501  *            to exit the loop
00502  */
00503 static int32_t do_continuous_conversion(uint8_t display_mode)
00504 {
00505     int32_t error_code;
00506     int32_t sample_data;
00507     ad717x_st_reg *device_mode_reg;
00508     ad717x_st_reg *device_chnmap_reg;
00509     ad717x_st_reg *device_status_reg;
00510 
00511     // Get the pointer to mode register
00512     device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG);
00513 
00514     // Clear the ADC CTRL MODE bits, has the effect of selecting continuous mode
00515     device_mode_reg->value &= ~(AD717X_ADCMODE_REG_MODE(0xf));
00516 
00517     if ((error_code = AD717X_WriteRegister(pad717x_dev,
00518                            AD717X_ADCMODE_REG)) != SUCCESS) {
00519         printf("Error (%ld) setting AD717x Continuous conversion mode." EOL,
00520                error_code);
00521 
00522         adi_press_any_key_to_continue();
00523         return (MENU_CONTINUE);
00524     }
00525 
00526     clear_channel_samples();
00527 
00528     /*
00529      *  If displaying data in stream form, want to output a channel header
00530      */
00531     if (display_mode == DISPLAY_DATA_STREAM) {
00532         bool channel_printed = false;
00533 
00534         for (uint8_t chn = 0; chn < NUMBER_OF_CHANNELS; chn++) {
00535             // Get the pointer to channel register
00536             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn);
00537 
00538             // if showing all channels, or channel is enabled
00539             if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) {
00540                 /*
00541                  *  add the comma before we output the next channel but
00542                  *  only if at least one channel has been printed
00543                  */
00544                 if (channel_printed) {
00545                     printf(", ");
00546                 }
00547                 printf("%d", chn);
00548             }
00549             channel_printed = true;
00550         }
00551         printf(EOL);
00552     }
00553 
00554     // Continuously read the channels, and store sample values
00555     while (was_escape_key_pressed() != true) {
00556         if (display_mode == DISPLAY_DATA_TABULAR) {
00557             adi_clear_console();
00558             printf("Running continuous conversion mode...\r\nPress Escape to stop" EOL EOL);
00559         }
00560 
00561         /*
00562          *  this polls the status register READY/ bit to determine when conversion is done
00563          *  this also ensures the STATUS register value is up to date and contains the
00564          *  channel that was sampled as well.
00565          *  Generally, no need to read STATUS separately, but for faster sampling
00566          *  enabling the DATA_STATUS bit means that status is appended to ADC data read
00567          *  so the channel being sampled is read back (and updated) as part of the same frame
00568          */
00569         if ((error_code = AD717X_WaitForReady(pad717x_dev, 10000)) != SUCCESS) {
00570             printf("Error/Timeout waiting for conversion ready %ld" EOL EOL, error_code);
00571             continue;
00572         }
00573 
00574         if ((error_code = AD717X_ReadData(pad717x_dev, &sample_data)) != SUCCESS) {
00575             printf("Error reading ADC Data (%ld)." EOL, error_code);
00576             continue;
00577         }
00578 
00579         /*
00580          * No error, need to process the sample, what channel has been read? update that channelSample
00581          */
00582         device_status_reg = AD717X_GetReg(pad717x_dev, AD717X_STATUS_REG);
00583         uint8_t channelRead = device_status_reg->value & 0x0000000F;
00584 
00585         if (channelRead < NUMBER_OF_CHANNELS) {
00586             channel_samples[channelRead] = sample_data;
00587             channel_samples_count[channelRead]++;
00588         } else {
00589             printf("Channel Read was %d, which is not < %d" EOL,
00590                    channelRead,
00591                    NUMBER_OF_CHANNELS);
00592         }
00593 
00594         dislay_channel_samples(SHOW_ENABLED_CHANNELS, display_mode);
00595     }
00596 
00597     // All done, ADC put into standby mode
00598     device_mode_reg->value =
00599         ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
00600          AD717X_ADCMODE_REG_MODE(STANDBY_MODE));
00601 
00602     if ((error_code = AD717X_WriteRegister(pad717x_dev,
00603                            AD717X_ADCMODE_REG)) != SUCCESS) {
00604         printf("Error (%ld) setting ADC into standby mode." EOL, error_code);
00605         adi_press_any_key_to_continue();
00606     }
00607 
00608     return (MENU_CONTINUE);
00609 }
00610 
00611 
00612 /*!
00613  * @brief      Samples all enabled channels and displays in tabular form
00614  *
00615  * @details
00616  */
00617 int32_t menu_continuous_conversion_tabular(uint32_t channel_id)
00618 {
00619     do_continuous_conversion(DISPLAY_DATA_TABULAR);
00620 
00621     adi_clear_console();
00622     printf("Continuous Conversion completed..." EOL EOL);
00623     dislay_channel_samples(SHOW_ALL_CHANNELS, DISPLAY_DATA_TABULAR);
00624     adi_press_any_key_to_continue();
00625 
00626     return (MENU_CONTINUE);
00627 }
00628 
00629 
00630 /*!
00631  * @brief      Samples all enabled channels and displays on the console
00632  *
00633  * @details
00634  */
00635 int32_t menu_continuous_conversion_stream(uint32_t channel_id)
00636 {
00637     do_continuous_conversion(DISPLAY_DATA_STREAM);
00638     printf("Continuous Conversion completed..." EOL EOL);
00639 
00640     adi_press_any_key_to_continue();
00641     return (MENU_CONTINUE);
00642 }
00643 
00644 
00645 /*!
00646  * @brief      Samples all enabled channels once in Single Conversion mode
00647  *
00648  * @details    This stores all channels that are enabled in a bitmask, and then
00649  *             runs the ADC in single conversion mode, which acquires one channel
00650  *             of data at a time. After capture, that channel is disabled, and
00651  *             single conversion run again, until no channels are enabled.
00652  *             The original enable state of each channel is then restored.
00653  */
00654 int32_t menu_single_conversion(uint32_t channel_id)
00655 {
00656     int32_t    error_code;
00657     uint16_t   channel_enable_mask = 0;
00658     uint8_t    channel_count = 0;
00659     int32_t    sample_data;
00660     ad717x_st_reg *device_chnmap_reg;
00661     ad717x_st_reg *device_mode_reg;
00662     ad717x_st_reg *device_status_reg;
00663 
00664     // Need to store which channels are enabled in this config so it can be restored
00665     for (uint8_t chn = 0 ; chn < NUMBER_OF_CHANNELS; chn++) {
00666         // Get the pointer to channel register
00667         device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn);
00668 
00669         if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) {
00670             channel_enable_mask |= (1 << chn);
00671             channel_count++;
00672         }
00673     }
00674 
00675     clear_channel_samples();
00676 
00677     adi_clear_console();
00678     printf("Running Single conversion mode...\r\nPress Escape to stop" EOL EOL);
00679 
00680     // Get the pointer to mode register
00681     device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG);
00682 
00683     // Clear the ADC CTRL MODE bits, selecting continuous mode
00684     device_mode_reg->value =
00685         ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
00686          AD717X_ADCMODE_REG_MODE(CONTINUOUS_CONVERSION));
00687 
00688     // read the channels, and store sample values
00689     for(uint8_t loopCount = 0 ; ((was_escape_key_pressed() != true)
00690                      && (loopCount < channel_count)) ; loopCount++) {
00691 
00692         device_mode_reg->value =
00693             ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
00694              AD717X_ADCMODE_REG_MODE(SINGLE_CONVERISION));
00695 
00696         if ((error_code = AD717X_WriteRegister(pad717x_dev,
00697                                AD717X_ADCMODE_REG)) != SUCCESS) {
00698             printf("Error (%ld) setting AD717x Single conversion mode." EOL, error_code);
00699             adi_press_any_key_to_continue();
00700             continue;
00701         }
00702 
00703         /*
00704          *  this polls the status register READY/ bit to determine when conversion is done
00705          *  this also ensures the STATUS register value is up to date and contains the
00706          *  channel that was sampled as well. No need to read STATUS separately
00707          */
00708         if ((error_code = AD717X_WaitForReady(pad717x_dev, 10000)) != SUCCESS) {
00709             printf("Error/Timeout waiting for conversion ready %ld" EOL, error_code);
00710             continue;
00711         }
00712 
00713         if ((error_code = AD717X_ReadData(pad717x_dev, &sample_data)) != SUCCESS) {
00714             printf("Error reading ADC Data (%ld)." EOL, error_code);
00715             continue;
00716         }
00717 
00718         /*
00719          * No error, need to process the sample, what channel has been read? update that channelSample
00720          */
00721         device_status_reg = AD717X_GetReg(pad717x_dev, AD717X_STATUS_REG);
00722         uint8_t channelRead = device_status_reg->value & 0x0000000F;
00723 
00724         if (channelRead < NUMBER_OF_CHANNELS) {
00725             channel_samples[channelRead] = sample_data;
00726             channel_samples_count[channelRead]++;
00727 
00728             // Get the pointer to channel register
00729             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + channelRead);
00730 
00731             /* also need to clear the channel enable bit so the next single conversion cycle will sample the next channel */
00732             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
00733             if ((error_code = AD717X_WriteRegister(pad717x_dev,
00734                                    AD717X_CHMAP0_REG + channelRead)) != SUCCESS) {
00735                 printf("Error (%ld) Clearing channel %d Enable bit." EOL,
00736                        error_code,
00737                        channelRead);
00738 
00739                 adi_press_any_key_to_continue();
00740                 continue;
00741             }
00742         } else {
00743             printf("Channel Read was %d, which is not < AD717x_CHANNEL_COUNT" EOL,
00744                    channelRead);
00745         }
00746     }
00747 
00748     // All done, ADC put into standby mode
00749     device_mode_reg->value =
00750         ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
00751          AD717X_ADCMODE_REG_MODE(STANDBY_MODE));
00752 
00753     // Need to restore the channels that were disabled during acquisition
00754     for(uint8_t chn = 0 ; chn < NUMBER_OF_CHANNELS ; chn++) {
00755         if (channel_enable_mask & (1 << chn)) {
00756             // Get the pointer to channel register
00757             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn);
00758 
00759             device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
00760 
00761             if ((error_code = AD717X_WriteRegister(pad717x_dev,
00762                                    AD717X_CHMAP0_REG + chn)) != SUCCESS) {
00763                 printf("Error (%ld) Setting channel %d Enable bit" EOL EOL, error_code, chn);
00764 
00765                 adi_press_any_key_to_continue();
00766                 return (MENU_CONTINUE);
00767             }
00768         }
00769     }
00770 
00771     printf("Single Conversion completed..." EOL EOL);
00772     dislay_channel_samples(SHOW_ENABLED_CHANNELS, DISPLAY_DATA_TABULAR);
00773 
00774     adi_press_any_key_to_continue();
00775     return (MENU_CONTINUE);
00776 }
00777 
00778 
00779 /*!
00780  * @brief      Handle the menu to sample the channels
00781  * @param      menu_id- (Optional parameter)
00782  * @return     MENU_CONTINUE
00783  */
00784 int32_t menu_sample_channels(uint32_t menu_id)
00785 {
00786     return adi_do_console_menu(&acquisition_menu);
00787 }
00788 
00789 
00790 /* @brief  Enable or disable adc channels
00791  * @param  channel ENABLE/DISABLE action
00792  * @return MENU_CONTINUE
00793  **/
00794 int32_t menu_channels_enable_disable(uint32_t action)
00795 {
00796     char rx_char;                // received character from the serial port
00797     uint8_t current_channel;     // channel to be enabled
00798     ad717x_st_reg *device_chnmap_reg;   // Pointer to channel map register
00799 
00800     do {
00801         // Get the channel selection
00802         current_channel = get_channel_selection();
00803 
00804         // Get the pointer to channel register
00805         device_chnmap_reg = AD717X_GetReg(pad717x_dev,
00806                           AD717X_CHMAP0_REG + current_channel);
00807 
00808         if (action == SELECT_ENABLE) {
00809             // Enable the selected channel
00810             device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
00811             printf("\tChannel %d is Enabled ", current_channel);
00812         } else {
00813             // Disable the selected channel
00814             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
00815             printf("\tChannel %d is Disabled ", current_channel);
00816         }
00817 
00818         // Write to ADC channel register
00819         if (AD717X_WriteRegister(pad717x_dev,
00820                      AD717X_CHMAP0_REG + current_channel) != SUCCESS) {
00821             printf("\tError in channel Enable/Disable!!" EOL);
00822             break;
00823         }
00824 
00825         printf(EOL EOL "\tDo you want to continue (y/n)?: ");
00826         rx_char = toupper(getchar());
00827 
00828         if ((rx_char != 'N') && (rx_char != 'Y')) {
00829             printf("Invalid entry!!" EOL);
00830         } else {
00831             // Print the entered character back on console window (serial port)
00832             printf("%c" EOL, rx_char);
00833         }
00834     } while (rx_char != 'N');
00835 
00836     return MENU_CONTINUE;
00837 }
00838 
00839 
00840 /*!
00841  * @brief      Display the menu to enable/disable channel selection
00842  * @param      menu_id- (Optional parameter)
00843  * @return     MENU_CONTINUE
00844  */
00845 int32_t menu_chn_enable_disable_display(uint32_t menu_id)
00846 {
00847     return adi_do_console_menu(&chn_enable_disable_menu);
00848 }
00849 
00850 
00851 /*!
00852  * @brief      Handle the menu to connect input to channel
00853  * @param      analog input to be connected
00854  * @return     MENU_CONTINUE
00855  */
00856 int32_t menu_analog_input_connect(uint32_t user_analog_input)
00857 {
00858     uint8_t current_channel;            // current channel
00859     ad717x_st_reg *device_chnmap_reg;   // Pointer to channel map register
00860 
00861     adi_clear_console();
00862 
00863     // Get the channel selection
00864     current_channel = get_channel_selection();
00865 
00866     if (input_to_select == POS_ANALOG_INP_SELECT) {
00867         printf(EOL "\tSelect Positive Analog Input" EOL);
00868         device_setup.pos_analog_input = user_analog_input;
00869     } else if (input_to_select == NEG_ANALOG_INP_SELECT) {
00870         printf(EOL "\tSelect Negative Analog Input" EOL);
00871         device_setup.neg_analog_input = user_analog_input;
00872     } else {
00873         device_setup.pos_analog_input = AD717X_CHMAP_REG_AINPOS_RD(user_analog_input);
00874         device_setup.neg_analog_input = AD717X_CHMAP_REG_AINNEG_RD(user_analog_input);
00875     }
00876 
00877     // Get the pointer to channel map register structure
00878     device_chnmap_reg = AD717X_GetReg(pad717x_dev,
00879                       AD717X_CHMAP0_REG + current_channel);
00880 
00881 #if defined(DEV_AD4111) || defined(DEV_AD4112) || defined(DEV_AD4114) || \
00882     defined(DEV_AD4115)
00883     // Select analog input pair
00884     device_chnmap_reg->value =
00885         ((device_chnmap_reg->value & ~AD4111_CHMAP_REG_INPUT_MSK) |
00886          AD4111_CHMAP_REG_INPUT(user_analog_input));
00887 #elif
00888     // Select positive analog input
00889     device_chnmap_reg->value =
00890         ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_AINPOS_MSK) |
00891          AD717X_CHMAP_REG_AINPOS(device_setup.pos_analog_input));
00892 
00893     // Select negative analog input
00894     device_chnmap_reg->value =
00895         ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_AINNEG_MSK) |
00896          AD717X_CHMAP_REG_AINNEG(device_setup.neg_analog_input));
00897 #endif
00898 
00899     // Write to ADC channel register
00900     if (AD717X_WriteRegister(pad717x_dev,
00901                  AD717X_CHMAP0_REG + current_channel) != SUCCESS) {
00902         printf(EOL "\tError in analog input connection!!" EOL);
00903     } else {
00904         printf(EOL "\t%s is connected to INP+ and %s is connectd to INP- for channel %d"
00905                EOL
00906                EOL,
00907                input_pin_map[device_setup.pos_analog_input],
00908                input_pin_map[device_setup.neg_analog_input],
00909                current_channel);
00910     }
00911 
00912     adi_press_any_key_to_continue();
00913     return MENU_CONTINUE;
00914 }
00915 
00916 
00917 /*!
00918  * @brief      Display the menu selections to connect analog input pins to a channel
00919  * @param      menu_id- (Optional parameter)
00920  * @return     MENU_CONTINUE
00921  */
00922 int32_t menu_input_chn_connect_display(uint32_t menu_id)
00923 {
00924 #if defined(DEV_AD4111) || defined(DEV_AD4112) || defined(DEV_AD4114) || \
00925     defined(DEV_AD4115)
00926     input_to_select = ANALOG_INP_PAIR_SELECT;
00927     adi_do_console_menu(&analog_input_connect_menu);
00928 #else
00929     input_to_select = POS_ANALOG_INP_SELECT;
00930     adi_do_console_menu(&analog_input_connect_menu);
00931 
00932     input_to_select = NEG_ANALOG_INP_SELECT;
00933     adi_do_console_menu(&analog_input_connect_menu);
00934 #endif
00935 
00936     return MENU_CONTINUE;
00937 }
00938 
00939 
00940 /*!
00941  * @brief      Handle the menu to select the filter type
00942  * @param      user selected filter type
00943  * @return     MENU_DONE
00944  */
00945 int32_t menu_filter_select(uint32_t user_input_filter_type)
00946 {
00947     ad717x_st_reg *device_filter_config_reg;    // Pointer to filter config register
00948 
00949     // Get the pointer to filter config register structure
00950     device_filter_config_reg = AD717X_GetReg(pad717x_dev,
00951                    AD717X_FILTCON0_REG + device_setup.setup);
00952 
00953     device_setup.filter = user_input_filter_type;
00954 
00955     device_filter_config_reg->value =
00956         ((device_filter_config_reg->value & ~AD717X_FILT_CONF_REG_ORDER_MSK) |
00957          AD717X_FILT_CONF_REG_ORDER(device_setup.filter));
00958 
00959     if (device_setup.filter == SINC3_FILTER) {
00960         device_filter_config_reg->value |= AD717X_FILT_CONF_REG_SINC3_MAP;
00961     } else {
00962         device_filter_config_reg->value &= (~AD717X_FILT_CONF_REG_SINC3_MAP);
00963     }
00964 
00965     if (AD717X_WriteRegister(pad717x_dev,
00966                  AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) {
00967         printf(EOL "\tError in Filter Selection!!" EOL);
00968         adi_press_any_key_to_continue();
00969     }
00970 
00971     return MENU_DONE;
00972 }
00973 
00974 
00975 /*!
00976  * @brief      Handle the menu to enable/disable the post filter
00977  * @param      user selected action
00978  * @return     MENU_DONE
00979  */
00980 int32_t menu_postfiler_enable_disable(uint32_t user_action)
00981 {
00982     ad717x_st_reg *device_filter_config_reg;    // Pointer to filter config register
00983 
00984     // Get the pointer to filter config register structure
00985     device_filter_config_reg = AD717X_GetReg(pad717x_dev,
00986                    AD717X_FILTCON0_REG + device_setup.setup);
00987 
00988     if (user_action == SELECT_ENABLE) {
00989         device_setup.post_filter_enabled = SELECT_ENABLE;
00990         device_filter_config_reg->value |= AD717X_FILT_CONF_REG_ENHFILTEN;
00991     } else {
00992         device_setup.post_filter_enabled = SELECT_DISBLE;
00993         device_filter_config_reg->value &= (~AD717X_FILT_CONF_REG_ENHFILTEN);
00994     }
00995 
00996     if (AD717X_WriteRegister(pad717x_dev,
00997                  AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) {
00998         printf(EOL "\tError in Enabling/Disabling Postfilter!!" EOL);
00999         adi_press_any_key_to_continue();
01000     }
01001 
01002     return MENU_DONE;
01003 }
01004 
01005 
01006 /*!
01007  * @brief      Handle the menu to select the post filter
01008  * @param      user selected post filter type
01009  * @return     MENU_DONE
01010  */
01011 int32_t menu_postfiler_select(uint32_t user_input_post_filter_type)
01012 {
01013     ad717x_st_reg *device_filter_config_reg;    // Pointer to filter config register
01014 
01015     // Get the pointer to filter config register structure
01016     device_filter_config_reg = AD717X_GetReg(pad717x_dev,
01017                    AD717X_FILTCON0_REG + device_setup.setup);
01018 
01019     device_setup.postfilter = user_input_post_filter_type;
01020 
01021     device_filter_config_reg->value =
01022         ((device_filter_config_reg->value & ~AD717X_FILT_CONF_REG_ENHFILT_MSK) |
01023          AD717X_FILT_CONF_REG_ENHFILT(device_setup.postfilter));
01024 
01025     if (AD717X_WriteRegister(pad717x_dev,
01026                  AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) {
01027         printf(EOL "\tError in Post-Filter Selection!!" EOL);
01028         adi_press_any_key_to_continue();
01029     }
01030 
01031     return MENU_DONE;
01032 }
01033 
01034 
01035 /*!
01036  * @brief      Handle the menu to select the ODR value
01037  * @param      user selected ODR
01038  * @return     MENU_DONE
01039  */
01040 int32_t menu_odr_select(uint32_t user_input_odr_val)
01041 {
01042     ad717x_st_reg *device_filter_config_reg;    // Pointer to filter config register
01043 
01044     // Get the pointer to filter config register structure
01045     device_filter_config_reg = AD717X_GetReg(pad717x_dev,
01046                    AD717X_FILTCON0_REG + device_setup.setup);
01047 
01048     device_setup.odr_bits = user_input_odr_val;
01049 
01050     device_filter_config_reg->value =
01051         ((device_filter_config_reg->value & ~AD717X_FILT_CONF_REG_ODR_MSK) |
01052          AD717X_FILT_CONF_REG_ODR(device_setup.odr_bits));
01053 
01054     if (AD717X_WriteRegister(pad717x_dev,
01055                  AD717X_FILTCON0_REG + device_setup.setup) != SUCCESS) {
01056         printf(EOL "\tError in ODR Selection!!" EOL);
01057         adi_press_any_key_to_continue();
01058     }
01059 
01060     return MENU_DONE;
01061 }
01062 
01063 
01064 /*!
01065  * @brief      Handle the menu to select the polarity
01066  * @param      user selected polarity
01067  * @return     MENU_DONE
01068  */
01069 int32_t menu_polarity_select(uint32_t user_input_polarity)
01070 {
01071     ad717x_st_reg *device_setup_control_reg;    // Pointer to setup control register
01072 
01073     // Get the pointer to setup control register structure
01074     device_setup_control_reg = AD717X_GetReg(pad717x_dev,
01075                    AD717X_SETUPCON0_REG + device_setup.setup);
01076 
01077     if (user_input_polarity == BIPOLAR) {
01078         device_setup.polarity = BIPOLAR;
01079         device_setup_control_reg->value |= AD717X_SETUP_CONF_REG_BI_UNIPOLAR;
01080     } else {
01081         device_setup.polarity = UNIPOLAR;
01082         device_setup_control_reg->value &= (~AD717X_SETUP_CONF_REG_BI_UNIPOLAR);
01083     }
01084 
01085     if (AD717X_WriteRegister(pad717x_dev,
01086                  AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) {
01087         printf(EOL "\tError in Polarity Selection!!" EOL);
01088         adi_press_any_key_to_continue();
01089     }
01090 
01091     return MENU_DONE;
01092 }
01093 
01094 
01095 /*!
01096  * @brief      Handle the menu to select the reference source
01097  * @param      user selected reference source
01098  * @return     MENU_DONE
01099  */
01100 int32_t menu_reference_source_select(uint32_t user_input_reference)
01101 {
01102     ad717x_st_reg *device_setup_control_reg;    // Pointer to setup control register
01103     ad717x_st_reg *device_mode_reg;             // Pointer to adc mode register
01104 
01105     device_setup.reference = user_input_reference;
01106 
01107     // Get the pointer to device mode register structure
01108     device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG);
01109 
01110     if (device_setup.reference == INTERNAL) {
01111         device_mode_reg->value |= AD717X_ADCMODE_REG_REF_EN;
01112     } else {
01113         device_mode_reg->value &= (~AD717X_ADCMODE_REG_REF_EN);
01114     }
01115 
01116     if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) {
01117         printf(EOL "\tError in Polarity Selection!!" EOL);
01118         adi_press_any_key_to_continue();
01119         return MENU_CONTINUE;
01120     }
01121 
01122     // Get the pointer to setup control register structure
01123     device_setup_control_reg = AD717X_GetReg(pad717x_dev,
01124                    AD717X_SETUPCON0_REG + device_setup.setup);
01125 
01126     device_setup_control_reg->value =
01127         ((device_setup_control_reg->value & ~AD717X_SETUP_CONF_REG_REF_SEL_MSK) |
01128          AD717X_SETUP_CONF_REG_REF_SEL(device_setup.reference));
01129 
01130     if (AD717X_WriteRegister(pad717x_dev,
01131                  AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) {
01132         printf(EOL "\tError in Polarity Selection!!" EOL);
01133         adi_press_any_key_to_continue();
01134     }
01135 
01136     return MENU_DONE;
01137 }
01138 
01139 
01140 /*!
01141  * @brief      Handle the menu to enable/disable the reference buffers
01142  * @param      user selected action
01143  * @return     MENU_DONE
01144  */
01145 int32_t  menu_ref_buffer_enable_disable(uint32_t user_action)
01146 {
01147     ad717x_st_reg *device_setup_control_reg;    // Pointer to setup control register
01148 
01149     // Get the pointer to setup control register structure
01150     device_setup_control_reg = AD717X_GetReg(pad717x_dev,
01151                    AD717X_SETUPCON0_REG + device_setup.setup);
01152 
01153     device_setup.reference_buffers = user_action;
01154 
01155     if (user_action == SELECT_ENABLE) {
01156         // Enable ref buffers (+ve/-ve)
01157         device_setup_control_reg->value |=
01158             (AD717X_SETUP_CONF_REG_REFBUF_P |
01159              AD717X_SETUP_CONF_REG_REFBUF_N);
01160     } else {
01161         // Disable ref buffers (+ve/-ve)
01162         device_setup_control_reg->value &=
01163             (~(AD717X_SETUP_CONF_REG_REFBUF_P |
01164                AD717X_SETUP_CONF_REG_REFBUF_N));
01165     }
01166 
01167     if (AD717X_WriteRegister(pad717x_dev,
01168                  AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) {
01169         printf(EOL "\tError in Reference Buffer Selection!!" EOL);
01170         adi_press_any_key_to_continue();
01171     }
01172 
01173     return MENU_DONE;
01174 }
01175 
01176 
01177 /*!
01178  * @brief      Handle the menu to enable/disable the input buffers
01179  * @param      user selected action
01180  * @return     MENU_DONE
01181  */
01182 int32_t menu_input_buffer_enable_disable(uint32_t user_action)
01183 {
01184     ad717x_st_reg *device_setup_control_reg;    // Pointer to setup control register
01185 
01186     // Get the pointer to setup control register structure
01187     device_setup_control_reg = AD717X_GetReg(pad717x_dev,
01188                    AD717X_SETUPCON0_REG + device_setup.setup);
01189 
01190     device_setup.input_buffers = user_action;
01191 
01192     if (user_action == SELECT_ENABLE) {
01193         // Enable ref buffers (+ve/-ve)
01194         device_setup_control_reg->value |=
01195             (AD717X_SETUP_CONF_REG_AINBUF_P |
01196              AD717X_SETUP_CONF_REG_AINBUF_N);
01197     } else {
01198         // Disable input buffers (+ve/-ve)
01199         device_setup_control_reg->value &=
01200             (~(AD717X_SETUP_CONF_REG_AINBUF_P |
01201                AD717X_SETUP_CONF_REG_AINBUF_N));
01202     }
01203 
01204     if (AD717X_WriteRegister(pad717x_dev,
01205                  AD717X_SETUPCON0_REG + device_setup.setup) != SUCCESS) {
01206         printf(EOL "\tError in Reference Buffer Selection!!" EOL);
01207         adi_press_any_key_to_continue();
01208     }
01209 
01210     return MENU_DONE;
01211 }
01212 
01213 
01214 /*!
01215  * @brief      Handle the menu to configure and assign the device setup
01216  * @param      menu_id- (Optional parameter)
01217  * @return     MENU_CONTINUE
01218  */
01219 int32_t menu_config_and_assign_setup(uint32_t menu_id)
01220 {
01221     float filter_odr;   // filter ODR value
01222     char rx_char;
01223 
01224     adi_clear_console();
01225 
01226     // Get the current setup selection
01227     device_setup.setup = get_setup_selection();
01228 
01229     // Select the filter type
01230     adi_do_console_menu(&filter_select_menu);
01231 
01232     if (device_setup.filter == SINC5_SINC1_FILTER) {
01233         // Select the post filter parameters
01234         adi_do_console_menu(&postfilter_enable_disable_menu);
01235 
01236         if (device_setup.post_filter_enabled == SELECT_ENABLE) {
01237             // Select the post filter type
01238             adi_do_console_menu(&postfilter_select_menu);
01239         }
01240 
01241         // Select the SINC+SINC1 filter ODR
01242         adi_do_console_menu(&sinc5_1_data_rate_select_menu);
01243         filter_odr = sinc5_sinc1_odr_map[device_setup.odr_bits];
01244     } else {
01245         // Select the SINC3 filter ODR
01246         adi_do_console_menu(&sinc3_data_rate_select_menu);
01247         filter_odr = sinc3_odr_map[device_setup.odr_bits];
01248     }
01249 
01250     // Select the polarity
01251     adi_do_console_menu(&polarity_select_menu);
01252 
01253     // Select the reference source
01254     adi_do_console_menu(&reference_select_menu);
01255 
01256     // Select the reference buffer
01257     adi_do_console_menu(&ref_buffer_enable_disable_menu);
01258 
01259     // Select the input buffer
01260     adi_do_console_menu(&input_buffer_enable_disable_menu);
01261 
01262     // Print selections
01263     printf(EOL EOL "\tSetup %ld is configured successfully =>" EOL,
01264            device_setup.setup);
01265     printf(EOL "\tFilter Type: %s", filter_name[device_setup.filter]);
01266 
01267     if (device_setup.filter == SINC5_SINC1_FILTER
01268         && device_setup.post_filter_enabled) {
01269         printf("\r\n\tPost Filter Type: %s", postfilter_name[device_setup.postfilter]);
01270     }
01271 
01272     printf(EOL "\tData Rate: %f", filter_odr);
01273     printf(EOL "\tPolarity: %s", polarity_status[device_setup.polarity]);
01274     printf(EOL "\tReference: %s", reference_name[device_setup.reference]);
01275     printf(EOL "\tReference Buffers: %s",
01276            enable_disable_status[device_setup.reference_buffers]);
01277     printf(EOL "\tInput Buffers: %s",
01278            enable_disable_status[device_setup.input_buffers]);
01279     printf(EOL);
01280 
01281     /* Allow user to assign setup to multiple channels*/
01282     do {
01283         // Select and assign the channel
01284         rx_char = select_chn_assignment();
01285     } while (rx_char != 'N');
01286 
01287     return MENU_CONTINUE;
01288 }
01289 
01290 
01291 /* @brief  Get the data rate based on data rate FS value and vice a versa
01292  * @param  Filter Type
01293  * @param  Filter data rate register value/bits
01294  * @return Actual Data Rate
01295  **/
01296 static float get_data_rate(uint32_t filter, uint32_t odr_reg_val)
01297 {
01298     float data_rate;   // filter data rate
01299 
01300     if (filter == SINC5_SINC1_FILTER) {
01301         data_rate = sinc5_sinc1_odr_map[odr_reg_val];
01302     } else {
01303         data_rate = sinc3_odr_map[odr_reg_val];
01304     }
01305 
01306     return data_rate;
01307 }
01308 
01309 
01310 /*!
01311  * @brief      Handle the menu to display device setup
01312  * @param      menu_id- (Optional parameter)
01313  * @return     MENU_CONTINUE
01314  */
01315 int32_t menu_display_setup(uint32_t menu_id)
01316 {
01317     float filter_data_rate;             // Filter data rate in SPS
01318     uint8_t setup_cnt;                  // setup counter
01319     uint8_t chn_cnt;                    // channel counter
01320     ad717x_st_reg *device_chnmap_reg;   // Pointer to channel map register
01321     ad717x_st_reg *device_setupcon_reg; // Pointer to setup control register
01322     ad717x_st_reg *device_filtercon_reg; // Pointer to filter control register
01323 
01324     printf(EOL);
01325     printf("\t---------------------------------------" EOL);
01326     printf("\tChannel# | Status | Setup | INP0 | INP1" EOL);
01327     printf("\t---------------------------------------" EOL);
01328 
01329     for (chn_cnt = 0; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) {
01330         // Get the pointer to channel register
01331         device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01332         if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01333             printf(EOL "Error reading setup!!" EOL);
01334             break;
01335         }
01336 
01337         // Extract the channel parameters from device register read value
01338         device_setup.channel_enabled = AD717X_CHMAP_REG_CH_EN_RD(
01339                                device_chnmap_reg->value);
01340         device_setup.setup_assigned = AD717X_CHMAP_REG_SETUP_SEL_RD(
01341                               device_chnmap_reg->value);
01342         device_setup.pos_analog_input = AD717X_CHMAP_REG_AINPOS_RD(
01343                             device_chnmap_reg->value);
01344         device_setup.neg_analog_input = AD717X_CHMAP_REG_AINNEG_RD(
01345                             device_chnmap_reg->value);
01346 
01347         //      Channel# | Status | Setup | INP0 | INP1
01348         printf("\t%4d %13s %4ld %8s %6s" EOL,
01349                chn_cnt,
01350                enable_disable_status[device_setup.channel_enabled],
01351                device_setup.setup_assigned,
01352                input_pin_map[device_setup.pos_analog_input],
01353                input_pin_map[device_setup.neg_analog_input]);
01354     }
01355 
01356     printf(EOL);
01357     printf("\t-------------------------------------------------------------------------------------------------------------"
01358            EOL);
01359     printf("\tSetup# | Filter |   Post Filter   | Data Rate | INPBUF+ | INPBUF- | REFBUF+ | REFBUF- | Polarity | Ref Source"
01360            EOL);
01361     printf("\t-------------------------------------------------------------------------------------------------------------"
01362            EOL);
01363 
01364     for (setup_cnt = 0; setup_cnt < NUMBER_OF_SETUPS; setup_cnt++) {
01365         // Get the pointer to filter control register
01366         device_filtercon_reg = AD717X_GetReg(pad717x_dev,
01367                              AD717X_FILTCON0_REG + setup_cnt);
01368         if (AD717X_ReadRegister(pad717x_dev,
01369                     AD717X_FILTCON0_REG + setup_cnt) != SUCCESS) {
01370             printf("\r\nError reading setup!!\r\n");
01371             break;
01372         }
01373 
01374         /* Extract the setup parameters from device register read value */
01375         device_setup.filter = AD717X_FILT_CONF_REG_ORDER_RD(
01376                           device_filtercon_reg->value);
01377         device_setup.odr_bits = AD717X_FILT_CONF_REG_ODR_RD(
01378                         device_filtercon_reg->value);
01379         device_setup.post_filter_enabled = AD717X_FILT_CONF_REG_ENHFILTEN_RD(
01380                 device_filtercon_reg->value);
01381         device_setup.postfilter = AD717X_FILT_CONF_REG_ENHFILT_RD(
01382                           device_filtercon_reg->value);
01383 
01384         if (device_setup.filter == SINC3_FILTER) {
01385             // Post filter unavailable for SINC3 type filter
01386             device_setup.post_filter_enabled = SELECT_DISBLE;
01387             device_setup.postfilter = POST_FILTER_NA;
01388         }
01389 
01390         // Get the pointer to setup control register
01391         device_setupcon_reg = AD717X_GetReg(pad717x_dev,
01392                             AD717X_SETUPCON0_REG + setup_cnt);
01393         if (AD717X_ReadRegister(pad717x_dev,
01394                     AD717X_SETUPCON0_REG + setup_cnt) != SUCCESS) {
01395             printf("\r\nError reading setup!!\r\n");
01396             break;
01397         }
01398 
01399 #if defined(DEV_AD4111) || defined(DEV_AD4112) || defined(DEV_AD4114) || \
01400     defined(DEV_AD4115)
01401         device_setup.input_buffers =
01402             AD4111_SETUP_CONF_REG_AIN_BUF_RD(device_setupcon_reg->value);
01403         device_setup.reference_buffers =
01404             (AD4111_SETUP_CONF_REG_REFPOS_BUF_RD(device_setupcon_reg->value) << 1 |
01405              AD4111_SETUP_CONF_REG_REFNEG_BUF_RD(device_setupcon_reg->value));
01406 #elif defined(DEV_AD7172_2) || defined(DEV_AD7172_4) || defined(DEV_AD7175_8)
01407         device_setup.input_buffers =
01408             (AD717X_SETUP_CONF_REG_AINBUF_P_RD(device_setupcon_reg->value) << 1) |
01409             (AD717X_SETUP_CONF_REG_AINBUF_N_RD(device_setupcon_reg->value));
01410 
01411         device_setup.reference_buffers =
01412             (AD717X_SETUP_CONF_REG_REFBUF_P_RD(device_setupcon_reg->value) << 1) |
01413             (AD717X_SETUP_CONF_REG_REFBUF_N_RD(device_setupcon_reg->value));
01414 #elif defined(DEV_AD7173_8)
01415         device_setup.input_buffers =
01416             AD717X_SETUP_CONF_REG_AIN_BUF_RD(device_setupcon_reg->value);
01417         device_setup.reference_buffers =
01418             AD717X_SETUP_CONF_REG_REF_BUF_RD(device_setupcon_reg->value);
01419 #endif
01420 
01421         device_setup.polarity = AD717X_SETUP_CONF_REG_BI_UNIPOLAR_RD(
01422                         device_setupcon_reg->value);
01423         device_setup.reference = AD717X_SETUP_CONF_REG_REF_SEL_RD(
01424                          device_setupcon_reg->value);
01425 
01426         // Get the actual data rate based on the filter selection
01427         filter_data_rate = get_data_rate(device_setup.filter,
01428                          device_setup.odr_bits);
01429 
01430         //      Setup# | Filter | Post Filter | Data Rate | INPBUF+ | INPBUF- | REFBUF+ | REFBUF- | Polarity | Ref Source
01431         printf("\t%4d %11s %8s(%6s) %10.2f %9s %9s %9s %9s %10s %10s" EOL,
01432                setup_cnt,
01433                filter_name[device_setup.filter],
01434                postfilter_name[device_setup.postfilter],
01435                enable_disable_status[device_setup.post_filter_enabled],
01436                filter_data_rate,
01437                enable_disable_status[(device_setup.input_buffers >> 1) & 0x01],
01438                enable_disable_status[(device_setup.input_buffers & 0x01)],
01439                enable_disable_status[(device_setup.reference_buffers >> 1) & 0x01],
01440                enable_disable_status[device_setup.reference_buffers & 0x01],
01441                polarity_status[device_setup.polarity],
01442                reference_name[device_setup.reference]);
01443     }
01444 
01445     adi_press_any_key_to_continue();
01446     return MENU_CONTINUE;
01447 }
01448 
01449 
01450 /*!
01451  * @brief      Handle the menu to read die temperature of device
01452  * @param      menu_id- (Optional parameter)
01453  * @return     MENU_CONTINUE
01454  */
01455 int32_t menu_read_temperature(uint32_t menu_id)
01456 {
01457     uint8_t chn_cnt;                // current channel
01458     uint16_t chn_mask = 0;          // channels enable mask
01459     ad717x_st_reg *device_mode_reg; // Pointer to device mode register
01460     ad717x_st_reg *device_chnmap_reg;   // Pointer to channel map register
01461     ad717x_st_reg *device_setup_control_reg;    // Pointer to setup control register
01462     int32_t sample_data;            // ADC sample result
01463     float temperature = 0.00;       // Temperature in Celcius
01464     float conversion_result;        // raw sample data to voltage conversion result
01465     int32_t prev_adc_reg_values[3]; // Holds the previous register values
01466     bool temperature_read_error;    // Temperature read error status
01467 
01468     temperature_read_error = false;
01469 
01470     // Disable the other enabled channels to read temperature from only 0th channel
01471     for (chn_cnt = 1; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) {
01472         // Get the pointer to channel register
01473         device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01474         if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01475             temperature_read_error = true;
01476             break;
01477         }
01478 
01479         if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) {
01480             // Save enabled channel
01481             chn_mask |= (1 << chn_cnt);
01482 
01483             // Disable the curent channel
01484             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
01485 
01486             // Write to ADC channel register
01487             if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01488                 temperature_read_error = true;
01489                 break;
01490             }
01491         }
01492     }
01493 
01494     if (temperature_read_error == false) {
01495         // Get the pointer to device registers
01496         device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG);
01497         device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG);
01498         device_setup_control_reg = AD717X_GetReg(pad717x_dev, AD717X_SETUPCON0_REG);
01499 
01500         // Save the previous values of below registers in order to not disturb
01501         // the user configured setup.
01502         // *Note: This step is not required for someone who intended to just
01503         //        read temperature. It is an application specific functionality.
01504         prev_adc_reg_values[0] = device_mode_reg->value;
01505         prev_adc_reg_values[1] = device_chnmap_reg->value;
01506         prev_adc_reg_values[2] = device_setup_control_reg->value;
01507 
01508         // Configure the channel map 0 register
01509         // AINP = Temp + , AINM = Temp - , Setup = 0, CHN Enabled = True
01510         device_chnmap_reg->value =
01511             (AD717X_CHMAP_REG_AINPOS(TEMP_SENSOR_POS_INP_BITS) |
01512              AD717X_CHMAP_REG_AINNEG(TEMP_SENSOR_NEG_INP_BITS) |
01513              AD717X_CHMAP_REG_SETUP_SEL(0) |
01514              AD717X_CHMAP_REG_CH_EN);
01515 
01516         if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG) != SUCCESS) {
01517             printf(EOL EOL "\tError Reading Temperature!!");
01518             adi_press_any_key_to_continue();
01519             return MENU_CONTINUE;
01520         }
01521 
01522         // Configure the setup control 0 register
01523         // Polarity: Bipolar, Input Buffers: Enable, Ref: Internal
01524         device_setup_control_reg->value =
01525             (AD717X_SETUP_CONF_REG_BI_UNIPOLAR |
01526              AD717X_SETUP_CONF_REG_AINBUF_P |
01527              AD717X_SETUP_CONF_REG_AINBUF_N |
01528              AD717X_SETUP_CONF_REG_REF_SEL(INTERNAL));
01529 
01530         if (AD717X_WriteRegister(pad717x_dev, AD717X_SETUPCON0_REG) != SUCCESS) {
01531             printf(EOL EOL "\tError Reading Temperature!!");
01532             adi_press_any_key_to_continue();
01533             return MENU_CONTINUE;
01534         }
01535 
01536         // Configure the device mode register
01537         // Internal Ref: Enable, Mode: Single Conversion
01538         device_mode_reg->value |= AD717X_ADCMODE_REG_REF_EN;
01539         device_mode_reg->value =
01540             ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
01541              AD717X_ADCMODE_REG_MODE(SINGLE_CONVERISION));
01542 
01543         if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) {
01544             printf(EOL EOL "\tError Reading Temperature!!");
01545             adi_press_any_key_to_continue();
01546             return MENU_CONTINUE;
01547         }
01548 
01549         for (uint8_t samples = 0; samples < 2; samples++) {
01550             // Wait for conversion to complete, then obtain sample
01551             AD717X_WaitForReady(pad717x_dev, 10000);
01552 
01553             if (AD717X_ReadData(pad717x_dev, &sample_data) != SUCCESS) {
01554                 temperature_read_error = true;
01555                 break;
01556             }
01557         }
01558 
01559         if (temperature_read_error == false) {
01560             conversion_result = (((float)sample_data / (1 << (ADC_RESOLUTION - 1))) - 1) *
01561                         ADC_REF_VOLTAGE;
01562 
01563             // Calculate the temparture in degree celcius (sensitivity: 477uV/K)
01564             // *Below equation is referred from the device datasheet
01565             temperature = ((float)conversion_result / 0.000477) - 273.15;
01566 
01567             // All done, restore previous state of device registers
01568             // *Note: This step is not required for someone who intended to just
01569             //        read temperature. It is an application specific functionality.
01570             device_mode_reg->value = prev_adc_reg_values[0];
01571             (void)AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG);
01572 
01573             device_chnmap_reg->value = prev_adc_reg_values[1];
01574             (void)AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG);
01575 
01576             device_setup_control_reg->value = prev_adc_reg_values[2];
01577             (void)AD717X_WriteRegister(pad717x_dev, AD717X_SETUPCON0_REG);
01578 
01579             // Need to restore the channels those were disabled during temperaure read
01580             for (uint8_t i = 0 ; i < NUMBER_OF_CHANNELS ; i++) {
01581                 if (chn_mask & (1 << i)) {
01582                     // Get the pointer to channel register
01583                     device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + i);
01584                     device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
01585 
01586                     if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + i) != SUCCESS) {
01587                         // continue with other channels
01588                     }
01589                 }
01590             }
01591         }
01592     }
01593 
01594     if (temperature_read_error == false) {
01595         printf(EOL EOL "\tTemperature: %.2f Celcius", temperature);
01596     } else {
01597         printf(EOL EOL "\tError Reading Temperature!!");
01598     }
01599 
01600     adi_press_any_key_to_continue();
01601     return MENU_CONTINUE;
01602 }
01603 
01604 
01605 /*!
01606  * @brief      Handle the menu to calibrate the device
01607  * @param      menu_id- (Optional parameter)
01608  * @return     MENU_CONTINUE
01609  */
01610 int32_t menu_calibrate_adc(uint32_t menu_id)
01611 {
01612     uint8_t chn_cnt;                    // Current channel
01613     uint16_t chn_mask = 0;              // Channel enable mask
01614     ad717x_st_reg *device_chnmap_reg;   // Pointer to channel map register
01615     ad717x_st_reg *device_mode_reg;     // Pointer to device mode register
01616     bool calibration_error;             // Calibration error flag
01617 
01618     calibration_error = false;
01619 
01620     for (chn_cnt = 0; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) {
01621         // Get the pointer to channel register
01622         device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01623         if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01624             calibration_error = true;
01625             break;
01626         }
01627 
01628         if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) {
01629             // Save enabled channel
01630             chn_mask |= (1 << chn_cnt);
01631 
01632             // Disable the curent channel
01633             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
01634 
01635             if(AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01636                 calibration_error = true;
01637                 break;
01638             }
01639         }
01640     }
01641 
01642     if (calibration_error == false) {
01643         // Calibrate all the channels
01644         for (chn_cnt = 0 ; chn_cnt < NUMBER_OF_CHANNELS ; chn_cnt++) {
01645             printf(EOL "\tCalibrating Channel %d => " EOL, chn_cnt);
01646 
01647             // Enable current channel
01648             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01649             device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
01650 
01651             if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01652                 calibration_error = true;
01653                 break;
01654             }
01655 
01656             device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG);
01657 
01658             // Start full scale internal (gain) calibration
01659             printf("\tRunning full-scale internal calibration..." EOL);
01660             device_mode_reg->value =
01661                 ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
01662                  AD717X_ADCMODE_REG_MODE(INTERNAL_FULL_SCALE_CAL_MODE));
01663 
01664             if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) {
01665                 calibration_error = true;
01666                 break;
01667             }
01668 
01669             // Wait for calibration to over
01670             if (AD717X_WaitForReady(pad717x_dev, 10000) != SUCCESS) {
01671                 calibration_error = true;
01672                 break;
01673             } else {
01674                 // Start zero scale internal (offset) calibration
01675                 printf("\tRunning zero-scale internal calibration..." EOL);
01676                 device_mode_reg->value =
01677                     ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
01678                      AD717X_ADCMODE_REG_MODE(INTERNAL_OFFSET_CAL_MODE));
01679 
01680                 if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) {
01681                     calibration_error = true;
01682                     break;
01683                 }
01684 
01685                 // Wait for calibration to over
01686                 if (AD717X_WaitForReady(pad717x_dev, 10000) != SUCCESS) {
01687                     printf("\tError in channel calibration..." EOL);
01688                 } else {
01689                     printf("\tCalibration Successful..." EOL);
01690                 }
01691             }
01692 
01693             // Disable current channel
01694             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
01695 
01696             if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01697                 calibration_error = true;
01698                 break;
01699             }
01700         }
01701     }
01702 
01703     // Need to restore the channels that were disabled during calibration
01704     for (chn_cnt = 0 ; chn_cnt < NUMBER_OF_CHANNELS ; chn_cnt++) {
01705         if (chn_mask & (1 << chn_cnt)) {
01706             // Get the pointer to channel register
01707             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01708             device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
01709 
01710             if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01711                 // continue with other channels
01712             }
01713         }
01714     }
01715 
01716     adi_press_any_key_to_continue();
01717     return MENU_CONTINUE;
01718 }
01719 
01720 
01721 /*!
01722  * @brief      Handle the menu to select input type for open wire detection
01723  * @param      User selected analog input type
01724  * @return     MENU_DONE
01725  */
01726 int32_t menu_input_type_selection(uint32_t user_input_type)
01727 {
01728     // Save the analog input type, for channel and input pair selections
01729     analog_input_type = user_input_type;
01730 
01731     return MENU_DONE;
01732 }
01733 
01734 
01735 /*!
01736  * @brief      Handle the menu to select channel pair for open wire detection
01737  * @param      User selected channel pair
01738  * @return     MENU_DONE
01739  */
01740 int32_t menu_select_chn_pair(uint32_t user_channel_pair)
01741 {
01742     // Save the channel pair for configuring channel map register
01743     channel_pair = user_channel_pair;
01744 
01745     return MENU_DONE;
01746 }
01747 
01748 
01749 /*!
01750  * @brief      Handle the menu to select input pair for open wire detection
01751  * @param      User selected analog input
01752  * @return     MENU_DONE
01753  */
01754 int32_t menu_select_input_pair(uint32_t user_analog_input)
01755 {
01756     uint8_t current_channel;            // current channel
01757     ad717x_st_reg *device_chnmap_reg;   // pointer to channel map register
01758     ad717x_st_reg *device_mode_reg;     // pointer to device mode register
01759     bool input_pair_select_error = false;   // Error in input pair selection
01760 
01761     if (input_pair_select_error == false) {
01762         // Set the configurations for channel pair
01763         for (uint8_t chn_cnt = 0; chn_cnt < 2; chn_cnt++) {
01764             if (chn_cnt == 0) {
01765                 // Get the first channel from the pair
01766                 current_channel = (channel_pair >> CHN_PAIR_OFFSET);
01767             } else {
01768                 // Get the second channel from the pair
01769                 current_channel = (channel_pair & CHN_PAIR_MASK);
01770             }
01771 
01772             // Get the pointer to channel map register structure
01773             device_chnmap_reg = AD717X_GetReg(pad717x_dev,
01774                               AD717X_CHMAP0_REG + current_channel);
01775 
01776             // Load the setup 0 value
01777             device_chnmap_reg->value =
01778                 ((device_chnmap_reg->value & ~AD717X_CHMAP_REG_SETUP_SEL_MSK) |
01779                  AD717X_CHMAP_REG_SETUP_SEL(0));
01780 
01781             // Select the analog input
01782             device_chnmap_reg->value =
01783                 ((device_chnmap_reg->value & ~AD4111_CHMAP_REG_INPUT_MSK) |
01784                  AD4111_CHMAP_REG_INPUT(user_analog_input));
01785 
01786             // Enable the channel
01787             device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
01788 
01789             device_mode_reg = AD717X_GetReg(pad717x_dev, AD717X_ADCMODE_REG);
01790             device_mode_reg->value =
01791                 ((device_mode_reg->value & ~AD717X_ADCMODE_REG_MODE_MSK) |
01792                  AD717X_ADCMODE_REG_MODE(SINGLE_CONVERISION));
01793 
01794             if (AD717X_WriteRegister(pad717x_dev, AD717X_ADCMODE_REG) != SUCCESS) {
01795                 input_pair_select_error = true;
01796             }
01797 
01798             if (AD717X_WriteRegister(pad717x_dev,
01799                          AD717X_CHMAP0_REG + current_channel) != SUCCESS) {
01800                 input_pair_select_error = true;
01801                 break;
01802             }
01803 
01804             if (AD717X_WaitForReady(pad717x_dev, 10000) != SUCCESS) {
01805                 input_pair_select_error = true;
01806                 break;
01807             }
01808 
01809             if (AD717X_ReadData(pad717x_dev,
01810                         &open_wire_detect_sample_data[chn_cnt]) != SUCCESS) {
01811                 input_pair_select_error = true;
01812                 break;
01813             }
01814 
01815             // Disable the current channel
01816             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
01817 
01818             if (AD717X_WriteRegister(pad717x_dev,
01819                          AD717X_CHMAP0_REG + current_channel) != SUCCESS) {
01820                 input_pair_select_error = true;
01821                 break;
01822             }
01823         }
01824     }
01825 
01826     if (input_pair_select_error == true) {
01827         printf("\tError in analog input selection!!" EOL);
01828         adi_press_any_key_to_continue();
01829     }
01830 
01831     return MENU_DONE;
01832 }
01833 
01834 
01835 /*!
01836  * @brief      Handle the menu to perform open wire detection
01837  * @param      menu_id- (Optional parameter)
01838  * @return     MENU_CONTINUE
01839  */
01840 int32_t menu_open_wire_detection(uint32_t menu_id)
01841 {
01842     ad717x_st_reg *device_chnmap_reg;   // pointer to channel map register
01843     ad717x_st_reg *device_gpiocon_reg;  // pointer to gpio control register
01844     ad717x_st_reg *device_setupcon_reg; // pointer to setup control register
01845     uint8_t chn_cnt;                    // Current channel count
01846     uint8_t chn_mask = 0;               // Channel enable/disable mask
01847     bool open_wire_detection_error = false; // Open wire detection error flag
01848 
01849     // Disable all the enabled channels before starting open wire detection
01850     for (chn_cnt = 0; chn_cnt < NUMBER_OF_CHANNELS; chn_cnt++) {
01851         device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01852 
01853         if (AD717X_ReadRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01854             open_wire_detection_error = true;
01855             break;
01856         }
01857 
01858         if (device_chnmap_reg->value & AD717X_CHMAP_REG_CH_EN) {
01859             // Save enabled channel
01860             chn_mask |= (1 << chn_cnt);
01861 
01862             // Disable the curent channel
01863             device_chnmap_reg->value &= (~AD717X_CHMAP_REG_CH_EN);
01864 
01865             // Write to ADC channel register
01866             if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01867                 open_wire_detection_error = true;
01868                 break;
01869             }
01870         }
01871     }
01872 
01873     if (open_wire_detection_error == false) {
01874         do {
01875             // Enable the open wire detection on voltage channels
01876             device_gpiocon_reg = AD717X_GetReg(pad717x_dev, AD717X_GPIOCON_REG);
01877 
01878             if (AD717X_ReadRegister(pad717x_dev, AD717X_GPIOCON_REG) == SUCCESS) {
01879                 device_gpiocon_reg->value |= (AD4111_GPIOCON_REG_OP_EN0_1 |
01880                                   AD4111_GPIOCON_REG_OW_EN);
01881 
01882                 if (AD717X_WriteRegister(pad717x_dev, AD717X_GPIOCON_REG) != SUCCESS) {
01883                     open_wire_detection_error = true;
01884                     break;
01885                 }
01886             } else {
01887                 break;
01888             }
01889 
01890             // Configure the setup control 0 register
01891             device_setupcon_reg = AD717X_GetReg(pad717x_dev, AD717X_SETUPCON0_REG);
01892 
01893             if (AD717X_ReadRegister(pad717x_dev, AD717X_SETUPCON0_REG) == SUCCESS) {
01894                 device_setupcon_reg->value |= (AD717X_SETUP_CONF_REG_AINBUF_P |
01895                                    AD717X_SETUP_CONF_REG_AINBUF_N |
01896                                    AD717X_SETUP_CONF_REG_BI_UNIPOLAR);
01897 
01898                 device_setupcon_reg->value = ((device_setupcon_reg->value &
01899                                    ~AD717X_SETUP_CONF_REG_REF_SEL_MSK) |
01900                                   AD717X_SETUP_CONF_REG_REF_SEL(EXTERNAL));
01901 
01902                 if (AD717X_WriteRegister(pad717x_dev, AD717X_SETUPCON0_REG) != SUCCESS) {
01903                     open_wire_detection_error = true;
01904                     break;
01905                 }
01906             } else {
01907                 break;
01908             }
01909         } while (0);
01910 
01911 
01912         if (open_wire_detection_error == false) {
01913             // Select the analog input type
01914             adi_do_console_menu(&open_wire_detect_input_type_menu);
01915 
01916             if (analog_input_type == SINGLE_ENDED_INPUT) {
01917                 // Select the single ended input channel pair
01918                 adi_do_console_menu(&open_wire_detect_se_channel_menu);
01919 
01920                 // Select the single ended analog input pair
01921                 adi_do_console_menu(&open_wire_detect_se_analog_input_menu);
01922             } else {
01923                 // Select the differential ended input channel pair
01924                 adi_do_console_menu(&open_wire_detect_de_channel_menu);
01925 
01926                 // Select the differential ended analog input pair
01927                 adi_do_console_menu(&open_wire_detect_de_analog_input_menu);
01928             }
01929 
01930             printf(EOL "\tChannel %d = %d" EOL, (channel_pair >> CHN_PAIR_OFFSET),
01931                    open_wire_detect_sample_data[0]);
01932 
01933             printf(EOL "\tChannel %d = %d" EOL, (channel_pair & CHN_PAIR_MASK),
01934                    open_wire_detect_sample_data[1]);
01935 
01936             // Check for open wire detection by measuring offset of channel pair sampled data
01937             if (abs(open_wire_detect_sample_data[0] - open_wire_detect_sample_data[1]) >
01938                 OPEN_WIRE_DETECT_THRESHOLD) {
01939                 printf(EOL "\tOpen Wire Detected on Selected Input Pair!!" EOL);
01940             } else {
01941                 printf(EOL "\tNo Open Wire Detected on Selected Input Pair..." EOL);
01942             }
01943         } else {
01944             printf(EOL "\tError in Open Wire Detection!!" EOL);
01945         }
01946     } else {
01947         printf(EOL "\tError in Open Wire Detection!!" EOL);
01948     }
01949 
01950     // Need to restore the channels that were disabled during open wire detection
01951     for (chn_cnt = 0 ; chn_cnt < NUMBER_OF_CHANNELS ; chn_cnt++) {
01952         if (chn_mask & (1 << chn_cnt)) {
01953             // Get the pointer to channel register
01954             device_chnmap_reg = AD717X_GetReg(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt);
01955 
01956             device_chnmap_reg->value |= AD717X_CHMAP_REG_CH_EN;
01957 
01958             if (AD717X_WriteRegister(pad717x_dev, AD717X_CHMAP0_REG + chn_cnt) != SUCCESS) {
01959                 continue;
01960             }
01961         }
01962     }
01963 
01964     adi_press_any_key_to_continue();
01965     return MENU_CONTINUE;
01966 }
01967 
01968 
01969 /* @brief  Console menu to read/write the adc register
01970  * @param  Read/Write ID/Operation
01971  * @return MENU_CONTINUE
01972  **/
01973 int32_t menu_rw_ad717x_register(uint32_t rw_id)
01974 {
01975     uint32_t reg_address;
01976     uint32_t reg_data;
01977     ad717x_st_reg *device_data_reg;  // Pointer to data register
01978 
01979     printf(EOL "\tEnter the register address (in hex): ");
01980     reg_address = adi_get_hex_integer(sizeof(reg_address));
01981 
01982     // Get the pointer to data register
01983     device_data_reg = AD717X_GetReg(pad717x_dev, reg_address);
01984 
01985     if ((uint32_t)DEVICE_REG_READ_ID == rw_id) {
01986         // Read from ADC channel register
01987         if (AD717X_ReadRegister(pad717x_dev, reg_address) != SUCCESS) {
01988             printf(EOL "Error reading setup!!" EOL);
01989         } else {
01990             reg_data = device_data_reg->value;
01991             printf(EOL "\tRead Value: 0x%lx", reg_data);
01992         }
01993     } else {
01994         printf(EOL "\tEnter the register data (in hex): ");
01995         reg_data = adi_get_hex_integer(sizeof(reg_data));
01996 
01997         device_data_reg->value = reg_data;
01998 
01999         if (AD717X_WriteRegister(pad717x_dev, reg_address) != SUCCESS) {
02000             printf(EOL "\tError in writing adc register!!" EOL);
02001         } else {
02002             printf(EOL "\tWrite Successful..." EOL);
02003         }
02004     }
02005 
02006     adi_press_any_key_to_continue();
02007     return MENU_CONTINUE;
02008 }
02009 
02010 
02011 /*!
02012  * @brief      Handle the menu to read/write device registers
02013  * @param      menu_id- (Optional parameter)
02014  * @return     MENU_CONTINUE
02015  */
02016 int32_t menu_read_write_device_regs(uint32_t menu_id)
02017 {
02018     return (adi_do_console_menu(&reg_read_write_menu));
02019 }