Example program for EVAL-CN0535-FMCZ

Dependencies:   platform_drivers AD77681

main.cpp

Committer:
jngarlitos
Date:
2021-04-12
Revision:
2:998f1de78dae
Parent:
1:f3b5e79a8488

File content as of revision 2:998f1de78dae:

/*!
 *****************************************************************************
 *@file:  main.c
 *
 *@brief: main module for EVAL-CN0535-FMCZ example program
 *
 *@details: main module for EVAL-CN0535-FMCZ example program
 *-----------------------------------------------------------------------------
 *
 Copyright (c) 2021 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.
 *****************************************************************************/

/*** includes ***/
#include "mbed.h"
#include "main.h"
#include "app_config.h"
#include "cn0535_init_params.h"

//Uncomment this to print CRC/XOR
//#define CRC_DEBUG

// Descriptor of the main device - the ADC AD7768-1
ad77681_dev *device;
// Descriptor of the  ADC AD7768-1 Status
ad77681_status_registers *current_status;
// Structure carying measured data, sampled by the ADC
adc_data measured_data;


// Initialize the serial object with TX and RX pins
Serial pc(USBTX, USBRX);
// Initialize the drdy pin as interrupt input
InterruptIn drdy(DRDY_PIN, PullNone);
// Initialize the adc_rst_pin pin as digital output
DigitalOut adc_rst(ADC_RST_PIN);
// Initialize the interrupt event variable
volatile bool int_event= false;


/*
 * ADC data recteption interrupt from DRDY
 *
 * Data reception from the ADC using interrupt generated by the ADC's DRDY (Data Ready) pin
 * Interrupt triggers falling edge of the active-high DRDY pulse
 * DRDY pulse is generated by the ADC and frequency of the DRDY pulse depends on the ADC settings:
 *
 * DRDY frequency = MCLK / ( MCLK_DIV * FILTER_OSR )
 *
 */
void drdy_interrupt()
{
    int_event = true;

    if (measured_data.count == measured_data.samples) { // Desired numer of samples has been taken, set everything back
        drdy.disable_irq();                             // Disable interrupt on DRDY pin
        measured_data.finish = true;                    // Desired number of samples has been taken
        measured_data.count = 0;                        // Set measured data counter to 0
    }
}


int main()
{
    int32_t connected = FAILURE;
    uint32_t menu;

    adc_hard_reset();                                                   // Perform hard reset thru GPIO
    connected = ad77681_setup(&device, init_params, &current_status);   // SETUP and check connection

    if(connected == FAILURE)
        go_to_error();

    adc_gpio_init();    // Initilized SDP-K1 GPIOS
    print_title();
    print_prompt();

//============ MAIN WHILE ====================
    while(1) {
        if (pc.readable()) {                                // Settings menu SWITCH
            getUserInput(&menu);

            switch (menu) {

            case 1:
                menu_1_set_pgia_gain_mode();                // Set PGIA gain or mode
                break;
            case 2:
                menu_2_set_fda_powermode();                 // Set FDA power mode
                break;
            case 3:
                menu_3_set_ad77681_powermode();             // Set FDA power mode
                break;
            case 4:
                menu_4_set_ad77681_clock_divider();         // Set FDA power mode
                break;
            case 5:
                menu_5_set_ad77681_filter_type();           // Set ad7768-1 filter type
                break;
            case 6:
                menu_6_ad77681_AIN_buffers_controll();      // Set ad7768-1 AIN buffers
                break;
            case 7:
                menu_7_ad77681_REF_buffers_controll();      // Set ad7768-1 REF buffers
                break;
            case 8:
                menu_8_set_ad77681_vcm_setup();             // Set ad7768-1 VCM
                break;
            case 9:
                menu_9_set_ad77681_data_output_mode();      // Set ad7768-1 Data output mode
                break;
            case 10:
                menu_10_set_ad77681_diagnostic_mode();      // Set ad7768-1 Diagnostic mode
                break;
            case 11:
                menu_11_set_ad77681_gains_offsets();        // Set ad7768-1 gain and offset
                break;
            case 12:
                menu_12_ad77681_read_master_status();       // Read ad7768-1 Master status
                break;
            case 13:
                menu_13_ad77681_read_register();            // Read ad7768-1 registers
                break;
            case 14:
                menu_14_read_ad77681_single_conv_data();    // Read ad7768-1 single convertion data
                break;
            case 15:
                menu_15_read_ad77681_continuous_data();     // Read ad7768-1 continuous read data
                break;
            case 16:
                menu_16_print_ad77681_continuos_read_data();// Print ad7768-1 continuous read data
                break;
            case 17:
                menu_17_ad77681_check_scratchpad();         // Perform ad7768-1 scratch pad check
                break;
            case 18:
                menu_18_reset_ad77681_ADC();                // Reset ad7768-1
                break;
            case 19:
                menu_19_set_default_settings();             // Set Board defaul settings
                break;
            case 20:
                menu_20_mclk_vref();                        // Set ad7768-1 MCLK and Vref Values
                break;
            default:
                pc.printf("Invalid option");                // Invalid Option
                print_prompt();
                break;
            }
        }
    }
}

/**
 * Error warning, in case of unsuccessfull SPI connection
 *
 */
void static go_to_error()
{
    int32_t connected = FAILURE;

    while (1) {
        pc.printf("ERROR: NOT CONNECTED\nCHECK YOUR PHYSICAL CONNECTION\n\n");  // When not connected, keep showing error message
        wait(5);

        connected = ad77681_setup(&device, init_params, &current_status);       // Keep trying to connect
        if (connected == SUCCESS) {
            pc.printf("SUCCESSFULLY RECONNECTED\n\n");                          // If successfull reading from scratchpad, init the ADC and go back
            break;
        }
    }
}

/**
 * Print title
 *
 */
void static print_title()
{
    pc.printf("\n\r");
    pc.printf("****************************************************************\n");
    pc.printf("*           CN0535 Demonstration Program -- (mbed)             *\n");
    pc.printf("*                                                              *\n");
    pc.printf("* This program demonstrates Universal Measurement Platform     *\n");
    pc.printf("* using the AD7768-1 Precision 24-bit sigma-delta AD converter *\n");
    pc.printf("*                                                              *\n");
    pc.printf("* Set the baud rate to 115200 select the newline terminator.   *\n");
    pc.printf("****************************************************************\n");
}

/**
 * Print main menu to console
 *
 */
void static print_prompt()
{
    pc.printf("\n\nCommand Summary:\n\n");
    pc.printf("  1  - Set LTC6373 PGIA Gain/Mode\n");
    pc.printf("  2  - Set ADA4945 FDA Power Mode\n");
    pc.printf("  3  - Set AD7768-1 power mode\n");
    pc.printf("  4  - Set AD7768-1 MCLK clock divider\n");
    pc.printf("  5  - Set AD7768-1 filter type\n");
    pc.printf("  6  - Set AD7768-1 AIN buffers\n");
    pc.printf("  7  - Set AD7768-1 REF buffers\n");
    pc.printf("  8  - Set AD7768-1 VCM output\n");
    pc.printf("  9  - Set AD7768-1 data output mode\n");
    pc.printf("  10 - Set AD7768-1 diagnostic mode\n");
    pc.printf("  11 - Set AD7768-1 Gains and Offsets\n");
    pc.printf("  12 - Read AD7768-1 master status\n");
    pc.printf("  13 - Read AD7768-1 desired register\n");
    pc.printf("  14 - Read AD7768-1 data register\n");
    pc.printf("  15 - Read AD7768-1 continuous mode data\n");
    pc.printf("  16 - Print AD7768-1 Continuous mode measured data\n");
    pc.printf("  17 - AD7768-1 Scratchpad Check \n");
    pc.printf("  18 - Reset AD7768-1 ADC\n");
    pc.printf("  19 - Set to Board Default Config\n");
    pc.printf("  20 - Update Vref and MCLK values\n");
    pc.printf("\n\r");
}

/**
 * Set LTC6373 PGIA Gain or Mode
 *
 */
void static menu_1_set_pgia_gain_mode(void)
{
    uint32_t new_pgia_gain;
    uint8_t value;

    pc.printf(" Avaliable LT6373 PGIA Gains and Mode: \n");
    pc.printf("  1 - Shutdown\n");
    pc.printf("  2 - 0.25V/V\n");
    pc.printf("  3 - 0.50V/V\n");
    pc.printf("  4 - 1V/V\n");
    pc.printf("  5 - 2V/V\n");
    pc.printf("  6 - 4V/V\n");
    pc.printf("  7 - 8V/V\n");
    pc.printf("  8 - 16V/V\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_pgia_gain);
    pc.putc('\n');

    switch (new_pgia_gain) {

    case 1:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 7;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA Shutdown selected\n");
        break;
    case 2:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 6;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 0.25V/V selected\n");
        break;
    case 3:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 5;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 0.5V/V selected\n");
        break;
    case 4:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 4;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 1V/V selected\n");
        break;
    case 5:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 3;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 2V/V selected\n");
        break;
    case 6:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 2;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 4V/V selected\n");
        break;
    case 7:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 1;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 8V/V selected\n");
        break;
    case 8:
        ad77681_spi_read_mask(device, AD77681_REG_GPIO_WRITE, AD77681_GPIO_WRITE_3_MSK, &value);
        value |= 0;
        ad77681_gpio_write(device,value, AD77681_ALL_GPIOS);
        pc.printf(" PGIA gain: 16V/V selected\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Set ADA4945 FDA Mode
 *
 */
void static menu_2_set_fda_powermode(void)
{
    uint32_t new_fda_powermode;
    uint8_t value;

    pc.printf(" Avaliable LT6373 PGIA Gains and Mode: \n");
    pc.printf("  1 - Full Power Mode\n");
    pc.printf("  2 - Low Power Moden");
    pc.printf(" Select an option: \n");

    getUserInput(&new_fda_powermode);
    pc.putc('\n');

    switch (new_fda_powermode) {

    case 1:
        value = 1;
        ad77681_gpio_write(device,value, AD77681_GPIO3);
        pc.printf(" FDA Full Power Mode selected\n");
        break;
    case 2:
        value = 0;
        ad77681_gpio_write(device,value, AD77681_GPIO3);
        pc.printf(" FDA Low Power Mode selected\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Set AD7768-1 power mode
 *
 */
void static menu_3_set_ad77681_powermode(void)
{
    uint32_t new_ad77681_pwr_mode;

    pc.printf(" Avaliable AD7768-1 power modes: \n");
    pc.printf("  1 - Low power mode\n");
    pc.printf("  2 - Median power mode\n");
    pc.printf("  3 - Fast power mode\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_ad77681_pwr_mode);
    pc.putc('\n');

    switch (new_ad77681_pwr_mode) {

    case 1:
        ad77681_set_power_mode(device, AD77681_ECO);
        pc.printf(" AD7768-1 Low power mode selected\n");
        break;
    case 2:
        ad77681_set_power_mode(device, AD77681_MEDIAN);
        pc.printf(" AD7768-1 Median power mode selected\n");
        break;
    case 3:
        ad77681_set_power_mode(device, AD77681_FAST);
        pc.printf(" AD7768-1 Fast power mode selected\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Set AD7768-1 clock divider
 *
 */
void static menu_4_set_ad77681_clock_divider(void)
{
    uint32_t new_ad77681_mclk_div;

    pc.printf(" Avaliable AD7768-1 MCLK divider options: \n");
    pc.printf("  1 - MCLK/16\n");
    pc.printf("  2 - MCLK/8\n");
    pc.printf("  3 - MCLK/4\n");
    pc.printf("  4 - MCLK/2\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_ad77681_mclk_div);
    pc.putc('\n');

    switch (new_ad77681_mclk_div) {

    case 1:
        ad77681_set_mclk_div(device, AD77681_MCLK_DIV_16);
        pc.printf(" AD7768-1 MCLK/16 selected\n");
        break;
    case 2:
        ad77681_set_mclk_div(device, AD77681_MCLK_DIV_8);
        pc.printf(" AD7768-1 MCLK/8 selected\n");
        break;
    case 3:
        ad77681_set_mclk_div(device, AD77681_MCLK_DIV_4);
        pc.printf(" AD7768-1 MCLK/4 selected\n");
        break;
    case 4:
        ad77681_set_mclk_div(device, AD77681_MCLK_DIV_2);
        pc.printf(" AD7768-1 MCLK/2 selected\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }

    ad77681_update_sample_rate(device);         // Update the sample rate after changing the MCLK divider
    print_prompt();
}

/**
 * Set filter type
 *
 */
void static menu_5_set_ad77681_filter_type(void)
{
    pc.printf(" Avaliable AD7768-1 Filter Type options: \n");
    pc.printf("  1 - SINC3 Fileter\n");
    pc.printf("  2 - SINC5 Filter\n");
    pc.printf("  3 - Low ripple FIR Filter\n");
    pc.printf("  4 - SINC3 50/60Hz rejection\n");
    pc.printf("  5 - User-defined FIR filter\n");
    pc.printf(" Select an option: \n");

    uint32_t new_filter = 0;
    int32_t ret;

    getUserInput(&new_filter);
    pc.putc('\n');

    switch (new_filter) {

    case 1:
        set_SINC3_filter();
        break;
    case 2:
        set_SINC5_filter();
        break;
    case 3:
        set_FIR_filter();
        break;
    case 4:
        set_50HZ_rej();
        break;
    case 5:
        set_user_defined_FIR();
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }

    ad77681_update_sample_rate(device);         // Update the sample rate after changing the Filter type
    print_prompt();
}

/**
 * Set SINC3 filter
 *
 */
void static set_SINC3_filter(void)
{
    uint32_t new_sinc3 = 0, new_sinc5 = 0;
    int32_t ret;

    pc.printf(" AD7768-1 SINC3 filter Oversampling ratios: \n");
    pc.printf("  OSR is calculated as (x + 1)*32\n");
    pc.printf("  x is SINC3 OSR register value\n");
    pc.printf(" Please input a value from 0 to 8192 = 2^13\n  :");

    ret = getUserInput(&new_sinc3);

    if ((new_sinc3 >= 0) && (new_sinc3 <= 8192) && (ret == SUCCESS)) {
        pc.printf("%d\n", new_sinc3);

        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx32, AD77681_SINC3, new_sinc3);
        pc.printf(" SINC3 OSR is set to %d\n", (new_sinc3 + 1) * 32);
    } else {
        pc.printf("%d\n", new_sinc3);
        pc.printf(" Invalid option - too large number\n");
    }
}

/**
 * Set SINC5 filter
 *
 */
void static set_SINC5_filter(void)
{
    uint32_t new_sinc5;

    pc.printf(" AD7768-1 SINC5 filter Oversampling ratios: \n");
    pc.printf("  1 - Oversampled by 8\n");
    pc.printf("  2 - Oversampled by 16\n");
    pc.printf("  3 - Oversampled by 32\n");
    pc.printf("  4 - Oversampled by 64\n");
    pc.printf("  5 - Oversampled by 128\n");
    pc.printf("  6 - Oversampled by 256\n");
    pc.printf("  7 - Oversampled by 512\n");
    pc.printf("  8 - Oversampled by 1024\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_sinc5);
    pc.putc('\n');

    switch (new_sinc5) {
    case 1:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx32, AD77681_SINC5_DECx8, 0);
        pc.printf(" SINC5 with OSRx8 set\n");
        break;
    case 2:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx32, AD77681_SINC5_DECx16, 0);
        pc.printf(" SINC5 with OSRx16 set\n");
        break;
    case 3:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx32, AD77681_SINC5, 0);
        pc.printf(" SINC5 with OSRx32 set\n");
        break;
    case 4:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx64, AD77681_SINC5, 0);
        pc.printf(" SINC5 with OSRx64 set\n");
        break;
    case 5:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx128, AD77681_SINC5, 0);
        pc.printf(" SINC5 with OSRx128 set\n");
        break;
    case 6:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx256, AD77681_SINC5, 0);
        pc.printf(" SINC5 with OSRx256 set\n");
        break;
    case 7:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx512, AD77681_SINC5, 0);
        pc.printf(" SINC5 with OSRx512 set\n");
        break;
    case 8:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx1024, AD77681_SINC5, 0);
        pc.printf(" SINC5 with OSRx1024 set\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
}

/**
 * Set FIR filter
 *
 */
void static set_FIR_filter(void)
{
    uint32_t new_fir;

    pc.printf(" AD7768-1 FIR filter Oversampling ratios: \n");
    pc.printf("  1 - Oversampled by 32\n");
    pc.printf("  2 - Oversampled by 64\n");
    pc.printf("  3 - Oversampled by 128\n");
    pc.printf("  4 - Oversampled by 256\n");
    pc.printf("  5 - Oversampled by 512\n");
    pc.printf("  6 - Oversampled by 1024\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_fir);
    pc.putc('\n');

    switch (new_fir) {
    case 1:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx32, AD77681_FIR, 0);
        pc.printf(" FIR with OSRx32 set\n");
        break;
    case 2:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx64, AD77681_FIR, 0);
        pc.printf(" FIR with OSRx64 set\n");
        break;
    case 3:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx128, AD77681_FIR, 0);
        pc.printf(" FIR with OSRx128 set\n");
        break;
    case 4:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx256, AD77681_FIR, 0);
        pc.printf(" FIR with OSRx256 set\n");
        break;
    case 5:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx512, AD77681_FIR, 0);
        pc.printf(" FIR with OSRx512 set\n");
        break;
    case 6:
        ad77681_set_filter_type(device, AD77681_SINC5_FIR_DECx1024, AD77681_FIR, 0);
        pc.printf(" FIR with OSRx1024 set\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
}

/**
 * Set 50HZ rejection bit when SINC3 is being used
 *
 */
void static set_50HZ_rej(void)
{
    uint32_t new_50Hz;

    pc.printf(" AD7768-1 SINC3 50/60Hz rejection: \n");
    pc.printf("  1 - 50/60Hz rejection enable \n");
    pc.printf("  2 - 50/60Hz rejection disable \n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_50Hz);
    pc.putc('\n');

    switch (new_50Hz) {
    case 1:
        ad77681_set_50HZ_rejection(device, ENABLE);
        pc.printf(" SINC3 50/60Hz rejection enabled\n");
        break;
    case 2:
        ad77681_set_50HZ_rejection(device, DISABLE);
        pc.printf(" SINC3 50/60Hz rejection disabled\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
}

/**
 * Insert user-defined FIR filter coeffs
 *
 */
void static set_user_defined_FIR(void)
{
    const uint8_t coeff_reg_length = 56;        // Maximum allowed number of coefficients in the coeff register

    pc.printf(" AD7768-1 User Defined FIR filter\n");

    if ((ARRAY_SIZE(programmable_FIR) <= coeff_reg_length) && (count_of_active_coeffs <= coeff_reg_length)) {
        pc.printf("  Aplying user-defined FIR filter coefficients from 'cn0535_init_params.h' programmable_FIR[56] \n");
        ad77681_programmable_filter(device, programmable_FIR, count_of_active_coeffs);
        pc.printf("  Coeffs inserted successfully\n");
    } else
        pc.printf("  Incorrect count of coefficients in 'cn0535_init_params.h' programmable_FIR[56]\n");
}

/**
 * AIN and REF buffers controll
 *
 */
void static menu_6_ad77681_AIN_buffers_controll(void)
{
    uint32_t new_AD77681_REF_buffer = 0;

    pc.printf(" AD7768-1 Analog IN precharge buffers settings: \n");
    pc.printf("  1 - Turn ON  both precharge buffers\n");
    pc.printf("  2 - Turn OFF both precharge buffers\n");
    pc.printf("  3 - Turn ON  AIN- precharge buffer\n");
    pc.printf("  4 - Turn OFF AIN- precharge buffer\n");
    pc.printf("  5 - Turn ON  AIN+ precharge buffer\n");
    pc.printf("  6 - Turn OFF AIN+ precharge buffer\n");
    pc.printf(" Select an option: \n");


    getUserInput(&new_AD77681_REF_buffer);
    pc.putc('\n');

    switch (new_AD77681_REF_buffer) {
    case 1:
        ad77681_set_AINn_buffer(device, AD77681_AINn_ENABLED);
        ad77681_set_AINp_buffer(device, AD77681_AINp_ENABLED);
        pc.printf(" AIN+ and AIN- enabled\n");
        break;
    case 2:
        ad77681_set_AINn_buffer(device, AD77681_AINn_DISABLED);
        ad77681_set_AINp_buffer(device, AD77681_AINp_DISABLED);
        pc.printf(" AIN+ and AIN- disabled\n");
        break;
    case 3:
        ad77681_set_AINn_buffer(device, AD77681_AINn_ENABLED);
        pc.printf(" AIN- Enabled\n");
        break;
    case 4:
        ad77681_set_AINn_buffer(device, AD77681_AINn_DISABLED);
        pc.printf(" AIN- Disabled\n");
        break;
    case 5:
        ad77681_set_AINp_buffer(device, AD77681_AINp_ENABLED);
        pc.printf(" AIN+ Enabled\n");
        break;
    case 6:
        ad77681_set_AINp_buffer(device, AD77681_AINp_DISABLED);
        pc.printf(" AIN+ Disabled\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * AIN and REF buffers controll
 *
 */
void static menu_7_ad77681_REF_buffers_controll(void)
{

    uint32_t  new_REF_buffer = 0;

    pc.printf(" REF buffers settings: \n");
    pc.printf("  1 - Full REF- reference buffer\n");
    pc.printf("  2 - Full REF+ reference buffer\n");
    pc.printf("  3 - Unbuffered REF- reference buffer\n");
    pc.printf("  4 - Unbuffered REF+ reference buffer\n");
    pc.printf("  5 - Precharge  REF- reference buffer\n");
    pc.printf("  6 - Precharge  REF+ reference buffer\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_REF_buffer);
    pc.putc('\n');

    switch (new_REF_buffer) {
    case 1:
        ad77681_set_REFn_buffer(device, AD77681_BUFn_FULL_BUFFER_ON);
        pc.printf(" Fully buffered REF-\n");
        break;
    case 2:
        ad77681_set_REFp_buffer(device, AD77681_BUFp_FULL_BUFFER_ON);
        pc.printf(" Fully buffered REF+\n");
        break;
    case 3:
        ad77681_set_REFn_buffer(device, AD77681_BUFn_DISABLED);
        pc.printf(" Unbuffered REF-\n");
        break;
    case 4:
        ad77681_set_REFp_buffer(device, AD77681_BUFp_DISABLED);
        pc.printf(" Unbuffered REF+\n");
        break;
    case 5:
        ad77681_set_REFn_buffer(device, AD77681_BUFn_ENABLED);
        pc.printf(" Precharge buffer on REF-\n");
        break;
    case 6:
        ad77681_set_REFp_buffer(device, AD77681_BUFp_ENABLED);
        pc.printf(" Precharge buffer on REF+\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;

    }
    print_prompt();
}

/**
 * VCM output controll
 *
 */
void static menu_8_set_ad77681_vcm_setup(void)
{
    uint32_t new_vcm = 0;

    pc.printf(" Avaliable VCM output voltage levels: \n");
    pc.printf("  1 - VCM = (AVDD1-AVSS)/2\n");
    pc.printf("  2 - VCM = 2.5V\n");
    pc.printf("  3 - VCM = 2.05V\n");
    pc.printf("  4 - VCM = 1.9V\n");
    pc.printf("  5 - VCM = 1.65V\n");
    pc.printf("  6 - VCM = 1.1V\n");
    pc.printf("  7 - VCM = 0.9V\n");
    pc.printf("  8 - VCM off\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_vcm);
    pc.putc('\n');

    switch (new_vcm) {

    case 1:
        ad77681_set_VCM_output(device, AD77681_VCM_HALF_VCC);
        pc.printf(" VCM set to half of the Vcc\n");
        break;
    case 2:
        ad77681_set_VCM_output(device, AD77681_VCM_2_5V);
        pc.printf(" VCM set to 2.5V\n");
        break;
    case 3:
        ad77681_set_VCM_output(device, AD77681_VCM_2_05V);
        pc.printf(" VCM set to 2.05V\n");
        break;
    case 4:
        ad77681_set_VCM_output(device, AD77681_VCM_1_9V);
        pc.printf(" VCM set to 1.9V\n");
        break;
    case 5:
        ad77681_set_VCM_output(device, AD77681_VCM_1_65V);
        pc.printf(" VCM set to 1.65V\n");
        break;
    case 6:
        ad77681_set_VCM_output(device, AD77681_VCM_1_1V);
        pc.printf(" VCM set to 1.1V\n");
        break;
    case 7:
        ad77681_set_VCM_output(device, AD77681_VCM_0_9V);
        pc.printf(" VCM set to 0.9V\n");
        break;
    case 8:
        ad77681_set_VCM_output(device, AD77681_VCM_OFF);
        pc.printf(" VCM OFF\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Set data output mode
 *
 */
void static menu_9_set_ad77681_data_output_mode(void)
{
    uint32_t new_data_mode = 0, new_length = 0, new_status = 0, new_crc = 0;

    pc.printf(" ADC data outpup modes: \n");
    pc.printf("  1 - Continuous: waiting for DRDY\n");
    pc.printf("  2 - Continuous one shot: waiting for SYNC_IN\n");
    pc.printf("  3 - Single-conversion standby\n");
    pc.printf("  4 - Periodic standby\n");
    pc.printf("  5 - Standby mode\n");
    pc.printf("  6 - 16bit or 24bit data format\n");
    pc.printf("  7 - Status bit output\n");
    pc.printf("  8 - Switch form diag mode to measure\n");
    pc.printf("  9 - Switch form measure to diag mode\n");
    pc.printf(" 10 - Set CRC type\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_data_mode);
    pc.putc('\n');

    switch (new_data_mode) {
    case 1:
        ad77681_set_conv_mode(device, AD77681_CONV_CONTINUOUS, device->diag_mux_sel, device->conv_diag_sel);         // DIAG MUX NOT SELECTED
        pc.printf(" Continuous mode set\n");
        break;
    case 2:
        ad77681_set_conv_mode(device, AD77681_CONV_ONE_SHOT, device->diag_mux_sel, device->conv_diag_sel);
        pc.printf(" Continuous one shot conversion set\n");
        break;
    case 3:
        ad77681_set_conv_mode(device, AD77681_CONV_SINGLE, device->diag_mux_sel, device->conv_diag_sel);
        pc.printf(" Single conversion standby mode set\n");
        break;
    case 4:
        ad77681_set_conv_mode(device, AD77681_CONV_PERIODIC, device->diag_mux_sel, device->conv_diag_sel);
        pc.printf(" Periodiec standby mode set\n");
        break;
    case 5:
        ad77681_set_conv_mode(device, AD77681_CONV_STANDBY, device->diag_mux_sel, device->conv_diag_sel);
        pc.printf(" Standby mode set\n");
        break;
    case 6:
        pc.printf(" Conversion length select: \n");
        pc.printf("  1 - 24bit length\n");
        pc.printf("  2 - 16bit length\n");

        getUserInput(&new_length);
        pc.putc('\n');

        switch (new_length) {
        case 1:
            ad77681_set_convlen(device, AD77681_CONV_24BIT);
            pc.printf(" 24bit data output format selected\n");
            break;
        case 2:
            ad77681_set_convlen(device, AD77681_CONV_16BIT);
            pc.printf(" 16bit data output format selected\n");
            break;
        default:
            pc.printf(" Invalid option\n");
            break;
        }
        break;
    case 7:
        pc.printf(" Status bit output: \n");
        pc.printf("  1 - Enable status bit after each ADC conversion\n");
        pc.printf("  2 - Disable status bit after each ADC conversion\n");

        getUserInput(&new_status);
        pc.putc('\n');

        switch (new_status) {
        case 1:
            ad77681_set_status_bit(device, true);
            pc.printf(" Status bit enabled\n");
            break;
        case 2:
            ad77681_set_status_bit(device, false);
            pc.printf(" Status bit disabled\n");
            break;
        default:
            pc.printf(" Invalid option\n");
            break;
        }

        break;
    case 8:
        ad77681_set_conv_mode(device, device->conv_mode, device->diag_mux_sel, false);      // DIAG MUX NOT SELECTED
        pc.printf(" Measure mode selected\n");
        break;
    case 9:
        ad77681_set_conv_mode(device, device->conv_mode, device->diag_mux_sel, true);       // DIAG MUX SELECTED
        pc.printf(" Diagnostic mode selected\n");
        break;
    case 10:
        pc.printf(" CRC settings \n");
        pc.printf("  1 - Disable CRC\n");
        pc.printf("  2 - 8-bit polynomial CRC\n");
        pc.printf("  3 - XOR based CRC\n");

        getUserInput(&new_crc);
        pc.putc('\n');

        switch (new_crc) {
        case 1:
            if(ad77681_set_crc_sel(device, AD77681_NO_CRC)==SUCCESS)
                pc.printf(" CRC disabled\n");
            else
                pc.printf("Command Failed\n");
            break;
        case 2:
            ad77681_set_crc_sel(device, AD77681_CRC);
            pc.printf("  8-bit polynomial CRC method selected\n");
            break;
        case 3:
            ad77681_set_crc_sel(device, AD77681_XOR);
            pc.printf("  XOR based CRC method selected\n");
            break;
        default:
            pc.printf(" Invalid option\n");
            break;
        }
        break;

    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Set diagnostic mode
 *
 */
void static menu_10_set_ad77681_diagnostic_mode(void)
{
    uint32_t new_diag_mode = 0;

    pc.printf(" ADC diagnostic modes: \n");
    pc.printf("  1 - Internal temperature sensor\n");
    pc.printf("  2 - AIN shorted\n");
    pc.printf("  3 - Positive full-scale\n");
    pc.printf("  4 - Negative full-scale\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_diag_mode);
    pc.putc('\n');

    switch (new_diag_mode) {
    case 1:
        ad77681_set_conv_mode(device, device->conv_mode, AD77681_TEMP_SENSOR, true);
        pc.printf(" Diagnostic mode: Internal temperature sensor selected\n");
        break;
    case 2:
        ad77681_set_conv_mode(device, device->conv_mode, AD77681_AIN_SHORT, true);
        pc.printf(" Diagnostic mode: AIN shorted selected\n");
        break;
    case 3:
        ad77681_set_conv_mode(device, device->conv_mode, AD77681_POSITIVE_FS, true);
        pc.printf(" Diagnostic mode: Positive full-scale selected\n");
        break;
    case 4:
        ad77681_set_conv_mode(device, device->conv_mode, AD77681_NEGATIVE_FS, true);
        pc.printf(" Diagnostic mode: Negative full-scale selected\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Set Gains and Offsets
 *
 */
void static menu_11_set_ad77681_gains_offsets(void)
{
    uint32_t gain_offset, ret;
    uint32_t new_menu_select;

    pc.printf(" Gains and Offsets settings: \n");
    pc.printf("  1 - Set gain\n");
    pc.printf("  2 - Set offset\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_menu_select);
    pc.putc('\n');

    switch (new_menu_select) {
    case 1:
        pc.printf(" Insert new Gain value in decimal form\n");
        ret = getUserInput(&gain_offset);

        if ((gain_offset <= 0xFFFFFF) && (ret == SUCCESS)) {
            ad77681_apply_gain(device, gain_offset);
            pc.printf(" Value %d has been successfully inserted to the Gain register\n", gain_offset);
        } else
            pc.printf(" Invalid value\n");
        break;
    case 2:
        pc.printf(" Insert new Offset value in decimal form\n");
        ret = getUserInput(&gain_offset);

        if ((gain_offset <= 0xFFFFFF) && (ret == SUCCESS)) {
            ad77681_apply_offset(device, gain_offset);
            pc.printf(" Value %d has been successfully inserted to the Offset register\n", gain_offset);
        } else
            pc.printf(" Invalid value\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Read ADC status from status registers
 *
 */
void static menu_12_ad77681_read_master_status(void)
{
    uint8_t reg_read_buf[3];
    char binary_number[8];

    ad77681_status(device, current_status);     // Read AD7768-1 Status
    pc.putc('\n');
    pc.printf("== MASTER STATUS REGISER\n");
    pc.printf("Master error:          %s\n", ((current_status->master_error == 0) ? "OK" : "FAULT"));
    pc.printf("ADC error:             %s\n", ((current_status->adc_error == 0) ? "OK" : "FAULT"));
    pc.printf("Dig error:             %s\n", ((current_status->dig_error == 0) ? "OK" : "FAULT"));
    pc.printf("Ext. clock:            %s\n", ((current_status->adc_err_ext_clk_qual == 0) ? "OK" : "FAULT"));
    pc.printf("Filter saturated:      %s\n", ((current_status->adc_filt_saturated == 0) ? "OK" : "FAULT"));
    pc.printf("Filter not settled:    %s\n", ((current_status->adc_filt_not_settled == 0) ? "OK" : "FAULT"));
    pc.printf("SPI error:             %s\n", ((current_status->spi_error == 0) ? "OK" : "FAULT"));
    pc.printf("POR Flag:              %s\n", ((current_status->por_flag == 0) ? "OK" : "FAULT"));

    if (current_status->spi_error == 1) {
        pc.printf("\n== SPI DIAG STATUS REGISER\n");
        pc.printf("SPI ignore error:      %s\n", ((current_status->spi_ignore == 0) ? "OK" : "FAULT"));
        pc.printf("SPI clock count error: %s\n", ((current_status->spi_clock_count == 0) ? "OK" : "FAULT"));
        pc.printf("SPI read error:        %s\n", ((current_status->spi_read_error == 0) ? "OK" : "FAULT"));
        pc.printf("SPI write error:       %s\n", ((current_status->spi_write_error == 0) ? "OK" : "FAULT"));
        pc.printf("SPI CRC error:         %s\n", ((current_status->spi_crc_error == 0) ? "OK" : "FAULT"));
    }

    if (current_status->adc_error == 1) {
        pc.printf("\n== ADC DIAG STATUS REGISER\n");
        pc.printf("DLDO PSM error:        %s\n", ((current_status->dldo_psm_error == 0) ? "OK" : "FAULT"));
        pc.printf("ALDO PSM error:        %s\n", ((current_status->aldo_psm_error == 0) ? "OK" : "FAULT"));
        pc.printf("REF DET error:         %s\n", ((current_status->ref_det_error == 0) ? "OK" : "FAULT"));
        pc.printf("FILT SAT error:        %s\n", ((current_status->filt_sat_error == 0) ? "OK" : "FAULT"));
        pc.printf("FILT NOT SET error:    %s\n", ((current_status->filt_not_set_error == 0) ? "OK" : "FAULT"));
        pc.printf("EXT CLK QUAL error:    %s\n", ((current_status->ext_clk_qual_error == 0) ? "OK" : "FAULT"));
    }

    if (current_status->dig_error == 1) {
        pc.printf("\n== DIGITAL DIAG STATUS REGISER\n");
        pc.printf("Memory map CRC error:  %s\n", ((current_status->memoy_map_crc_error == 0) ? "OK" : "FAULT"));
        pc.printf("RAM CRC error:         %s\n", ((current_status->ram_crc_error == 0) ? "OK" : "FAULT"));
        pc.printf("FUSE CRC error:        %s\n", ((current_status->fuse_crc_error == 0) ? "OK" : "FAULT"));
    }

    pc.putc('\n');
    print_prompt();
}

/**
 * Register read
 *
 */
void static menu_13_ad77681_read_register(void)
{
    uint32_t new_reg_to_read = 0;
    uint8_t reg_read_buf[3], read_adc_data[6], hex_number = 0;
    uint8_t HI = 0, MID = 0, LO = 0;
    char binary_number[8];

    pc.printf(" Read desired register: \n");
    pc.printf("  1 - 0x03        - Chip type\n");
    pc.printf("  2 - 0x14        - Interface format\n");
    pc.printf("  3 - 0x15        - Power clock\n");
    pc.printf("  4 - 0x16        - Analog\n");
    pc.printf("  5 - 0x17        - Analog2\n");
    pc.printf("  6 - 0x18        - Conversion\n");
    pc.printf("  7 - 0x19        - Digital filter\n");
    pc.printf("  8 - 0x1A        - SINC3 Dec. rate MSB\n");
    pc.printf("  9 - 0x1B        - SINC3 Dec. rate LSB\n");
    pc.printf(" 10 - 0x1C        - Duty cycle ratio\n");
    pc.printf(" 11 - 0x1D        - Sync, Reset\n");
    pc.printf(" 12 - 0x1E        - GPIO Controll\n");
    pc.printf(" 13 - 0x1F        - GPIO Write\n");
    pc.printf(" 14 - 0x20        - GPIO Read\n");
    pc.printf(" 15 - 0x21 - 0x23 - Offset register\n");
    pc.printf(" 16 - 0x24 - 0x26 - Gain register\n");
    pc.printf(" 17 - 0x2C        - ADC Data\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_reg_to_read);
    pc.putc('\n');

    switch (new_reg_to_read) {

    case 1:
        ad77681_spi_reg_read(device, AD77681_REG_CHIP_TYPE, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x03 - Chip type register is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 2:
        ad77681_spi_reg_read(device, AD77681_REG_INTERFACE_FORMAT, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x14 - Interface format register is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 3:
        ad77681_spi_reg_read(device, AD77681_REG_POWER_CLOCK, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x15 - Power clock register is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 4:
        ad77681_spi_reg_read(device, AD77681_REG_ANALOG, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x16 - Anlaog register is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 5:
        ad77681_spi_reg_read(device, AD77681_REG_ANALOG2, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x17 - Analog2 regster is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 6:
        ad77681_spi_reg_read(device, AD77681_REG_CONVERSION, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x18 - Conversion register is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 7:
        ad77681_spi_reg_read(device, AD77681_REG_DIGITAL_FILTER, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x19 - Digital filter register is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 8:
        ad77681_spi_reg_read(device, AD77681_REG_SINC3_DEC_RATE_MSB, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x1A - SINC3 Dec. rate MSB is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 9:
        ad77681_spi_reg_read(device, AD77681_REG_SINC3_DEC_RATE_LSB, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x1B - SINC3 Dec. rate LSB is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 10:
        ad77681_spi_reg_read(device, AD77681_REG_DUTY_CYCLE_RATIO, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x1C - Duty cycle ratio 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 11:
        ad77681_spi_reg_read(device, AD77681_REG_SYNC_RESET, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x1D - Sync, Reset 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 12:
        ad77681_spi_reg_read(device, AD77681_REG_GPIO_CONTROL, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x1E - GPIO Controll is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 13:
        ad77681_spi_reg_read(device, AD77681_REG_GPIO_WRITE, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x1F - GPIO Write is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 14:
        ad77681_spi_reg_read(device, AD77681_REG_GPIO_READ, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x20 - GPIO Read is: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    case 15:
        ad77681_spi_reg_read(device, AD77681_REG_OFFSET_HI, reg_read_buf);
        HI = reg_read_buf[1];

        ad77681_spi_reg_read(device, AD77681_REG_OFFSET_MID, reg_read_buf);
        MID = reg_read_buf[1];

        ad77681_spi_reg_read(device, AD77681_REG_OFFSET_LO, reg_read_buf);
        LO = reg_read_buf[1];

        pc.printf(" Value of 0x21 - 0x23 - Offset register is: 0x%x %x %x\n", HI, MID, LO);
        break;
    case 16:
        ad77681_spi_reg_read(device, AD77681_REG_GAIN_HI, reg_read_buf);
        HI = reg_read_buf[1];

        ad77681_spi_reg_read(device, AD77681_REG_GAIN_MID, reg_read_buf);
        MID = reg_read_buf[1];

        ad77681_spi_reg_read(device, AD77681_REG_GAIN_LO, reg_read_buf);
        LO = reg_read_buf[1];

        pc.printf(" Value of 0x24 - 0x26 - Gain register is: 0x%x %x %x\n", HI, MID, LO);
        break;
    case 17:
        ad77681_spi_read_adc_data(device, read_adc_data, AD77681_REGISTER_DATA_READ);
        pc.printf(" Value of 0x2C - ADC data is: 0x%x 0x%x 0x%x\n", read_adc_data[1], read_adc_data[2], read_adc_data[3]);
        break;
    case 18:
        ad77681_spi_reg_read(device, AD77681_REG_INTERFACE_FORMAT, reg_read_buf);
        print_binary(reg_read_buf[1], binary_number);
        pc.printf(" Value of 0x14 -REG_INTERFACE_FORMATis: 0x%x  0b%s\n", reg_read_buf[1], binary_number);
        break;
    default :
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Print measured data and transfered to voltage
 *
 */
void static menu_14_read_ad77681_single_conv_data(void)
{

    uint8_t adc_reg[6];
    uint32_t raw_code;
    int32_t converted_data;
    double voltage;
    int32_t shifted_data;
    char buf[15];

    ad77681_spi_read_adc_data(device, adc_reg, AD77681_REGISTER_DATA_READ);
    raw_code = (adc_reg[1] << 16) | (adc_reg[2] << 8) | (adc_reg[3] << 0);
    // Printing Voltage
    pc.printf("\n\nVoltage\n");
    ad77681_data_to_voltage(device, &raw_code, &voltage);
    sprintf(buf, "%.9f \n",voltage);
    pc.printf(buf);
    memset(buf, 0, sizeof(buf));//clears buffer
    
    // Printing Raw Code
    pc.printf("\n\nRaw Code\n");
    pc.printf("%d\n", raw_code);
    
    // Printing Shifted Code
    pc.printf("\n\nShifted Code\n");
    if (raw_code & 0x800000)
        shifted_data = (int32_t)((0xFF << 24) | raw_code);
    else
        shifted_data = (int32_t)((0x00 << 24) | raw_code);
    pc.printf("%d\n", shifted_data + AD7768_HALF_SCALE);

    print_prompt();
}

/**
 * Read ADC data
 *
 */
void static menu_15_read_ad77681_continuous_data(void)
{
    uint8_t buf[6];
    uint32_t new_sample_count = 0;
    int32_t ret;

    pc.printf(" Read Continuous ADC Data");
    pc.printf("  Input number of samples (1 to 4096): \n");
    ret = getUserInput(&new_sample_count);                  // Get user input

    if ((new_sample_count <= 4096) && (ret == SUCCESS) ) {
        pc.printf("\n%d of samples\n", new_sample_count);   // Print Desired Measurement Count
        measured_data.samples = (uint16_t)(new_sample_count);
        measured_data.finish = false;
        measured_data.count = 0;
        pc.printf("Sampling....\n");
        ad77681_set_continuos_read(device, AD77681_CONTINUOUS_READ_ENABLE);
        __enable_irq();                                             // Enable all interupts
        drdy.enable_irq();                                          // Enable interrupt on DRDY pin
        drdy.fall(&drdy_interrupt);                                 // Interrupt on falling edne of DRDY

        while (!measured_data.finish) { // While loop. Waiting for the measurements to be completed
            if (int_event==true) {      // Checks if Interrupt Occurred
                ad77681_spi_read_adc_data(device, buf, AD77681_CONTINUOUS_DATA_READ);    // Read the continuous read data
                if (device->conv_len == AD77681_CONV_24BIT)                                                     // 24bit format
                    measured_data.raw_data[measured_data.count] = (buf[0] << 16 | buf[1] << 8 | buf[2]<< 0);    // Combining the SPI buffers
                else                                                                                            // 16bit format
                    measured_data.raw_data[measured_data.count] = (buf[0] << 8 | buf[1]<< 0);                   // Combining the SPI buffers
                measured_data.count++;  // Increment Measured Data Counter
                int_event=false;        // Set int event flag after reading the Data
            }
        }
        ad77681_set_continuos_read(device, AD77681_CONTINUOUS_READ_DISABLE);            // Disable continuous ADC read
        pc.printf("Done Sampling....\n");
    }

    else {
        pc.printf(" Invalid option\n");
    }
    print_prompt();
}

/**
 * Print measured data and transfered to voltage
 *
 */
void static menu_16_print_ad77681_continuos_read_data(void)
{
    double voltage;
    int32_t shifted_data;
    uint16_t i;
    char buf[15];

    if (measured_data.finish) {
        // Printing Voltage
        pc.printf("\n\nVoltage\n");
        for ( i = 0; i < measured_data.samples; i++) {
            ad77681_data_to_voltage(device, &measured_data.raw_data[i], &voltage);
            sprintf(buf, "%.9f \n",voltage);
            pc.printf(buf);
            memset(buf, 0, sizeof(buf));//clears buffer
        }
        // Printing Codes
        pc.printf("\n\nCodes\n");
        for(i = 0 ; i < measured_data.samples ; i++) {
            if (measured_data.raw_data[i] & 0x800000)
                shifted_data = (int32_t)((0xFF << 24) | measured_data.raw_data[i]);
            else
                shifted_data = (int32_t)((0x00 << 24) | measured_data.raw_data[i]);

            pc.printf("%d\n", shifted_data + AD7768_HALF_SCALE);
        }
        // Printing Raw Date
        pc.printf("\n\nRaw data\n");
        for (i = 0; i < measured_data.samples; i++)
            pc.printf("%d\n", measured_data.raw_data[i]);
        // Set  measured_data.finish to false after Printing
        measured_data.finish = false;
    } else
        pc.printf("Data not prepared\n");
    print_prompt();
}

/**
 * Chceck read and write functionaity by writing to and reading from scratchpad register
 *
 */
void static menu_17_ad77681_check_scratchpad(void)
{
    uint32_t new_menu_select;
    uint8_t chceck_sequence;
    int32_t ret;
    
    pc.printf(" Scratchpad check\n");
    pc.printf(" Insert 8bit number for scratchpad check: \n");

    ret = getUserInput(&new_menu_select);                   // Get user input

    if ((new_menu_select <= 0xFF) && (new_menu_select >= 0) && (ret == SUCCESS)) {
        chceck_sequence = (uint8_t)(new_menu_select);
        ret = ad77681_scratchpad(device, &chceck_sequence); // Write and read Scratch Pad
        pc.printf("  Insered sequence:  %d\n  Returned sequence: %d\n", new_menu_select, chceck_sequence);
        if (ret == SUCCESS)
            pc.printf("  SUCCESS!\n");
        else
            pc.printf("  FAILURE!\n");
    } else
        pc.printf("  Invalid value\n");
    print_prompt();
}

void static menu_18_reset_ad77681_ADC(void)
{
    uint32_t new_reset_option = 0;

    pc.printf(" ADC reset opportunities: \n");
    pc.printf("  1 - Soft reset - over SPI\n");
    pc.printf("  2 - Hard reset - uing RESET pin\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_reset_option);
    pc.putc('\n');

    switch (new_reset_option) {
    case 1:
        ad77681_soft_reset(device);             // Perform soft reset thru SPI write
        pc.printf(" ADC after soft reset\n");
        break;
    case 2:
        adc_hard_reset();                       // Perform hard reset thru GPIO
        pc.printf(" ADC after hard reset\n");
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Rest and set the Board to default setting
 *
 */
void static menu_19_set_default_settings(void)
{

    int32_t default_settings_flag;

    adc_hard_reset();                                                               // Perform hard reset thru GPIO
    default_settings_flag = ad77681_setup(&device, init_params, &current_status);   // SETUP and check connection
    adc_gpio_init();                                                                // Initilized SDP-K1 GPIOS

    if (default_settings_flag == SUCCESS)
        pc.printf("\n Default settings successfull loaded\n");
    else
        pc.printf("\n Error in settings, please reset the ADC\n");
    print_prompt();
}

/**
 * Set Vref anc MCLK as "exteranl" values, depending on you setup
 *
 */
void static menu_20_mclk_vref(void)
{
    uint32_t input = 0, new_settings = 0;
    int32_t ret;

    pc.printf(" Set Vref and Mclk: \n");
    pc.printf("  1 - Change Vref\n");
    pc.printf("  2 - Change MCLK\n");
    pc.printf(" Select an option: \n");

    getUserInput(&new_settings);
    pc.putc('\n');

    switch (new_settings) {
    case 1:
        pc.printf(" Change Vref from %d mV to [mV]: ", device->vref);           // Vref change
        ret = getUserInput(&input);

        if ((input >= 1000) && (input <= 5000) && (ret == SUCCESS)) {
            pc.printf("\n New Vref value is %d mV", input);
            device->vref = input;
        } else
            pc.printf(" Invalid option\n");

        pc.putc('\n');
        break;

    case 2:
        pc.printf(" Change MCLK from %d kHz to [kHz]: ", device->mclk);         // MCLK change
        ret = getUserInput(&input);
        if ((input >= 10000) && (input <= 50000) && (ret == SUCCESS)) {
            pc.printf("\n New MCLK value is %d kHz\n", input);
            device->vref = input;
            ad77681_update_sample_rate(device);                                 // Update the sample rate after changinig the MCLK
        } else
            pc.printf(" Invalid option\n");

        pc.putc('\n');
        break;
    default:
        pc.printf(" Invalid option\n");
        break;
    }
    print_prompt();
}

/**
 * Prints out an array in binary form
 *
 */
void static print_binary(uint8_t number, char *binary_number)
{
    for (int8_t i = 7; i >= 0; i--) {
        if (number & 1)
            binary_number[i] = '1';
        else
            binary_number[i] = '0';
        number >>= 1;
    }
}

/**
 * Read user input from uart
 * *UserInput = 0 if failure
 *
 */
int32_t static getUserInput(uint32_t *UserInput)
{
    long uart_val;
    int32_t ret;

    ret = pc.scanf("%ld", &uart_val);       // Return 1 = OK, Return 0 = Fail

    if((ret == 0) || (uart_val < 0)) {      // Failure if uart_val is negative, or non-digit
        *UserInput = 0;
        return FAILURE;
    }
    *UserInput = (uint32_t)(uart_val);
    return SUCCESS;
}

/**
 * ADC hard reset thru SDP-K1 GPIO
 *
 */
void static adc_hard_reset()
{
    adc_rst=0;      // Set ADC reset pin to Low
    mdelay(100);    // Delay 100ms
    adc_rst=1;      // Set ADC reset pin to High
    mdelay(100);    // Delay 100ms
}

/**
 * ADC hard reset thru SDP-K1 GPIO
 *
 */
void static adc_gpio_init()
{
    ad77681_global_gpio(device, AD77681_GLOBAL_GPIO_ENABLE);                                    // Enable AD7768-1 GPIO pins
    ad77681_gpio_inout(device, AD77681_GPIO_CNTRL_ALL_GPIOS_OP_EN(0x0F), AD77681_ALL_GPIOS);    // Set AD7768-1 GPIO1 - GPIO3 as Output
    ad77681_gpio_write(device,AD77681_GPIO_CNTRL_ALL_GPIOS_OP_EN(0x05), AD77681_ALL_GPIOS);     // Set FDA to Low Power mode and PGIA Gain to 1
}