Forked repository to push EVAL-AD593x updates
Dependencies: platform_drivers
app/main.cpp
- Committer:
- pmallick
- Date:
- 2021-10-13
- Revision:
- 5:ca8fe90d3ab5
File content as of revision 5:ca8fe90d3ab5:
/*************************************************************************//** * @file main.cpp * @brief Main application code for AD5933 firmware example program * @author ssmith (sean.smith@analog.com) ****************************************************************************** * Copyright (c) 2019-2021 Analog Devices, Inc. * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * - Modified versions of the software must be conspicuously marked as such. * - This software is licensed solely and exclusively for use with * processors/products manufactured by or for Analog Devices, Inc. * - This software may not be combined or merged with other code in any manner * that would cause the software to become subject to terms and * conditions which differ from those listed here. * - Neither the name of Analog Devices, Inc. nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * - The use of this software may or may not infringe the patent rights * of one or more patent holders. This license does not release you from * the requirement that you obtain separate licenses from these patent * holders to use this software. * * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * NON-INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, * INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF * INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * 20180927-7CBSD SLA *****************************************************************************/ #include <mbed.h> #include <ctype.h> #include "i2c.h" #include "i2c_extra.h" #include "error.h" #include "app_config.h" #ifdef __cplusplus extern "C" { #endif // _cplusplus #include "delay.h" #ifdef __cplusplus // Closing extern c } #endif // _cplusplus //Lower this value if storage becomes a problem #define MAX_FREQ_INCREMENTS 511 #define TEMP_LIMIT_MIN -40 #define TEMP_LIMIT_MAX 125 #define MAX_SETTLING_CYCLES 511 static void print_title(void); static void getMenuSelect(uint8_t *menuSelect); static void print_prompt(); static uint8_t read_temperature(); static uint8_t set_system_clock(); static uint8_t set_vrange_and_pga_gain(); static int32_t configure_system(); static uint8_t calculate_gain_factor(); static uint8_t guide(); static uint8_t impedance_sweep(); typedef struct ad5933_config_data { float start_freq; uint8_t pga_gain; float output_voltage_range; int32_t start_frequency; int32_t frequency_increment; int32_t number_increments; int32_t number_settling_cycles; }ad5933_config_data; ad5933_config_data config_data; static double gain_factor = 0; static double temperature; /******************************************************************************/ /************************** Variables Declarations ****************************/ /******************************************************************************/ // Initialize the extra parameters for I2C initialization mbed_i2c_init_param i2c_init_extra_params = { .i2c_sda_pin = I2C_SDA, .i2c_scl_pin = I2C_SCL }; i2c_init_param i2c_params = { .max_speed_hz = 100000, // i2c max speed (hz) .slave_address = AD5933_ADDRESS, // i2c slave address //A0 tied high .extra = &i2c_init_extra_params // i2c extra initialization parameters }; ad5933_init_param init_params = { .i2c_init = i2c_params, // I2C parameters .current_sys_clk = AD5933_INTERNAL_SYS_CLK, //current_sys_clk frequency (16MHz) .current_clock_source = AD5933_CONTROL_INT_SYSCLK, //current_clock_source .current_gain = AD5933_RANGE_1000mVpp, //current_gain .current_range = AD5933_GAIN_X1, //current_range }; ad5933_dev *device; int32_t connected = -1; int main() { uint8_t menu_select = 0; print_title(); connected = ad5933_init(&device, init_params); //Do a quick check to ensure basic connectivity is ok temperature = ad5933_get_temperature(device); if (temperature >= TEMP_LIMIT_MIN && temperature <= TEMP_LIMIT_MAX) { printf("\nTemperature: %f, AD5933 initialisation successful!\n",temperature); } else { printf("AD5933 initialisation reported a bad temperature - recommend debug :\n"); } while (connected == SUCCESS) { print_prompt(); getMenuSelect(&menu_select); config_data.start_freq = 10000; if (menu_select > 12) print_prompt(); else switch (menu_select) { case 0: guide(); mdelay(2000); break; case 1: read_temperature(); break; case 2: configure_system(); break; case 3: calculate_gain_factor(); break; case 4: impedance_sweep(); break; default: printf("Invalid option: Ignored."); break; } mdelay(100); } return 0; } //! Prints the title block void print_title() { printf("*****************************************************************\n"); printf("* AD5933 Demonstration Program *\n"); printf("* *\n"); printf("* This program demonstrates communication with the AD5933 *\n"); printf("* *\n"); printf("* 1 MSPS, 12-Bit Impedance Converter, Network analyser *\n"); printf("* *\n"); printf("* Set the baud rate to 115200 select the newline terminator. *\n"); printf("*****************************************************************\n"); } void print_prompt() { printf("\n\n\rCommand Summary:\n\n"); printf(" 0 -Software Guide\n"); printf(" 1 -Read temperature\n"); printf(" 2 -Configure voltage-range, PGA-Gain and sweep parameters\n"); printf(" 3 -Calculate Gain-Factor\n"); printf(" 4 -Do an impedance sweep\n"); printf("\n\rMake a selection...\n"); } static void getMenuSelect(uint8_t *menuSelect) { scanf("%d", (int *)menuSelect); } static uint8_t read_temperature() { temperature = ad5933_get_temperature(device); printf("Current temperature:%.3f C", temperature); return SUCCESS; } static uint8_t set_system_clock() { printf(" Select Internal (1) or external clock (2): "); int input = 0; scanf("%d", &input); if (isdigit(input) == 0 && (input == 1 || input == 2)) { input == 1 ? printf("\n You selected Internal clock source\n") : printf(" You selected external Source clock source\n"); } else { printf("Invalid entry\n"); mdelay(2000); return FAILURE; } if (input == 2) { printf(" Enter external clock frequency in Hz "); scanf("%d", &input); if (isdigit(input) == 0 && input > 0 && input < 20000000) { printf(" External clk-source frequency set to %d \n", input); } else { printf("Invalid entry\n"); mdelay(2000); return FAILURE; } } ad5933_set_system_clk(device, input == 1 ? AD5933_CONTROL_INT_SYSCLK : AD5933_CONTROL_EXT_SYSCLK, input); return 0; } static uint8_t set_vrange_and_pga_gain() { int input; uint8_t v_range = AD5933_RANGE_1000mVpp; printf(" Select output voltage range:\n"); printf(" 0: 2Vpp typical:\n"); printf(" 1: 200mVpp typical:\n"); printf(" 2: 400mVpp typical:\n"); printf(" 3: 1Vpp typical:\n"); scanf("%d", &input); if (input >= 0 && input < 4) { switch (input) { case AD5933_RANGE_2000mVpp: { printf(" Selected 2V pp typical.\n"); break; } case AD5933_RANGE_200mVpp: { printf(" Selected 200mV pp typical.\n"); break; } case AD5933_RANGE_400mVpp: { printf(" Selected 400mV pp typical.\n"); break; } case AD5933_RANGE_1000mVpp: { printf(" Selected 1V pp typical.\n"); break; } } v_range = input; } else { printf("Invalid entry\n"); mdelay(2000); return FAILURE; } printf("\n Select PGA Gain (0=X5, 1=X1)\n"); scanf("%d", &input); if (input >= 0 && input < 2) { config_data.pga_gain = input; config_data.output_voltage_range = v_range; printf("PGA gain set to : "); input == AD5933_GAIN_X5 ? printf("X5\n\n") : printf("X1\n\n"); ad5933_set_range_and_gain(device, config_data.output_voltage_range, config_data.pga_gain); } else { printf("Invalid entry: write aborted\n"); mdelay(2000); return FAILURE; } return SUCCESS; } static int32_t configure_system() { printf("Configure the impedance meter\n\n"); set_vrange_and_pga_gain(); set_system_clock(); int start_freq; int freq_inc; int num_increments; int num_settling_cycles; int multiplier = AD5933_SETTLING_X1; printf("\n Enter start-frequency as a decimal number: "); if (scanf("%d", &start_freq) == 1) { if (start_freq <= 0) { printf(" Invalid entry, write aborted: \n"); return FAILURE; } } printf("\n Enter frequency-increment as a decimal number: "); scanf("%d", &freq_inc); if (isdigit(freq_inc) != 0 || freq_inc <= 0) { printf(" Invalid entry, write aborted: \n"); return FAILURE; } printf("\n Enter the number of increments as a decimal number: "); printf("\n Number of increments must be less than %d\n", MAX_FREQ_INCREMENTS); scanf("%d", &num_increments); if (isdigit(num_increments) != 0 || num_increments > MAX_FREQ_INCREMENTS) { printf(" Invalid entry, write aborted: \n"); return FAILURE; } printf("Enter the number of settling-time cycles before ADC is triggered.\n"); scanf("%d", &num_settling_cycles); if (num_settling_cycles > MAX_SETTLING_CYCLES) { printf(" Invalid entry, write aborted: \n"); return FAILURE; } printf("Set the settling time multiplier (X1=0, X2=1, X4=2).\n"); scanf("%d", &multiplier); if (multiplier > 2) { printf(" Invalid entry, write aborted: \n"); return FAILURE; } else { //adjust X4 option to match memory map if (multiplier == 2) multiplier = AD5933_SETTLING_X4; } printf("\n Setting start frequency to %d\n\r", (unsigned int)start_freq); printf(" Setting frequency increment to %d\n\r", (unsigned int)freq_inc); printf(" Setting the number of increments to %d\n\r", (unsigned int)num_increments); printf(" Setting the number of settling-cycles to %d\n\r", (unsigned int)num_settling_cycles); printf(" The multiplier for the settling-cycles %d\n\r", (unsigned int)multiplier+1); //update device state config_data.start_freq = start_freq; config_data.frequency_increment = freq_inc; config_data.number_increments = num_increments; config_data.number_settling_cycles = num_settling_cycles; ad5933_set_settling_time(device,multiplier,num_settling_cycles); ad5933_set_range_and_gain(device, device->current_range, device->current_gain); ad5933_config_sweep(device, start_freq, freq_inc, num_increments); return SUCCESS; } static uint8_t calculate_gain_factor() { double calibration_impedance; printf("\n\nCalculate the gain-factor (see datasheet for information)\n"); printf("Calcualted gain-factor will be stored for impedance measurements and\n"); printf("displayed on the terminal screen.\n"); printf("Ensure that the system has been configured before\n"); printf("calculating the gain factor\n"); ad5933_config_sweep(device, config_data.start_freq, config_data.frequency_increment, config_data.number_increments); // Do standby, init-start freq, start the sweep, and wait for valid data ad5933_start_sweep(device); printf("\nEnter calibration resistance in Ohms: "); scanf("%le", &calibration_impedance); printf("Calculating gain factor\n\r"); gain_factor = ad5933_calculate_gain_factor(device, calibration_impedance, AD5933_FUNCTION_REPEAT_FREQ); printf("\n\r Calculated gain factor %e\n\r", gain_factor); return SUCCESS; } static uint8_t guide() { printf("\n\rAD5933-Demo quick-start guide: \n\n"); printf("This program can be used both as a demo of the AD5933 impedance \n"); printf("measurement system and as a starting point for developing a \n"); printf("more advanced program for prototyping. This program is not \n"); printf("provided as production-quality code, but as a helpful starting point.\n\n"); printf("As a quick start, the following steps can be implemented to ensure\n"); printf("firmware is communcating with the board and measurements taking place.\n\n"); printf("Firstly - use menu option 1 to read the on-chip temperature.\n"); printf("If a realistic temperature comes back - you are good to go :)\n\n"); printf("Step 1\tConnect a 200k Resistor across the SMA terminals of the PMOD 1A\n"); printf("Step 2\tSelect the 100k feedback resistor by pulling the SEL pin high\n"); printf("Step 2\tConfigure the impedance system with Menu Option 2\n"); printf("Step 3\tCalculate the gain factor with menu-item 3\n"); printf("Step 3\tReplace the 200k impedance across the SMA terminals with a \n"); printf("different 'unknown' impedance (300K perhaps)\n"); printf("Step 4\tRun the impedance measurement with menu-item 4\n"); printf("\tresults are dispayed on the terminal\n"); return SUCCESS; } static uint8_t impedance_sweep() { printf("\nPerform a sweep to calculate an unknown impedance (see datasheet for information)\n"); printf("System should have been previously configured (Menu Option 2)\n"); printf("Impedance will be caculated and results shown.\n\r"); int32_t status = FAILURE; double impedance; float frequency = config_data.start_freq; ad5933_config_sweep(device, config_data.start_freq, config_data.frequency_increment, config_data.number_increments); /* > program frequency sweep parameters into relevant registerS > place the ad5933 into standby mode. > start frequency register > number of increments register */ ad5933_start_sweep(device); printf("\n FREQUENCY MAGNITUDE PHASE IMPEDANCE\n"); do { //Fill up the results struct with data impedance = ad5933_calculate_impedance(device, gain_factor, AD5933_FUNCTION_INC_FREQ); printf(" %.2f,", frequency); printf(" %.2f\n", impedance); frequency += config_data.frequency_increment; //poll the status register to check if frequency sweep is complete. status = ad5933_get_register_value(device, AD5933_REG_STATUS, 1); } while ((status & AD5933_STAT_SWEEP_DONE) == 0); return status; }