Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: adi_console_menu platform_drivers
ad5592r_console_app.c
00001 /*! 00002 ***************************************************************************** 00003 * @file ad5592r_console_app.c 00004 * @brief AD5592R console application interfaces 00005 * @details This file is specific to ad5592r and ad5593r console menu application handle. 00006 * The functions defined in this file performs the action 00007 * based on user selected console menu. 00008 * 00009 ----------------------------------------------------------------------------- 00010 Copyright (c) 2020-2021 Analog Devices, Inc. 00011 All rights reserved. 00012 00013 This software is proprietary to Analog Devices, Inc. and its licensors. 00014 By using this software you agree to the terms of the associated 00015 Analog Devices Software License Agreement. 00016 *****************************************************************************/ 00017 00018 /******************************************************************************/ 00019 /***************************** Include Files **********************************/ 00020 /******************************************************************************/ 00021 #include <stdio.h> 00022 #include <string.h> 00023 #include <stdbool.h> 00024 00025 #include "app_config.h" 00026 #include "ad5592r_configs.h" 00027 00028 #include "platform_support.h" 00029 #include "error.h" 00030 #include "gpio.h" 00031 #include "i2c.h" 00032 #include "spi.h" 00033 #include "spi_extra.h" 00034 #include "i2c_extra.h" 00035 00036 #include "ad5592r-base.h" 00037 #include "ad5592r.h" 00038 #include "ad5593r.h" 00039 00040 #include "ad5592r_console_app.h" 00041 00042 /******************************************************************************/ 00043 /************************* Macros & Constant Definitions **********************/ 00044 /******************************************************************************/ 00045 // vref_voltage can be defined as EXTERNAL_VREF_VOLTAGE or INTERNAL_VREF_VOLTAGE 00046 // Change EXTERNAL_VREF_VOLTAGE if using supply other than 2.5V 00047 #define EXTERNAL_VREF_VOLTAGE 2.5 00048 float vref_voltage = EXTERNAL_VREF_VOLTAGE; 00049 00050 #define AD5592R_CHANNEL(N) (N) 00051 #define AD5592R_REG_ADC_SEQ_INCL(x) BIT(x) 00052 #define AD5592R_REG_PD_CHANNEL(x) BIT(x) 00053 #define AD5592R_GPIO(x) BIT(x) 00054 00055 #define TEMP_SAMPLE_SIZE 5 00056 #define CLEAR_CHANNEL_SELECTION 1000 00057 #define MDELAY_TO_DISPLAY_INSTRUCTION 1000 00058 #define TEMPERATURE_READBACK_CHANNEL 8 00059 00060 #define MAX_ADC_CODE 4095.0 00061 #define ADC_GAIN_LOW_CONVERSION_VALUE 2.654 00062 #define ADC_GAIN_HIGH_CONVERSION_VALUE 1.327 00063 00064 /* Private Variables */ 00065 static struct ad5592r_dev sAd5592r_dev; 00066 00067 static const char *mode_names[] = { 00068 "Unused", 00069 "ADC\t", 00070 "DAC\t", 00071 "ADC+DAC", 00072 "GPI\t", 00073 "GPO\t", 00074 }; 00075 static const char *offstate_names[] = { 00076 "Pulldown", 00077 "Low\t", 00078 "High\t", 00079 "Tristate" 00080 }; 00081 static bool active_channel_selections[NUM_CHANNELS] = { 00082 false, 00083 false, 00084 false, 00085 false, 00086 false, 00087 false, 00088 false, 00089 false 00090 }; 00091 00092 static uint16_t adc_channels_in_seq = AD5592R_REG_ADC_SEQ_TEMP_READBACK; 00093 00094 /******************************************************************************/ 00095 /***************************** Function Declarations **************************/ 00096 /******************************************************************************/ 00097 static int32_t do_software_reset(uint32_t id); 00098 static int32_t do_read_die_temp(uint32_t id); 00099 static float die_temp_calculation(uint16_t adc_temp_code, bool adc_gain); 00100 static void do_set_channel_modes(void); 00101 static int32_t do_toggle_channel_selection(uint32_t channel); 00102 static int32_t do_mode_selection(uint32_t mode); 00103 static int32_t do_reset_channel_modes(uint32_t id); 00104 static int32_t do_offstate_selection(uint32_t mode); 00105 static int32_t do_channel_7_adc_indicator(uint32_t id); 00106 static int32_t do_general_settings_toggle(uint32_t reg_bit_id); 00107 static int32_t do_write_dac_value(uint32_t id); 00108 static int32_t do_dac_input_reg_to_output(uint32_t id); 00109 static int32_t do_toggle_ldac_mode(uint32_t id); 00110 static int32_t do_toggle_dac_powerdown(uint32_t id); 00111 static int32_t do_toggle_incl_in_seq(uint32_t id); 00112 static int32_t do_read_adc_sequence(uint32_t id); 00113 00114 extern console_menu power_down_pin_select_menu; 00115 extern console_menu config_channels_menu; 00116 extern console_menu general_settings_menu; 00117 extern console_menu dac_menu; 00118 extern console_menu gpio_menu; 00119 extern console_menu adc_menu; 00120 00121 /******************************************************************************/ 00122 /***************************** Function Definitions ***************************/ 00123 /******************************************************************************/ 00124 00125 /*! 00126 * @brief Initialize AD5592/3R. ACTIVE_DEVICE defined in app_config.h 00127 *@details The device initialization varies depending on what ACTIVE_DEVICE is defined. 00128 * Device is reset and default register map values written. 00129 * SPI or I2C initialization occurs. 00130 * @return SUCCESS (0), FAILURE (negative) 00131 */ 00132 int32_t ad5592r_app_initalization(void) 00133 { 00134 memcpy(&sAd5592r_dev, &ad5592r_dev_user, sizeof(ad5592r_dev_user)); 00135 int32_t status; 00136 if (ACTIVE_DEVICE == ID_AD5593R) { 00137 sAd5592r_dev.i2c = &i2c_user_descr; 00138 i2c_init(&sAd5592r_dev.i2c, &i2c_user_params); 00139 status = ad5593r_init(&sAd5592r_dev, &ad5592r_user_param); 00140 } else { 00141 sAd5592r_dev.spi = &spi_user_descr; 00142 spi_init(&sAd5592r_dev.spi, &spi_user_params); 00143 status = ad5592r_init(&sAd5592r_dev, &ad5592r_user_param); 00144 } 00145 return status; 00146 } 00147 00148 /*! 00149 * @brief Performs software reset 00150 * @details Writes to the reset register. Resets sAd5592r_dev configuration using 00151 * configuration from ad5592r_reset_config.c SPI, I2C and ops are stored 00152 * and restored after the reset. 00153 * @return MENU_CONTINUE 00154 */ 00155 static int32_t do_software_reset(uint32_t id) 00156 { 00157 int32_t status; 00158 00159 if ((status = ad5592r_software_reset(&sAd5592r_dev)) == SUCCESS) { 00160 // Save spi_desc field, i2c_desc and device ops settings as it is not reset 00161 spi_desc *spi_interface = sAd5592r_dev.spi; 00162 i2c_desc *i2c_interface = sAd5592r_dev.i2c; 00163 const struct ad5592r_rw_ops *dev_ops = sAd5592r_dev.ops; 00164 // Copy over the reset state of the device 00165 memcpy(&sAd5592r_dev, &ad5592r_dev_reset, sizeof(ad5592r_dev_reset)); 00166 00167 // Restore device ops 00168 sAd5592r_dev.ops = dev_ops; 00169 if (ACTIVE_DEVICE == ID_AD5592R) { 00170 // Restore the spi_desc pointer field 00171 sAd5592r_dev.spi = spi_interface; 00172 printf(EOL " --- AD5592R Software Reset Successful---" EOL); 00173 } else { 00174 // Restore the i2c_desc pointer field 00175 sAd5592r_dev.i2c = i2c_interface; 00176 printf(EOL " --- AD5593R Reset Request Successful---" EOL); 00177 } 00178 } else { 00179 printf(EOL " *** Software Reset Failure: %d ***" EOL, status); 00180 adi_press_any_key_to_continue(); 00181 } 00182 00183 adi_press_any_key_to_continue(); 00184 return (MENU_CONTINUE); 00185 } 00186 00187 /*! 00188 * @brief Prints the temperature of the die 00189 * @details Sets the devices to perform a temperature readback. 00190 * Performs a number of samples based on TEMP_SAMPLE_SIZE 00191 * @return MENU_CONTINUE 00192 */ 00193 static int32_t do_read_die_temp(uint32_t id) 00194 { 00195 uint16_t readback_reg[1] = { 0 }; 00196 int32_t status = 0, ch_state = 0; 00197 float result = 0; 00198 00199 ch_state = sAd5592r_dev.channel_modes[7]; 00200 sAd5592r_dev.channel_modes[7] = CH_MODE_ADC; 00201 do_set_channel_modes(); 00202 00203 do { 00204 00205 for (int8_t i = 0; i < TEMP_SAMPLE_SIZE; i++) { 00206 do { 00207 status = sAd5592r_dev.ops->read_adc(&sAd5592r_dev, 00208 AD5592R_CHANNEL(8), 00209 readback_reg); 00210 } while (0); 00211 if (status != SUCCESS) { 00212 // Break out of for loop if not successful 00213 break; 00214 } 00215 result += die_temp_calculation(readback_reg[0], 00216 (AD5592R_REG_CTRL_ADC_RANGE & sAd5592r_dev.cached_gp_ctrl)); 00217 } 00218 00219 result /= TEMP_SAMPLE_SIZE; 00220 00221 if (status == SUCCESS) { 00222 // Print average of samples 00223 printf(EOL " --- Temperature: %.1f*C --- " EOL, result); 00224 } else { 00225 printf(EOL " *** Error reading die temperature: %d **" EOL, status); 00226 break; 00227 } 00228 } while (0); 00229 00230 sAd5592r_dev.channel_modes[7] = ch_state; 00231 do_set_channel_modes(); 00232 00233 adi_press_any_key_to_continue(); 00234 return (MENU_CONTINUE); 00235 } 00236 00237 /*! 00238 * @brief Calculates the die temperature 00239 * @details Based on conversion equation, die temperature is estimated 00240 * @param adc_temp_code - data read from ADC readback frame 00241 * adc_gain - status of adc_gain 00242 * @return result 00243 */ 00244 static float die_temp_calculation(uint16_t adc_temp_code, bool adc_gain) 00245 { 00246 float result = 0; 00247 00248 // use different equation depending on gain 00249 if(adc_gain) { 00250 result = 25 + ((AD5592R_REG_ADC_SEQ_CODE_MSK(adc_temp_code) - 00251 ((0.5 / (2 * vref_voltage)) * MAX_ADC_CODE)) / 00252 (ADC_GAIN_HIGH_CONVERSION_VALUE * (2.5 / vref_voltage))); 00253 } else { 00254 result = 25 + ((AD5592R_REG_ADC_SEQ_CODE_MSK(adc_temp_code) - 00255 ((0.5 / vref_voltage) * MAX_ADC_CODE)) / 00256 (ADC_GAIN_LOW_CONVERSION_VALUE * (2.5 / vref_voltage))); 00257 } 00258 return result; 00259 } 00260 00261 /*! 00262 * @brief Set channel modes 00263 * 00264 *@details The channels modes are set by passing the altered device 00265 * struct into the ad5592r_set_channel_modes function. There the channels are 00266 * set to desired modes. 00267 */ 00268 static void do_set_channel_modes(void) 00269 { 00270 int32_t status; 00271 if ((status = ad5592r_set_channel_modes(&sAd5592r_dev)) != SUCCESS) { 00272 printf(EOL "Error configuring Channels (%d)" EOL, status); 00273 adi_press_any_key_to_continue(); 00274 } 00275 } 00276 00277 /*! 00278 * @brief Toggle channels currently selected 00279 * @details The channels the user has currently selected are set here. 00280 * These are the channels that will be altered by mode or offstate selection 00281 * @param channel - A channel that the user wants to add to the currently selected channels 00282 * @return (MENU_CONTINUE) 00283 */ 00284 static int32_t do_toggle_channel_selection(uint32_t channel) 00285 { 00286 if (channel == CLEAR_CHANNEL_SELECTION) { 00287 for (uint8_t i = 0; i < sAd5592r_dev.num_channels; i++) { 00288 00289 active_channel_selections[i] = false; 00290 } 00291 } else { 00292 active_channel_selections[channel] = !active_channel_selections[channel]; 00293 } 00294 00295 return (MENU_CONTINUE); 00296 } 00297 00298 /*! 00299 * @brief Mode selection 00300 * @details The mode the users wishes to apply to the currently selected channels 00301 * are selected here. do_set_channel_modes is called which sets the channels 00302 * on the device. 00303 * @param mode -The mode that the user wishes to apply to the selected channels 00304 * @return (MENU_CONTINUE) 00305 */ 00306 static int32_t do_mode_selection(uint32_t mode) 00307 { 00308 for (uint8_t i = 0; i < sAd5592r_dev.num_channels; i++) { 00309 if (active_channel_selections[i] == true) { 00310 sAd5592r_dev.channel_modes[i] = mode; 00311 } 00312 } 00313 do_set_channel_modes(); 00314 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00315 return (MENU_CONTINUE); 00316 } 00317 00318 /*! 00319 * @brief Offstate selection 00320 * @details The offstate the users wishes to apply to the currently selected channels 00321 * are selected here. do_set_channel_modes is called which sets the channels 00322 * on the device. 00323 * @param The offstate that the user wishes to apply to the selected channels 00324 * @return (MENU_CONTINUE) 00325 */ 00326 static int32_t do_offstate_selection(uint32_t mode) 00327 { 00328 for (uint8_t i = 0; i < sAd5592r_dev.num_channels; i++) { 00329 if (active_channel_selections[i] == true) { 00330 sAd5592r_dev.channel_offstate[i] = mode; 00331 } 00332 } 00333 do_set_channel_modes(); 00334 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00335 return (MENU_CONTINUE); 00336 } 00337 00338 /*! 00339 * @brief Reset Channel Modes 00340 * @details This resets all channel modes to unused. 00341 * @return (MENU_CONTINUE) 00342 * 00343 */ 00344 static int32_t do_reset_channel_modes(uint32_t id) 00345 { 00346 ad5592r_reset_channel_modes(&sAd5592r_dev); 00347 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00348 return (MENU_CONTINUE); 00349 } 00350 00351 /*! 00352 * @brief Sets Channel 7 as ADC conversion indicator 00353 * @details Channel 7 is set as a GPIO and the NOT BUSY bit is set in the GPIO 00354 * write configuration register enabling channel 7 to be used as an indicator 00355 * when ADC conversion are occurring. Channel 7 will go LOW when a conversion 00356 * is occurring. 00357 * ***NOTE*** After selecting this Channel 7 will appear as GPO. 00358 * ***NOTE*** Ensure this is the last channel to be configured in order to 00359 * ensure preference will no be overwritten 00360 * @return (MENU_CONTINUE) 00361 */ 00362 static int32_t do_channel_7_adc_indicator(uint32_t id) 00363 { 00364 sAd5592r_dev.channel_modes[AD5592R_CHANNEL(7)] = 00365 ((sAd5592r_dev.channel_modes[AD5592R_CHANNEL(7)] == CH_MODE_UNUSED) 00366 ? CH_MODE_GPO : CH_MODE_UNUSED); 00367 do_set_channel_modes(); 00368 do_general_settings_toggle(((AD5592R_REG_GPIO_OUT_EN << 12) 00369 | AD5592R_REG_GPIO_OUT_EN_ADC_NOT_BUSY)); 00370 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00371 return (MENU_CONTINUE); 00372 } 00373 00374 /*! 00375 * @brief Toggle general setting 00376 * @details Setting (reg_bit) in register (reg) is toggled 00377 * @param reg_bit_id - Combined value containing register address and bit to toggle 00378 * @return (MENU_CONTINUE) 00379 */ 00380 static int32_t do_general_settings_toggle(uint32_t reg_bit_id) 00381 { 00382 uint8_t reg = (reg_bit_id >> 12); 00383 uint16_t reg_bit = (reg_bit_id & 0xFFF), readback_reg; 00384 int32_t status; 00385 00386 if ((status = ad5592r_base_reg_read(&sAd5592r_dev, reg, 00387 &readback_reg)) != SUCCESS) { 00388 printf(" *** Error Reading Setting Status (%x) *** " EOL, reg); 00389 adi_press_any_key_to_continue(); 00390 } else if ((status = ad5592r_base_reg_write(&sAd5592r_dev, reg, 00391 (reg_bit ^ readback_reg))) != SUCCESS) { 00392 printf(" *** Error Toggling Setting (%x) *** " EOL, reg); 00393 adi_press_any_key_to_continue(); 00394 } 00395 00396 if (reg == AD5592R_REG_PD && reg_bit == AD5592R_REG_PD_EN_REF) { 00397 if ((AD5592R_REG_PD_EN_REF & (reg_bit ^ readback_reg))) { 00398 vref_voltage = INTERNAL_VREF_VOLTAGE; 00399 } else { 00400 vref_voltage = EXTERNAL_VREF_VOLTAGE; 00401 } 00402 } 00403 return (MENU_CONTINUE); 00404 } 00405 00406 /*! 00407 * @brief displays the general settings header 00408 */ 00409 static void display_general_setting_header(void) 00410 { 00411 00412 int32_t status = 0; 00413 uint16_t ctrl_reg_data = 0, pd_reg_data = 0; 00414 00415 do { 00416 if ((status = ad5592r_base_reg_read(&sAd5592r_dev, AD5592R_REG_CTRL, 00417 &ctrl_reg_data)) == SUCCESS) { 00418 sAd5592r_dev.cached_gp_ctrl = ctrl_reg_data; 00419 } else { 00420 printf(" *** Error reading register (%x) *** " EOL, AD5592R_REG_CTRL); 00421 adi_press_any_key_to_continue(); 00422 break; 00423 } 00424 00425 if ((status = ad5592r_base_reg_read(&sAd5592r_dev, AD5592R_REG_PD, 00426 &pd_reg_data)) == SUCCESS) { 00427 } else { 00428 printf(" *** Error reading register (%x) *** " EOL, AD5592R_REG_PD); 00429 adi_press_any_key_to_continue(); 00430 break; 00431 } 00432 } while(0); 00433 00434 printf("\tSetting \tEnabled\t\tSetting \tEnabled"EOL); 00435 printf("\tEn Ref\t\t%s\t\tADC Gain\t%s"EOL, 00436 (AD5592R_REG_PD_EN_REF & pd_reg_data)?"X":"\00", 00437 (AD5592R_REG_CTRL_ADC_RANGE & ctrl_reg_data)?"X":"\00"); 00438 printf("\tPC Buff\t\t%s\t\tPD All\t\t%s"EOL, 00439 (AD5592R_REG_CTRL_ADC_PC_BUFF & ctrl_reg_data)?"X":"\00", 00440 (AD5592R_REG_PD_PD_ALL & pd_reg_data) ? "X" : "\00"); 00441 printf("\tBuff\t\t%s\t\tDAC Gain\t%s"EOL, 00442 (AD5592R_REG_CTRL_ADC_BUFF_EN & ctrl_reg_data)?"X":"\00", 00443 (AD5592R_REG_CTRL_DAC_RANGE & ctrl_reg_data)?"X":"\00"); 00444 printf("\tLock Config\t%s\t\tWr All\t\t%s"EOL, 00445 (AD5592R_REG_CTRL_CONFIG_LOCK & ctrl_reg_data)?"X":"\00", 00446 (AD5592R_REG_CTRL_W_ALL_DACS & ctrl_reg_data)?"X":"\00"); 00447 00448 } 00449 00450 /*! 00451 * @brief DAC input register to DAC output 00452 * @details Writes the data from the DAC input register to the DAC output. 00453 * The LDAC mode is returned to write data to the input register only. 00454 * @return (MENU_CONTINUE) 00455 */ 00456 static int32_t do_dac_input_reg_to_output(uint32_t id) 00457 { 00458 int32_t status; 00459 if ((status = ad5592r_base_reg_write(&sAd5592r_dev, AD5592R_REG_LDAC, 00460 AD5592R_REG_LDAC_INPUT_REG_OUT)) != SUCCESS) { 00461 printf("*** Error setting LDAC to write to output (%d) *** ", status); 00462 adi_press_any_key_to_continue(); 00463 } 00464 sAd5592r_dev.ldac_mode = AD5592R_REG_LDAC_INPUT_REG_ONLY; 00465 return (MENU_CONTINUE); 00466 } 00467 00468 /*! 00469 * @brief User dac code 00470 * @details Generate dac code that can be written to device from voltage provided by user 00471 * @param user_voltage - float value provided by user for voltage value to be set 00472 * @return dac code value 00473 */ 00474 static uint16_t user_dac_code(float user_voltage) 00475 { 00476 return (uint16_t) (((user_voltage) * MAX_ADC_CODE) / vref_voltage); 00477 } 00478 00479 /*! 00480 * @brief Code values to voltage 00481 * @details Generate voltage based on code value 00482 * @param code - integer value used to generate voltage value 00483 * @return float voltage value 00484 */ 00485 static float code_to_volts(int16_t code) 00486 { 00487 return ((code / MAX_ADC_CODE) * vref_voltage); 00488 } 00489 00490 /*! 00491 * @brief Write DAC Values 00492 * @details Write value specified by user to Channels selected by user in the DAC menu 00493 * @return (MENU_CONTINUE) 00494 */ 00495 static int32_t do_write_dac_value(uint32_t id) 00496 { 00497 int32_t status; 00498 uint16_t user_code = 0; 00499 float user_voltage = 2.5; 00500 00501 printf(EOL "\tEnter voltage to write to selected DACs (0 - Vref) : " EOL); 00502 user_voltage = adi_get_decimal_float(5); 00503 user_code = user_dac_code(user_voltage); 00504 00505 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00506 if (active_channel_selections[i]) { 00507 if ((status = sAd5592r_dev.ops->write_dac(&sAd5592r_dev, i, 00508 user_code)) != SUCCESS) { 00509 printf("*** Error writing DAC value to channel %d (%d) ***" EOL, i, status); 00510 adi_press_any_key_to_continue(); 00511 } 00512 sAd5592r_dev.cached_dac[i] = user_code; 00513 } 00514 } 00515 return (MENU_CONTINUE); 00516 } 00517 00518 /*! 00519 * @brief Toggle LDAC Modes 00520 * @details Toggles the LDAC mode variable between Immediate write to output 00521 * and write values to input register 00522 * @return (MENU_CONTINUE) 00523 */ 00524 static int32_t do_toggle_ldac_mode(uint32_t id) 00525 { 00526 if (sAd5592r_dev.ldac_mode == AD5592R_REG_LDAC_INPUT_REG_ONLY) { 00527 sAd5592r_dev.ldac_mode = AD5592R_REG_LDAC_IMMEDIATE_OUT; 00528 } else { 00529 sAd5592r_dev.ldac_mode = AD5592R_REG_LDAC_INPUT_REG_ONLY; 00530 } 00531 return (MENU_CONTINUE); 00532 } 00533 00534 /*! 00535 * @brief Toggle DAC channels to power-down 00536 * @details Toggles DAC channels that are powered down based on user selection 00537 * @return (MENU_CONTINUE) 00538 */ 00539 static int32_t do_toggle_dac_powerdown(uint32_t id) 00540 { 00541 int32_t status; 00542 uint16_t powerdown = 0; 00543 00544 if ((status = ad5592r_base_reg_read(&sAd5592r_dev, AD5592R_REG_PD, 00545 &powerdown)) != SUCCESS) { 00546 printf("*** Error Reading Power Down Config (%d)***" EOL, status); 00547 adi_press_any_key_to_continue(); 00548 } 00549 00550 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00551 if (active_channel_selections[i]) { 00552 powerdown ^= AD5592R_REG_PD_CHANNEL(i); 00553 } 00554 } 00555 00556 if ((status = ad5592r_base_reg_write(&sAd5592r_dev, AD5592R_REG_PD, 00557 powerdown)) != SUCCESS) { 00558 printf("*** Error writing Power Down Config (%d)***" EOL, status); 00559 adi_press_any_key_to_continue(); 00560 } 00561 00562 return (MENU_CONTINUE); 00563 } 00564 00565 /*! 00566 * @brief Toggle Channels to include in ADC Sequence 00567 * @details Toggles channels that are included in the ADC conversion sequence 00568 * @return MENU_CONTINUE 00569 */ 00570 static int32_t do_toggle_incl_in_seq(uint32_t id) 00571 { 00572 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00573 if (active_channel_selections[i]) { 00574 adc_channels_in_seq ^= AD5592R_REG_ADC_SEQ_INCL(i); 00575 } 00576 } 00577 return (MENU_CONTINUE); 00578 } 00579 00580 /*! 00581 * @brief Read ADC Sequence 00582 * @details The channels that are included in an ADC conversion sequence are read. 00583 * For the number of channels in the sequence, the data is parsed, converted 00584 * and printed. 00585 * @return SUCCESS OR FAILURE 00586 */ 00587 int32_t do_read_adc_sequence(uint32_t id) 00588 { 00589 int32_t status; 00590 uint16_t adc_seq_data[9] = {0,0,0,0,0,0,0,0,0}, adc_code; 00591 uint8_t chan; 00592 float temperature = 0, voltage = 0; 00593 size_t samples; 00594 00595 samples = hweight8(adc_channels_in_seq); 00596 00597 if ((status = sAd5592r_dev.ops->multi_read_adc(&sAd5592r_dev, 00598 adc_channels_in_seq, adc_seq_data)) != SUCCESS) { 00599 printf("*** Error reading adc_sequencer (%d)***" EOL, status); 00600 adi_press_any_key_to_continue(); 00601 return FAILURE; 00602 } 00603 00604 printf("\tCh \tCode \tVoltage \tTemp" EOL); 00605 00606 for (uint8_t i = 0; i < samples; i++) { 00607 temperature = 0; 00608 00609 adc_code = AD5592R_REG_ADC_SEQ_CODE_MSK(adc_seq_data[i]); 00610 chan = ((adc_seq_data[i] & 0xF000) >> 12); 00611 00612 voltage = code_to_volts(adc_code); 00613 00614 if (chan == TEMPERATURE_READBACK_CHANNEL) { 00615 temperature = die_temp_calculation(adc_code, 00616 (AD5592R_REG_CTRL_ADC_RANGE & 00617 sAd5592r_dev.cached_gp_ctrl)); 00618 // Invalid data on temperature read back frame 00619 voltage = 0; 00620 adc_code = 0; 00621 } 00622 printf("\t%d \t%x \t%.2f \t\t%.1f" EOL, 00623 chan, 00624 adc_code, 00625 voltage, 00626 temperature 00627 ); 00628 } 00629 adi_press_any_key_to_continue(); 00630 return SUCCESS; 00631 } 00632 00633 /*! 00634 * @brief Set GPI 00635 * @details GPIO channels that are selected, with the selection being stored in 00636 * active_channel_selections array are set to GPIO Inputs. The selection is then cleared. 00637 * @return (MENU_CONTINUE) 00638 */ 00639 static int32_t do_set_gpio_input(uint32_t id) 00640 { 00641 int32_t status; 00642 00643 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00644 if (active_channel_selections[i] == true) { 00645 sAd5592r_dev.channel_modes[i] = CH_MODE_GPI; 00646 if ((status = ad5592r_gpio_direction_input 00647 (&sAd5592r_dev, AD5592R_CHANNEL(i) )) != SUCCESS) { 00648 printf(" *** Error Setting GPIO Input on Channel %d (%d) ***" EOL, i, status); 00649 adi_press_any_key_to_continue(); 00650 } 00651 } 00652 } 00653 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00654 return (MENU_CONTINUE); 00655 } 00656 00657 /*! 00658 * @brief Set GPO 00659 * @details GPIO channels that are selected, with the selection being stored in 00660 * active_channel_selections array are set to GPIO Outputs with their 00661 * output set LOW. The selection is then cleared. 00662 * @return (MENU_CONTINUE) 00663 */ 00664 static int32_t do_set_gpio_output(uint32_t value) 00665 { 00666 int32_t status; 00667 00668 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00669 if (active_channel_selections[i] == true) { 00670 sAd5592r_dev.channel_modes[i] = CH_MODE_GPO; 00671 if ((status = ad5592r_gpio_direction_output 00672 (&sAd5592r_dev, AD5592R_CHANNEL(i), GPIO_LOW)) != SUCCESS) { 00673 printf(" *** Error Setting GPIO Output on channel %d (%d) ***" EOL, i,status); 00674 adi_press_any_key_to_continue(); 00675 } 00676 } 00677 } 00678 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00679 return (MENU_CONTINUE); 00680 } 00681 00682 /*! 00683 * @brief Toggle GPO 00684 * @details GPIO channels that are selected, with the selection being stored in 00685 * active_channel_selections array are set to GPIO Outputs with their 00686 * output set toggled HIGH and LOW. The selection is then cleared. 00687 * @return (MENU_CONTINUE) 00688 */ 00689 static int32_t do_toggle_gpio_output(uint32_t id) 00690 { 00691 int32_t status; 00692 00693 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00694 if (active_channel_selections[i] == true) { 00695 if ((status = ad5592r_gpio_set(&sAd5592r_dev, 00696 AD5592R_CHANNEL(i), 00697 !ad5592r_gpio_get(&sAd5592r_dev, AD5592R_CHANNEL(i))) != SUCCESS)) { 00698 printf(" *** Error Toggling GPIO Output on Channel %d (%d) ***", i, status); 00699 adi_press_any_key_to_continue(); 00700 } 00701 } 00702 } 00703 do_toggle_channel_selection(CLEAR_CHANNEL_SELECTION); 00704 return (MENU_CONTINUE); 00705 } 00706 00707 00708 /*! 00709 * @brief calls the general configuration menu 00710 */ 00711 static int32_t menu_general_settings(uint32_t id) 00712 { 00713 return adi_do_console_menu(&general_settings_menu); 00714 } 00715 00716 /*! 00717 * @brief calls the DAC configuration menu 00718 */ 00719 static int32_t menu_dac(uint32_t id) 00720 { 00721 return adi_do_console_menu(&dac_menu); 00722 } 00723 00724 /*! 00725 * @brief calls the channel configuration menu 00726 */ 00727 static int32_t menu_config_channels(uint32_t id) 00728 { 00729 return adi_do_console_menu(&config_channels_menu); 00730 } 00731 00732 /*! 00733 * @brief calls the ADC configuration menu 00734 */ 00735 static int32_t menu_adc(uint32_t id) 00736 { 00737 return adi_do_console_menu(&adc_menu); 00738 } 00739 00740 /*! 00741 * @brief calls the menu to select GPIO pins to toggle 00742 */ 00743 static int32_t menu_gpio(uint32_t id) 00744 { 00745 return adi_do_console_menu(&gpio_menu); 00746 } 00747 00748 /*! 00749 * @brief displays the channel configuration header 00750 */ 00751 static void display_channel_selection_header(void) 00752 { 00753 printf(" Configuration Lock: %s" EOL, 00754 (AD5592R_REG_CTRL_CONFIG_LOCK & sAd5592r_dev.cached_gp_ctrl) 00755 ?"Enabled":"Disabled"); 00756 00757 printf("\tCh\tMode\t\tOffstate\tSelected" EOL); 00758 for (uint8_t i = 0; i < sAd5592r_dev.num_channels; i++) { 00759 printf("\t%d \t%s \t%s \t\t%s" EOL, 00760 i, 00761 mode_names[sAd5592r_dev.channel_modes[i]], 00762 offstate_names[sAd5592r_dev.channel_offstate[i]], 00763 active_channel_selections[i]?"X":"\00" ); 00764 } 00765 } 00766 00767 /*! 00768 * @brief displays the gpio menu header 00769 */ 00770 static void display_gpio_menu_header(void) 00771 { 00772 printf("\tCh\tDir \tValue\tSelected" EOL); 00773 00774 for (uint8_t i = 0; i < sAd5592r_dev.num_channels; i++) { 00775 00776 printf("\t%d \t%s%s \t%s \t%s" EOL, 00777 i, 00778 (sAd5592r_dev.gpio_in & AD5592R_GPIO(i)) ? "In " : "", 00779 (sAd5592r_dev.gpio_out & AD5592R_GPIO(i)) ? "Out " : "", 00780 ad5592r_gpio_get(&sAd5592r_dev, AD5592R_CHANNEL(i)) ? "High" : "Low", 00781 active_channel_selections[i] ? "X" : "\00" 00782 ); 00783 } 00784 } 00785 00786 /*! 00787 * @brief displays the DAC menu header 00788 */ 00789 static void display_dac_menu_header(void) 00790 { 00791 int32_t status; 00792 float voltage; 00793 uint16_t powerdown_read; 00794 char *dac_channel_state = ""; 00795 00796 printf("\tLDAC mode: %s" EOL EOL, 00797 sAd5592r_dev.ldac_mode ? "Write to Input Register": "Immediate Output"); 00798 00799 printf("\tCH \tConfig \tCode \tVoltage \tSelected" EOL); 00800 00801 if ((status = ad5592r_base_reg_read(&sAd5592r_dev, 00802 AD5592R_REG_PD, 00803 &powerdown_read)) != SUCCESS) { 00804 printf("*** Error checking Power Down status (%d) ***" EOL, status); 00805 adi_press_any_key_to_continue(); 00806 } 00807 00808 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00809 voltage = 0; 00810 switch (sAd5592r_dev.channel_modes[i]) { 00811 case CH_MODE_DAC: 00812 case CH_MODE_DAC_AND_ADC: 00813 if (powerdown_read & AD5592R_REG_PD_CHANNEL(i)) { 00814 dac_channel_state = "PD"; 00815 } else { 00816 dac_channel_state = "DAC"; 00817 voltage = code_to_volts(sAd5592r_dev.cached_dac[i]); 00818 } 00819 break; 00820 default: 00821 dac_channel_state = "-"; 00822 // Channel no longer set as DAC - Clear cached value 00823 sAd5592r_dev.cached_dac[i] = 0; 00824 break; 00825 } 00826 00827 printf("\t%d \t%s \t%x \t%.2fV \t\t%s" EOL, 00828 i, 00829 dac_channel_state, 00830 sAd5592r_dev.cached_dac[i], 00831 voltage, 00832 active_channel_selections[i]?"X":"\00"); 00833 } 00834 } 00835 00836 /*! 00837 * @brief displays the Main menu header 00838 */ 00839 static void display_main_menu_header(void) 00840 { 00841 printf("\tCurrent Channel Configuration:" EOL); 00842 printf("\tCH \tMode " EOL); 00843 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00844 printf("\t%d \t%s" EOL, 00845 i, 00846 mode_names[sAd5592r_dev.channel_modes[i]]); 00847 } 00848 } 00849 00850 /*! 00851 * @brief displays the ADC menu header 00852 */ 00853 static void display_adc_menu_header(void) 00854 { 00855 char *adc_channel_state = ""; 00856 00857 printf("\tCh \tMode \tIncl \tSelected" EOL); 00858 00859 for (uint8_t i = 0; i < NUM_CHANNELS; i++) { 00860 switch (sAd5592r_dev.channel_modes[i]) { 00861 case CH_MODE_ADC: 00862 case CH_MODE_DAC_AND_ADC: 00863 adc_channel_state = "ADC"; 00864 00865 break; 00866 default: 00867 adc_channel_state = "-"; 00868 break; 00869 } 00870 00871 printf("\t%d \t%s \t%s \t%s" EOL, 00872 i, 00873 adc_channel_state, 00874 (adc_channels_in_seq & AD5592R_REG_ADC_SEQ_INCL(i)) ?"X":"", 00875 active_channel_selections[i]?"X":"" 00876 ); 00877 } 00878 } 00879 00880 /* 00881 * Definition of the menu of pins to include in adc sequence and menu itself 00882 */ 00883 console_menu_item gpio_menu_items[] = { 00884 { "Select Channel", '\00', NULL }, 00885 { "Channel 0", 'A', do_toggle_channel_selection, AD5592R_CHANNEL(0) }, 00886 { "Channel 1", 'S', do_toggle_channel_selection, AD5592R_CHANNEL(1) }, 00887 { "Channel 2", 'D', do_toggle_channel_selection, AD5592R_CHANNEL(2) }, 00888 { "Channel 3", 'F', do_toggle_channel_selection, AD5592R_CHANNEL(3) }, 00889 { "Channel 4", 'G', do_toggle_channel_selection, AD5592R_CHANNEL(4) }, 00890 { "Channel 5", 'H', do_toggle_channel_selection, AD5592R_CHANNEL(5) }, 00891 { "Channel 6", 'J', do_toggle_channel_selection, AD5592R_CHANNEL(6) }, 00892 { "Channel 7", 'K', do_toggle_channel_selection, AD5592R_CHANNEL(7) }, 00893 { "", '\00', NULL }, 00894 { "Set as GPIO Input", 'Z', do_set_gpio_input }, 00895 { "Set as GPIO Output", 'X', do_set_gpio_output }, 00896 { "Toggle Output Value", 'C', do_toggle_gpio_output}, 00897 }; 00898 00899 console_menu gpio_menu = { 00900 .title = "GPIO Menu" EOL, 00901 .items = gpio_menu_items, 00902 .itemCount = ARRAY_SIZE(gpio_menu_items), 00903 .headerItem = display_gpio_menu_header, 00904 .footerItem = NULL, 00905 .enableEscapeKey = true 00906 }; 00907 00908 /* 00909 * Definition of the ADC config menu and menu itself 00910 */ 00911 console_menu_item adc_menu_items[] = { 00912 { "Select channels:" }, 00913 { "Channel 0", 'A', do_toggle_channel_selection, AD5592R_CHANNEL(0) }, 00914 { "Channel 1", 'S', do_toggle_channel_selection, AD5592R_CHANNEL(1) }, 00915 { "Channel 2", 'D', do_toggle_channel_selection, AD5592R_CHANNEL(2) }, 00916 { "Channel 3", 'F', do_toggle_channel_selection, AD5592R_CHANNEL(3) }, 00917 { "Channel 4", 'G', do_toggle_channel_selection, AD5592R_CHANNEL(4) }, 00918 { "Channel 5", 'H', do_toggle_channel_selection, AD5592R_CHANNEL(5) }, 00919 { "Channel 6", 'J', do_toggle_channel_selection, AD5592R_CHANNEL(6) }, 00920 { "Channel 7", 'K', do_toggle_channel_selection, AD5592R_CHANNEL(7) }, 00921 { "", '\00', NULL }, 00922 { "Toggle Channels in Sequence", 'Q', do_toggle_incl_in_seq }, 00923 { "Read ADC Sequence", 'W', do_read_adc_sequence}, 00924 }; 00925 00926 console_menu adc_menu = { 00927 .title = "ADC Configuration Settings", 00928 .items = adc_menu_items, 00929 .itemCount = ARRAY_SIZE(adc_menu_items), 00930 .headerItem = display_adc_menu_header, 00931 .footerItem = NULL, 00932 .enableEscapeKey = true 00933 }; 00934 00935 00936 /* 00937 * Definition of the DAC menu and menu itself 00938 */ 00939 console_menu_item dac_menu_items[] = { 00940 { "Select Channels:"}, 00941 { "Channel 0", 'A', do_toggle_channel_selection, AD5592R_CHANNEL(0) }, 00942 { "Channel 1", 'S', do_toggle_channel_selection, AD5592R_CHANNEL(1) }, 00943 { "Channel 2", 'D', do_toggle_channel_selection, AD5592R_CHANNEL(2) }, 00944 { "Channel 3", 'F', do_toggle_channel_selection, AD5592R_CHANNEL(3) }, 00945 { "Channel 4", 'G', do_toggle_channel_selection, AD5592R_CHANNEL(4) }, 00946 { "Channel 5", 'H', do_toggle_channel_selection, AD5592R_CHANNEL(5) }, 00947 { "Channel 6", 'J', do_toggle_channel_selection, AD5592R_CHANNEL(6) }, 00948 { "Channel 7", 'K', do_toggle_channel_selection, AD5592R_CHANNEL(7) }, 00949 { "", '\00', NULL }, 00950 { "Write voltage to selected DAC channels", 'Q', do_write_dac_value }, 00951 { "Toggle Power Down selected DAC channels", 'W', do_toggle_dac_powerdown }, 00952 { "Write Input Reg to DAC output", 'E', do_dac_input_reg_to_output }, 00953 { "Toggle LDAC mode", 'R', do_toggle_ldac_mode }, 00954 }; 00955 00956 console_menu dac_menu = { 00957 .title = "DAC Menu", 00958 .items = dac_menu_items, 00959 .itemCount = ARRAY_SIZE(dac_menu_items), 00960 .headerItem = display_dac_menu_header, 00961 .footerItem = NULL, 00962 .enableEscapeKey = true 00963 }; 00964 00965 /* 00966 * Definition of the General Settings menu and menu itself 00967 */ 00968 console_menu_item general_settings_menu_items[] = { 00969 { 00970 "Toggle Internal Voltage Ref (En Ref)", 'A', do_general_settings_toggle, 00971 ((AD5592R_REG_PD << 12) | AD5592R_REG_PD_EN_REF) 00972 }, 00973 { 00974 "Toggle ADC PreCharge Buffer (PC Buff)", 'S', do_general_settings_toggle, 00975 ((AD5592R_REG_CTRL << 12) | AD5592R_REG_CTRL_ADC_PC_BUFF) 00976 }, 00977 { 00978 "Toggle ADC Buffer (Buff)", 'D', do_general_settings_toggle, 00979 ((AD5592R_REG_CTRL << 12) | AD5592R_REG_CTRL_ADC_BUFF_EN) 00980 }, 00981 { 00982 "Toggle Lock Channel Config (Lock Config)", 'F', do_general_settings_toggle, 00983 ((AD5592R_REG_CTRL << 12) | AD5592R_REG_CTRL_CONFIG_LOCK) 00984 }, 00985 { 00986 "Toggle PD All DACs and Internal Ref", 'G', do_general_settings_toggle, 00987 ((AD5592R_REG_PD << 12) | AD5592R_REG_PD_PD_ALL) 00988 }, 00989 { 00990 "Toggle ADC Gain Range (ADC Gain)", 'H', do_general_settings_toggle, 00991 ((AD5592R_REG_CTRL << 12) | AD5592R_REG_CTRL_ADC_RANGE) 00992 }, 00993 { 00994 "Toggle DAC Gain Range (DAC Gain)", 'J', do_general_settings_toggle, 00995 ((AD5592R_REG_CTRL << 12) | AD5592R_REG_CTRL_DAC_RANGE) 00996 }, 00997 { 00998 "Toggle Write All DACS (Wr All)", 'K', do_general_settings_toggle, 00999 ((AD5592R_REG_CTRL << 12) | AD5592R_REG_CTRL_W_ALL_DACS) 01000 }, 01001 }; 01002 01003 console_menu general_settings_menu = { 01004 .title = "General Configuration Settings", 01005 .items = general_settings_menu_items, 01006 .itemCount = ARRAY_SIZE(general_settings_menu_items), 01007 .headerItem = display_general_setting_header, 01008 .footerItem = NULL, 01009 .enableEscapeKey = true 01010 }; 01011 01012 /* 01013 * Definition of the Channel mode selection menu and menu itself 01014 */ 01015 console_menu_item config_channels_menu_items[] = { 01016 { "Select Channels:"}, 01017 { "Channel 0", 'A', do_toggle_channel_selection, AD5592R_CHANNEL(0) }, 01018 { "Channel 1", 'S', do_toggle_channel_selection, AD5592R_CHANNEL(1) }, 01019 { "Channel 2", 'D', do_toggle_channel_selection, AD5592R_CHANNEL(2) }, 01020 { "Channel 3", 'F', do_toggle_channel_selection, AD5592R_CHANNEL(3) }, 01021 { "Channel 4", 'G', do_toggle_channel_selection, AD5592R_CHANNEL(4) }, 01022 { "Channel 5", 'H', do_toggle_channel_selection, AD5592R_CHANNEL(5) }, 01023 { "Channel 6", 'J', do_toggle_channel_selection, AD5592R_CHANNEL(6) }, 01024 { "Channel 7", 'K', do_toggle_channel_selection, AD5592R_CHANNEL(7) }, 01025 { "", '\00', NULL }, 01026 { "DAC", 'Q', do_mode_selection, CH_MODE_DAC }, 01027 { "ADC", 'W', do_mode_selection, CH_MODE_ADC }, 01028 { "ADC + DAC", 'E', do_mode_selection, CH_MODE_DAC_AND_ADC }, 01029 { "GPI", 'R', do_mode_selection, CH_MODE_GPI }, 01030 { "GPO", 'T', do_mode_selection, CH_MODE_GPO }, 01031 { "Unused", 'Y', do_mode_selection, CH_MODE_UNUSED }, 01032 { "Restore Default Modes", 'U', do_reset_channel_modes }, 01033 { "", '\00', NULL }, 01034 { "Pulldown", 'Z', do_offstate_selection, CH_OFFSTATE_PULLDOWN }, 01035 { "Output Low", 'X', do_offstate_selection, CH_OFFSTATE_OUT_LOW }, 01036 { "Output High",'C', do_offstate_selection, CH_OFFSTATE_OUT_HIGH }, 01037 { "Tristate", 'V', do_offstate_selection, CH_OFFSTATE_OUT_TRISTATE }, 01038 { "", '\00', NULL }, 01039 { "Channel 7 as ADC conversion indicator (AD5592R)", 'M', do_channel_7_adc_indicator }, 01040 }; 01041 01042 console_menu config_channels_menu = { 01043 .title = "Configure IO Channels", 01044 .items = config_channels_menu_items, 01045 .itemCount = ARRAY_SIZE(config_channels_menu_items), 01046 .headerItem = display_channel_selection_header, 01047 .footerItem = NULL, 01048 .enableEscapeKey = true 01049 }; 01050 01051 /* 01052 * Definition of the Main Menu Items and menu itself 01053 */ 01054 console_menu_item main_menu_items[] = { 01055 { "Software Reset", 'Q', do_software_reset }, 01056 { "Read ADC die temp", 'W', do_read_die_temp}, 01057 { "", '\00', NULL }, 01058 { "Configure Channels", 'A', menu_config_channels}, 01059 { "General Settings", 'S', menu_general_settings }, 01060 { "DAC Menu", 'D', menu_dac }, 01061 { "ADC Menu", 'F', menu_adc }, 01062 { "GPIO Menu", 'G', menu_gpio}, 01063 }; 01064 01065 console_menu ad5592r_main_menu = { 01066 .title = "AD5592R/AD5593R Main Menu", 01067 .items = main_menu_items, 01068 .itemCount = ARRAY_SIZE(main_menu_items), 01069 .headerItem = display_main_menu_header, 01070 .footerItem = NULL, 01071 .enableEscapeKey = NULL 01072 };
Generated on Wed Jul 13 2022 14:09:19 by
1.7.2