Pratyush Mallick
/
nano_dac
this is testing
app/nanodac_console_app.c
- Committer:
- pmallick
- Date:
- 2021-01-14
- Revision:
- 0:e8a1ba50c46b
File content as of revision 0:e8a1ba50c46b:
/*! ***************************************************************************** @file: nanodac_console_app.c @brief: Implementation for the menu functions that handles the nanodac functionality @details: This file is specific to nanodac console menu application handle. The functions defined in this file performs the action based on user selected console menu. ----------------------------------------------------------------------------- Copyright (c) 2020 Analog Devices, Inc. All rights reserved. This software is proprietary to Analog Devices, Inc. and its licensors. By using this software you agree to the terms of the associated Analog Devices Software License Agreement. *****************************************************************************/ /******************************************************************************/ /***************************** Include Files **********************************/ /******************************************************************************/ #include <stdio.h> #include <string.h> #include <stdbool.h> #include "app_config.h" #include "ad5686.h" #include "platform_support.h" #include "platform_drivers.h" #include "i2c_extra.h" #include "spi_extra.h" #include "nanodac_console_app.h" /******************************************************************************/ /********************** Macros and Constants Definitions **********************/ /******************************************************************************/ #if !defined(I2C_SLAVE_ADDRESS) #define I2C_SLAVE_ADDRESS 0 // For non I2C devices #endif #define INTERNAL_VREF_VOLTAGE 2.5 #define INTERNAL_VREF_SOURCE 0U #define EXTERNAL_VREF_SOURCE 1U #define GAIN_LOW 1 #define GAIN_HIGH 2 /******************************************************************************/ /********************** Variables and User Defined Data Types *****************/ /******************************************************************************/ // Pointer to a nanodac device structure static struct ad5686_dev *nanodac_dev = NULL; // Current DAC channel (default value is channel 0) static enum ad5686_dac_channels current_dac_channel = AD5686_CH_0; // Define the Vref source and voltage #if !defined(EXT_VREF_SOURCE_ONLY) // Default Vref voltage is 2.5v for internal reference source static uint32_t vref_source = INTERNAL_VREF_SOURCE; static float vref_voltage = INTERNAL_VREF_VOLTAGE; #else // Vref voltage for external reference source is user selectable static uint32_t vref_source = EXTERNAL_VREF_SOURCE; static float vref_voltage = 0; #endif // Gain value (default is 1) static uint32_t gain = GAIN_LOW; // LDAC pin state (default is High/Vlogic) static uint32_t ldac_pin_state = GPIO_HIGH; // LDAC mask status (default is False/Disable) static bool ldac_mask_status = false; // Vref sources string static const char *vref_source_str[] = { "Internal", "External" }; // Operating mode string static const char *operating_mode_str[] = { "Normal Power-Up", "1K to GND", "100K to GND", "Three State" }; // Menu pre-declarations extern console_menu dac_channel_select_menu; extern console_menu vref_select_menu; extern console_menu gain_select_menu; extern console_menu dac_readback_select_menu; extern console_menu ldac_mask_select_menu; extern console_menu operating_mode_select_menu; extern console_menu ldac_pin_select_menu; /******************************************************************************/ /************************ Functions Declarations ******************************/ /******************************************************************************/ static void gpio_power_up_configuration(void); /******************************************************************************/ /************************ Functions Definitions *******************************/ /******************************************************************************/ /* @brief Initialize the nanodac device * @param none * @return SUCCESS(0), FAILURE(negative) **/ int32_t nanodac_app_initialize(void) { int32_t device_init_status; // Init status of device // Initialize the exra parameters for I2C initialization mbed_i2c_init_param i2c_init_extra_params = { .i2c_sda_pin = I2C_SDA, .i2c_scl_pin = I2C_SCL }; // Initialize the exra parameters for SPI initialization mbed_spi_init_param spi_init_extra_params = { .spi_miso_pin = SPI_MISO, .spi_mosi_pin = SPI_MOSI, .spi_clk_pin = SPI_SCK }; // Initialize the device structure struct ad5686_init_param nanodac_init_params = { // i2c_init_param { 100000, // I2C max speed (Hz) I2C_SLAVE_ADDRESS, // I2C slave address &i2c_init_extra_params // I2C extra init parameters }, // spi_init_param { 2000000, // SPI max speed (Hz) SPI_SS, // Chip select SPI_MODE_2, // SPI Mode &spi_init_extra_params // SPI extra init parameters }, // gpio_init_param { RESET_PIN, NULL }, // gpio_reset { LDAC_PIN, NULL }, // gpio_ldac { GAIN_PIN, NULL }, // gpio_gain ACTIVE_DEVICE // Active device }; // Initialize the device device_init_status = ad5686_init(&nanodac_dev, nanodac_init_params); // Configure the GPIOs specific to application upon power-up gpio_power_up_configuration(); return device_init_status; } /*! * @brief Set the power-up GPIO configurations * @return None */ static void gpio_power_up_configuration(void) { // Set the directions for GPIO pins (void)gpio_direction_output(nanodac_dev->gpio_gain, GPIO_OUT); (void)gpio_direction_output(nanodac_dev->gpio_ldac, GPIO_OUT); (void)gpio_direction_output(nanodac_dev->gpio_reset, GPIO_OUT); // Set the GPIO values gpio_set_value(nanodac_dev->gpio_reset, GPIO_HIGH); gpio_set_value(nanodac_dev->gpio_gain, GPIO_LOW); gpio_set_value(nanodac_dev->gpio_ldac, GPIO_HIGH); } /*! * @brief Display the header info for menu * @return None */ static void display_menu_header(void) { printf("\t%s (nanodac) | ", ACTIVE_DEVICE_NAME); printf("Vref:%s (%.1fV) | ", vref_source_str[vref_source], vref_voltage); printf("Gain:%ld"EOL, gain); } /*! * @brief Display the footer info for menu * @return None */ static void display_menu_footer(void) { // Display the device name printf("\tActive Channel: %d | ", current_dac_channel); printf("LDAC Pin: %ld | ", ldac_pin_state); printf("LDAC Mask: %d"EOL, ldac_mask_status); } /*! * @brief Handle the DAC channel selection menu * @param uint32_t channel_id- Selected DAC channel number * @return MENU_CONTINUE */ static int32_t menu_select_dac_channel(uint32_t channel_id) { // Store the dac channel for future read/write operations current_dac_channel = (enum ad5686_dac_channels)channel_id; printf(EOL EOL"\tDAC Channel %ld is selected..."EOL, channel_id); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to display DAC channel selection * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_dac_channels(uint32_t menu_id) { // Display the dac channel selection menu adi_do_console_menu(&dac_channel_select_menu); return MENU_CONTINUE; } /*! * @brief Handle the menu to write DAC input register * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_write_to_input_register(uint32_t menu_id) { uint16_t dac_data_input; // Data to be written to DAC printf(EOL"\tEnter the Data/Code (in decimal): "); dac_data_input = (uint16_t)adi_get_decimal_int(5); // Write DAC input register for current selected channel ad5686_write_register(nanodac_dev, current_dac_channel, dac_data_input); printf(EOL EOL"\tData %d written to DAC input register..."EOL, dac_data_input); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to update DAC register with value from input register * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_update_dac_from_input(uint32_t menu_id) { // Update the DAC with input register data for current selected channel ad5686_update_register(nanodac_dev, current_dac_channel); printf(EOL EOL"\tUpdated DAC register with contents of input register..."EOL); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to update DAC register by asserting LDAC pin * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_update_dac_by_ldac_assert(uint32_t menu_id) { // Update DAC registers by asserting LDAC pin High to Low gpio_set_value(nanodac_dev->gpio_ldac, GPIO_HIGH); mdelay(1); gpio_set_value(nanodac_dev->gpio_ldac, GPIO_LOW); mdelay(1); // Restore the previous state of LDAC pin if (ldac_pin_state == GPIO_HIGH) { gpio_set_value(nanodac_dev->gpio_ldac, GPIO_HIGH); } printf(EOL EOL"\tUpdated DAC register with contents of input register..."EOL); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to write and update DAC register directly * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_write_and_update_dac(uint32_t menu_id) { uint16_t dac_data_input; // Data to be written to DAC printf(EOL"\tEnter the Data/Code (in decimal): "); dac_data_input = (uint16_t)adi_get_decimal_int(5); // Update DAC data register for current selected channel ad5686_write_update_register(nanodac_dev, current_dac_channel, dac_data_input); printf(EOL EOL"\tDAC updated with Data %d"EOL, dac_data_input); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to select operating mode of DAC * @param uint32_t operating_mode_input- User input operating mode * @return MENU_CONTINUE */ static int32_t menu_select_operating_mode(uint32_t operating_mode_input) { // Select the operating mode of DAC ad5686_power_mode(nanodac_dev, current_dac_channel, operating_mode_input); printf(EOL EOL"\tSelected operating mode as %s"EOL, operating_mode_str[operating_mode_input]); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to display operating modes of DAC * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_dac_operating_modes(uint32_t menu_id) { // Display the operating mode select menu adi_do_console_menu(&operating_mode_select_menu); return MENU_CONTINUE; } /*! * @brief Handle the menu to select the reference source for DAC * @param uint32_t ref_source_input- user selected reference source * @return MENU_CONTINUE */ static int32_t menu_select_vref_source(uint32_t ref_source_input) { float user_vref_value = INTERNAL_VREF_VOLTAGE; // user input reference // voltage value if (ref_source_input == INTERNAL_VREF_SOURCE) { // Enable the internal reference source ad5686_internal_reference(nanodac_dev, AD5686_INTREF_EN); vref_source = INTERNAL_VREF_SOURCE; vref_voltage = INTERNAL_VREF_VOLTAGE; // Display the vref selections on console window printf(EOL"\tVref Source: %s"EOL, vref_source_str[vref_source]); printf("\tVref Voltage: %f"EOL, vref_voltage); } else if (ref_source_input == EXTERNAL_VREF_SOURCE) { printf(EOL EOL"\tEnter the external reference voltage"EOL); user_vref_value = adi_get_decimal_float(5); // Disable the internal reference source ad5686_internal_reference(nanodac_dev, AD5686_INTREF_DIS); vref_source = EXTERNAL_VREF_SOURCE; vref_voltage = user_vref_value; // Display the vref selections on console window printf(EOL"\tVref Source: %s"EOL, vref_source_str[vref_source]); printf("\tVref Voltage: %f"EOL, vref_voltage); } else { printf(EOL EOL"\tInvalid Vref Source selection"EOL); } adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to display the reference source for DAC * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_vref_sources(uint32_t menu_id) { // Display the Vref selection menu adi_do_console_menu(&vref_select_menu); return MENU_CONTINUE; } /*! * @brief Handle the menu to readback DAC register for selected channel * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_dac_readback(uint32_t menu_id) { uint16_t dac_data; // Readback DAC data float output_voltage; // Output voltage of DAC channel // Readback data for current selected DAC channel dac_data = ad5686_read_back_register(nanodac_dev, current_dac_channel); // Calculate equivalent output voltage output_voltage = (vref_voltage * gain * ((float)dac_data / TOTAL_OUTPUT_CODES)); printf(EOL EOL"\tDAC Channel %d Data: %d"EOL, current_dac_channel, dac_data); printf(EOL"\tVoltage: %.3f V"EOL EOL, output_voltage); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to select LDACx mask (x:DAC channel) * @param uint32_t mask_status- user input LDAC mask * @return MENU_CONTINUE */ static int32_t menu_set_ldac_mask(uint32_t mask_status) { // Set the LDAC mask (0/1) ad5686_ldac_mask(nanodac_dev, current_dac_channel, mask_status); ldac_mask_status = mask_status; printf(EOL EOL"\tLDAC Mask for Channel %d: %ld"EOL, current_dac_channel, mask_status); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to display LDACx mask menu selections * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_ldac_masks(uint32_t menu_id) { // Display the LDAC mask selection menu adi_do_console_menu(&ldac_mask_select_menu); return MENU_CONTINUE; } /*! * @brief Handle the menu to set LDAC pin state * @param uint32_t pin_state- user input pin state (HIGH/LOW) * @return MENU_CONTINUE */ static int32_t menu_set_ldac_pin(uint32_t pin_state) { if (pin_state == GPIO_HIGH) { gpio_set_value(nanodac_dev->gpio_ldac, GPIO_HIGH); } else { gpio_set_value(nanodac_dev->gpio_ldac, GPIO_LOW); } ldac_pin_state = pin_state; printf(EOL EOL"\tLDAC pin set to %ld"EOL, ldac_pin_state); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to assert LDAC pin to update DAC * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_select_ldac_pin_state(uint32_t menu_id) { // Display the LDAC pin selection menu adi_do_console_menu(&ldac_pin_select_menu); return MENU_CONTINUE; } /*! * @brief Handle the menu to set the DAC gain * @param uint32_t gain_input- Gain input value * @return MENU_CONTINUE */ static int32_t menu_set_gain(uint32_t gain_input) { // Set the device gain gain = gain_input; #if defined (SOFTWARE_CONTROLLED_GAIN) ad5686_gain_mode(nanodac_dev, gain); #else if (gain == GAIN_LOW) { gpio_set_value(nanodac_dev->gpio_gain, GPIO_LOW); } else { gpio_set_value(nanodac_dev->gpio_gain, GPIO_HIGH); } #endif printf(EOL EOL"\tGain set to %ld"EOL,gain); adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to display DAC gain selections * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_gain_selection(uint32_t menu_id) { // Display the DAC gain selection menu adi_do_console_menu(&gain_select_menu); return MENU_CONTINUE; } /*! * @brief Handle the menu to perform DAC software reset * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_assert_software_reset(uint32_t menu_id) { // Do device software reset ad5686_software_reset(nanodac_dev); printf(EOL"\tSoftware Reset Complete..."EOL); // Device reset disables the LDAC mask through hardware. // This needs to be synched with software. ldac_mask_status = false; adi_press_any_key_to_continue(); return MENU_CONTINUE; } /*! * @brief Handle the menu to perform DAC hardware reset * @param uint32_t menu_id- (Optional parameter) * @return MENU_CONTINUE */ static int32_t menu_assert_hardware_reset(uint32_t menu_id) { // Do device hardware reset gpio_set_value(nanodac_dev->gpio_reset, GPIO_LOW); mdelay(1); gpio_set_value(nanodac_dev->gpio_reset, GPIO_HIGH); printf(EOL"\tHardware Reset Complete..."EOL); // Device reset disables the LDAC mask through hardware. // This needs to be synched with software. ldac_mask_status = false; adi_press_any_key_to_continue(); return MENU_CONTINUE; } // Operating mode menu for DAC static console_menu_item operating_mode_select_items[] = { { "Normal Power-Up", 'A', menu_select_operating_mode, AD5686_PWRM_NORMAL }, #if defined(_1K_TO_GND_POWER_DOWN) { "1K to GND (Power-Down)", 'B', menu_select_operating_mode, AD5686_PWRM_1K }, #endif #if defined(_100K_TO_GND_POWER_DOWN) { "100K to GND (Power-Down)", 'C', menu_select_operating_mode, AD5686_PWRM_100K }, #endif #if defined(THREE_STATE_POWER_DOWN) { "Three-State (Power-Down)", 'D', menu_select_operating_mode, AD5686_PWRM_THREESTATE }, #endif }; console_menu operating_mode_select_menu = { .title = "Select Operating Mode", .items = operating_mode_select_items, .itemCount = ARRAY_SIZE(operating_mode_select_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = true }; // LDAC pin set menu for DAC static console_menu_item ldac_pin_select_items[] = { { "High (VLogic)", 'H', menu_set_ldac_pin, GPIO_HIGH }, { "Low (GND)", 'L', menu_set_ldac_pin, GPIO_LOW } }; console_menu ldac_pin_select_menu = { .title = "Select LDAC Mask", .items = ldac_pin_select_items, .itemCount = ARRAY_SIZE(ldac_pin_select_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = true }; // LDAC mask menu for DAC static console_menu_item ldac_mask_select_items[] = { { "Disable (LDAC Pin Controlled)", 'D', menu_set_ldac_mask, 0 }, { "Enable (LDAC Pin Ignored)", 'E', menu_set_ldac_mask, 1 } }; console_menu ldac_mask_select_menu = { .title = "Select LDAC Mask", .items = ldac_mask_select_items, .itemCount = ARRAY_SIZE(ldac_mask_select_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = true }; // Gain select menu for DAC static console_menu_item gain_select_items[] = { { "Gain= 1 (Vout: 0-Vref)", '1', menu_set_gain, GAIN_LOW }, { "Gain= 2 (Vout: 0-2*Vref)", '2', menu_set_gain, GAIN_HIGH } }; console_menu gain_select_menu = { .title = "Select Gain", .items = gain_select_items, .itemCount = ARRAY_SIZE(gain_select_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = true }; // Vref select menu for DAC static console_menu_item vref_select_items[] = { #if !defined(EXT_VREF_SOURCE_ONLY) { "Internal Vref", 'I', menu_select_vref_source, INTERNAL_VREF_SOURCE }, #endif { "External Vref", 'E', menu_select_vref_source, EXTERNAL_VREF_SOURCE } }; console_menu vref_select_menu = { .title = "Select Vref Source", .items = vref_select_items, .itemCount = ARRAY_SIZE(vref_select_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = true }; // Channel selection menu for DAC static console_menu_item dac_channel_select_items[] = { { "Channel 0", 'A', menu_select_dac_channel, (uint32_t)AD5686_CH_0 }, { "Channel 1", 'B', menu_select_dac_channel, (uint32_t)AD5686_CH_1 }, #if DAC_CHANNEL_COUNT > 2 { "Channel 2", 'C', menu_select_dac_channel, (uint32_t)AD5686_CH_2 }, { "Channel 3", 'D', menu_select_dac_channel, (uint32_t)AD5686_CH_3 }, #endif #if DAC_CHANNEL_COUNT > 4 { "Channel 4", 'E', menu_select_dac_channel, (uint32_t)AD5686_CH_4 }, { "Channel 5", 'F', menu_select_dac_channel, (uint32_t)AD5686_CH_5 }, { "Channel 6", 'G', menu_select_dac_channel, (uint32_t)AD5686_CH_6 }, { "Channel 7", 'H', menu_select_dac_channel, (uint32_t)AD5686_CH_7 }, #endif #if DAC_CHANNEL_COUNT > 8 { "Channel 8", 'I', menu_select_dac_channel, (uint32_t)AD5686_CH_8 }, { "Channel 9", 'J', menu_select_dac_channel, (uint32_t)AD5686_CH_9 }, { "Channel 10", 'K', menu_select_dac_channel, (uint32_t)AD5686_CH_10 }, { "Channel 11", 'L', menu_select_dac_channel, (uint32_t)AD5686_CH_11 }, { "Channel 12", 'M', menu_select_dac_channel, (uint32_t)AD5686_CH_12 }, { "Channel 13", 'N', menu_select_dac_channel, (uint32_t)AD5686_CH_13 }, { "Channel 14", 'O', menu_select_dac_channel, (uint32_t)AD5686_CH_14 }, { "Channel 15", 'P', menu_select_dac_channel, (uint32_t)AD5686_CH_15 }, #endif }; console_menu dac_channel_select_menu = { .title = "Select DAC Channel", .items = dac_channel_select_items, .itemCount = ARRAY_SIZE(dac_channel_select_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = true }; /* * Definition of the Main Menu Items and menu itself */ static console_menu_item main_menu_items[] = { #ifdef DISPLAY_DAC_CHANNEL_SELECT_MENU { "Select DAC Channel", 'A', menu_dac_channels }, {""}, #endif { "Write to Input Register (LDAC Dependent)", 'B',menu_write_to_input_register }, {""}, { "Update DAC from Input Register", 'C', menu_update_dac_from_input }, {""}, { "Update DAC by LDAC Assert (H->L)", 'D', menu_update_dac_by_ldac_assert }, {""}, { "Write and Update DAC (Direct Update)", 'E', menu_write_and_update_dac }, {""}, { "Read Back DAC Channel", 'F', menu_dac_readback }, {""}, #ifdef DISPLAY_LDAC_MASK_SELECT_MENU { "Set LDAC# Mask", 'G', menu_ldac_masks }, {""}, #endif { "Select LDAC Pin State", 'H', menu_select_ldac_pin_state }, {""}, { "Select Operating Mode", 'I', menu_dac_operating_modes }, {""}, { "Select Reference Source (Vref)", 'J', menu_vref_sources }, {""}, { "Set Gain", 'K', menu_gain_selection }, {""}, { "Assert Software Reset", 'L', menu_assert_software_reset }, {""}, { "Assert Hardware Reset", 'M', menu_assert_hardware_reset }, {""}, }; console_menu nanodac_main_menu = { .title = "Main Menu", .items = main_menu_items, .itemCount = ARRAY_SIZE(main_menu_items), .headerItem = display_menu_header, .footerItem = display_menu_footer, .enableEscapeKey = false };