EVAL-AD593x Mbed Project.

Dependencies:   platform_drivers

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

Go to the documentation of this file.
00001 /*************************************************************************//**
00002  *   @file   main.cpp
00003  *   @brief  Main application code for AD5933 firmware example program
00004  *   @author ssmith (sean.smith@analog.com)
00005 ******************************************************************************
00006 * Copyright (c) 2019-2021 Analog Devices, Inc.  
00007 * 
00008 * All rights reserved.
00009 * 
00010 * Redistribution and use in source and binary forms, with or without 
00011 * modification, are permitted provided that the following conditions are met:
00012 *   - Redistributions of source code must retain the above copyright notice, 
00013 *     this list of conditions and the following disclaimer.
00014 *   - Redistributions in binary form must reproduce the above copyright notice, 
00015 *     this list of conditions and the following disclaimer in the documentation 
00016 *     and/or other materials provided with the distribution.  
00017 *   - Modified versions of the software must be conspicuously marked as such.
00018 *   - This software is licensed solely and exclusively for use with 
00019 *     processors/products manufactured by or for Analog Devices, Inc.
00020 *   - This software may not be combined or merged with other code in any manner 
00021 *     that would cause the software to become subject to terms and 
00022 *     conditions which differ from those listed here.
00023 *   - Neither the name of Analog Devices, Inc. nor the names of its 
00024 *     contributors may be used to endorse or promote products derived 
00025 *     from this software without specific prior written permission.
00026 *   - The use of this software may or may not infringe the patent rights 
00027 *     of one or more patent holders. This license does not release you from 
00028 *     the requirement that you obtain separate licenses from these patent 
00029 *     holders to use this software.
00030 * 
00031 * THIS SOFTWARE IS PROVIDED BY ANALOG DEVICES, INC. AND CONTRIBUTORS "AS IS" 
00032 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00033 * NON-INFRINGEMENT, TITLE, MERCHANTABILITY AND FITNESS FOR A 
00034 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANALOG DEVICES, 
00035 * INC. OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00036 * SPECIAL, EXEMPLARY, PUNITIVE OR CONSEQUENTIAL DAMAGES 
00037 * (INCLUDING, BUT NOT LIMITED TO, DAMAGES ARISING OUT OF CLAIMS OF 
00038 * INTELLECTUAL PROPERTY RIGHTS INFRINGEMENT; PROCUREMENT OF SUBSTITUTE 
00039 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00040 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
00041 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00042 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
00043 * POSSIBILITY OF SUCH DAMAGE.
00044 * 
00045 * 20180927-7CBSD SLA
00046 *****************************************************************************/
00047 
00048 #include <mbed.h>
00049 #include <ctype.h>
00050 #include "i2c.h"
00051 #include "i2c_extra.h"
00052 #include "error.h"
00053 #include "app_config.h"
00054 
00055 #ifdef __cplusplus
00056 extern "C"
00057 {
00058 #endif //  _cplusplus 
00059 #include "delay.h"
00060 #ifdef __cplusplus  // Closing extern c
00061 }
00062 #endif //  _cplusplus
00063 
00064 //Lower this value if storage becomes a problem
00065 #define MAX_FREQ_INCREMENTS 511
00066 #define TEMP_LIMIT_MIN -40
00067 #define TEMP_LIMIT_MAX 125 
00068 #define MAX_SETTLING_CYCLES  511
00069 
00070 static void print_title(void);
00071 static void getMenuSelect(uint8_t *menuSelect);
00072 static void print_prompt();
00073 static uint8_t read_temperature();
00074 static uint8_t set_system_clock();
00075 static uint8_t set_vrange_and_pga_gain();
00076 static int32_t configure_system();
00077 static uint8_t calculate_gain_factor();
00078 static uint8_t guide();
00079 static uint8_t impedance_sweep();
00080 
00081 typedef struct ad5933_config_data {
00082     float   start_freq;
00083     uint8_t pga_gain;
00084     float   output_voltage_range;
00085     int32_t start_frequency;
00086     int32_t frequency_increment;
00087     int32_t number_increments;
00088     int32_t number_settling_cycles;
00089 }ad5933_config_data;
00090 
00091 ad5933_config_data config_data;
00092 
00093 static double gain_factor = 0;
00094 static double temperature;
00095 
00096 
00097 /******************************************************************************/
00098 /************************** Variables Declarations ****************************/
00099 /******************************************************************************/
00100 
00101 // Initialize the extra parameters for I2C initialization
00102 mbed_i2c_init_param i2c_init_extra_params = {
00103     .i2c_sda_pin = I2C_SDA,
00104     .i2c_scl_pin = I2C_SCL
00105 };
00106 
00107 i2c_init_param i2c_params =
00108 {
00109     .max_speed_hz = 100000,             // i2c max speed (hz)
00110     .slave_address = AD5933_ADDRESS,    // i2c slave address //A0 tied high
00111     .extra = &i2c_init_extra_params     // i2c extra initialization parameters
00112 };
00113 
00114 
00115 ad5933_init_param init_params = {
00116     .i2c_init = i2c_params,                             // I2C parameters 
00117     .current_sys_clk = AD5933_INTERNAL_SYS_CLK,         //current_sys_clk frequency (16MHz)
00118     .current_clock_source = AD5933_CONTROL_INT_SYSCLK,  //current_clock_source
00119     .current_gain = AD5933_RANGE_1000mVpp,              //current_gain
00120     .current_range = AD5933_GAIN_X1,                    //current_range
00121 };
00122 
00123 ad5933_dev *device;
00124 int32_t connected = -1;
00125 
00126 int main()
00127 {
00128     
00129     uint8_t menu_select = 0;
00130     print_title();
00131     connected = ad5933_init(&device, init_params);
00132 
00133 
00134     //Do a quick check to ensure basic connectivity is ok
00135     temperature  = ad5933_get_temperature(device);
00136     if (temperature >= TEMP_LIMIT_MIN && temperature <= TEMP_LIMIT_MAX) {
00137         printf("\nTemperature: %f, AD5933 initialisation successful!\n",temperature);
00138     }
00139     else {
00140         printf("AD5933 initialisation reported a bad temperature - recommend debug :\n");
00141     }
00142 
00143     while (connected == SUCCESS) {
00144         print_prompt();
00145         getMenuSelect(&menu_select);
00146         config_data.start_freq = 10000;
00147 
00148         if (menu_select > 12)
00149             print_prompt();
00150         else switch (menu_select)
00151             {
00152             case 0: 
00153                 guide();
00154                 mdelay(2000); 
00155                 break;
00156 
00157             case 1:
00158                 read_temperature();
00159                 break;
00160             case 2:
00161                 configure_system();
00162                 break;
00163             case 3:
00164                 calculate_gain_factor();
00165                 break;
00166             case 4:
00167                 impedance_sweep();
00168                 break;
00169 
00170             default:
00171                 printf("Invalid option: Ignored.");
00172                 break;
00173             }
00174 
00175             mdelay(100);
00176         }
00177 
00178         return 0;
00179 }
00180 
00181 //! Prints the title block
00182 void print_title()
00183 {
00184     printf("*****************************************************************\n");
00185     printf("* AD5933 Demonstration Program                                  *\n");
00186     printf("*                                                               *\n");
00187     printf("* This program demonstrates communication with the AD5933       *\n");
00188     printf("*                                                               *\n");
00189     printf("* 1 MSPS, 12-Bit Impedance Converter, Network analyser          *\n");
00190     printf("*                                                               *\n");
00191     printf("* Set the baud rate to 115200 select the newline terminator.    *\n");
00192     printf("*****************************************************************\n");
00193 }
00194 
00195 void print_prompt()
00196 {
00197     printf("\n\n\rCommand Summary:\n\n");
00198     printf("  0  -Software Guide\n");
00199     printf("  1  -Read temperature\n");
00200     printf("  2  -Configure voltage-range, PGA-Gain and sweep parameters\n");
00201     printf("  3  -Calculate Gain-Factor\n");
00202     printf("  4  -Do an impedance sweep\n");
00203     printf("\n\rMake a selection...\n");
00204 
00205 }
00206 
00207 
00208 static void getMenuSelect(uint8_t *menuSelect) {
00209     scanf("%d", (int *)menuSelect);
00210 }
00211 
00212 static uint8_t read_temperature()
00213 {
00214     temperature = ad5933_get_temperature(device);
00215 
00216     printf("Current temperature:%.3f C", temperature);
00217     return SUCCESS;
00218 }
00219 
00220 static uint8_t set_system_clock()
00221 {
00222     printf("  Select Internal (1) or external clock (2): ");
00223 
00224     int input = 0;
00225     scanf("%d", &input);
00226     if (isdigit(input) == 0 && (input == 1 || input == 2))
00227     {
00228         input == 1 ? printf("\n  You selected Internal clock source\n") :
00229             printf("  You selected external Source clock source\n");
00230     }
00231     else
00232     {
00233         printf("Invalid entry\n");
00234         mdelay(2000);
00235         return FAILURE;
00236     }
00237 
00238     if (input == 2)
00239     {
00240         
00241         printf("  Enter external clock frequency in Hz ");
00242         scanf("%d", &input);
00243         if (isdigit(input) == 0  && input > 0 && input < 20000000)
00244         {
00245             printf("  External clk-source frequency set to %d \n", input);
00246         }
00247         else
00248         {
00249             printf("Invalid entry\n");
00250             mdelay(2000);
00251             return FAILURE;
00252         }
00253     }
00254 
00255     ad5933_set_system_clk(device,
00256         input == 1 ? AD5933_CONTROL_INT_SYSCLK : 
00257                                     AD5933_CONTROL_EXT_SYSCLK,
00258         input);
00259 
00260     return 0;
00261 }
00262 
00263 static uint8_t set_vrange_and_pga_gain()
00264 {
00265     int input;
00266     uint8_t v_range = AD5933_RANGE_1000mVpp;
00267 
00268     printf("  Select output voltage range:\n");
00269     printf("    0: 2Vpp typical:\n");
00270     printf("    1: 200mVpp typical:\n");
00271     printf("    2: 400mVpp typical:\n");
00272     printf("    3: 1Vpp typical:\n");
00273 
00274 
00275     scanf("%d", &input);
00276     if (input >= 0 && input < 4)
00277     {
00278         switch (input)
00279         {
00280         case AD5933_RANGE_2000mVpp: { 
00281                 printf("  Selected 2V pp typical.\n");
00282                 break;
00283             }
00284         case AD5933_RANGE_200mVpp: { 
00285                 printf("  Selected 200mV pp typical.\n");
00286                 break;
00287             }
00288         case AD5933_RANGE_400mVpp: { 
00289                 printf("  Selected 400mV pp typical.\n");
00290                 break;
00291             }
00292         case AD5933_RANGE_1000mVpp: { 
00293                 printf("  Selected 1V pp typical.\n");
00294                 break;
00295             }
00296         }
00297         v_range = input;
00298     }
00299     else
00300     {
00301         printf("Invalid entry\n");
00302         mdelay(2000);
00303         return FAILURE;
00304     }
00305 
00306     printf("\n  Select PGA Gain (0=X5, 1=X1)\n");
00307     scanf("%d", &input);
00308     if (input >= 0 && input < 2)
00309     {
00310         config_data.pga_gain = input;
00311         config_data.output_voltage_range = v_range;
00312 
00313         printf("PGA gain set to : ");
00314         input == AD5933_GAIN_X5 ? printf("X5\n\n") : printf("X1\n\n");
00315         ad5933_set_range_and_gain(device, 
00316             config_data.output_voltage_range,
00317             config_data.pga_gain);
00318     }
00319     else
00320     {
00321         printf("Invalid entry: write aborted\n");
00322         mdelay(2000);
00323         return FAILURE;
00324     }
00325         
00326 
00327     return SUCCESS;
00328 }
00329 
00330 static int32_t configure_system()
00331 {
00332 
00333     printf("Configure the impedance meter\n\n");
00334     set_vrange_and_pga_gain();
00335     set_system_clock();
00336 
00337     int start_freq;
00338     int freq_inc;
00339     int num_increments;
00340     int num_settling_cycles;
00341     int multiplier = AD5933_SETTLING_X1;
00342 
00343     printf("\n  Enter start-frequency as a decimal number: ");
00344     if (scanf("%d", &start_freq) == 1)
00345     {
00346         if (start_freq <= 0)
00347         {
00348             printf("  Invalid entry, write aborted: \n");
00349             return FAILURE;
00350         }
00351     }
00352 
00353 
00354     printf("\n  Enter frequency-increment as a decimal number: ");
00355     scanf("%d", &freq_inc);
00356     if (isdigit(freq_inc) != 0  || freq_inc <= 0)
00357     {
00358         printf("  Invalid entry, write aborted: \n");
00359         return FAILURE;
00360     }
00361 
00362     printf("\n  Enter the number of increments as a decimal number: ");
00363     printf("\n  Number of increments must be less than %d\n", MAX_FREQ_INCREMENTS);
00364     scanf("%d", &num_increments);
00365     if (isdigit(num_increments) != 0  || num_increments > MAX_FREQ_INCREMENTS)
00366     {
00367         printf("  Invalid entry, write aborted: \n");
00368         return FAILURE;
00369     }
00370 
00371     printf("Enter the number of settling-time cycles before ADC is triggered.\n");
00372     scanf("%d", &num_settling_cycles);
00373     if (num_settling_cycles > MAX_SETTLING_CYCLES)
00374     {
00375         printf("  Invalid entry, write aborted: \n");
00376         return FAILURE;
00377     }
00378 
00379     printf("Set the settling time multiplier (X1=0, X2=1, X4=2).\n");
00380     scanf("%d", &multiplier);
00381     if (multiplier > 2)
00382     {
00383         printf("  Invalid entry, write aborted: \n");
00384         return FAILURE;
00385     }
00386     else
00387     {   //adjust X4 option to match memory map
00388         if (multiplier == 2) 
00389             multiplier = AD5933_SETTLING_X4;
00390     }
00391 
00392     printf("\n    Setting start frequency to %d\n\r", (unsigned int)start_freq);
00393     printf("    Setting frequency increment to %d\n\r", (unsigned int)freq_inc);
00394     printf("    Setting the number of increments to %d\n\r", (unsigned int)num_increments);
00395     printf("    Setting the number of settling-cycles to %d\n\r", (unsigned int)num_settling_cycles);
00396     printf("    The multiplier for the settling-cycles %d\n\r", (unsigned int)multiplier+1);
00397 
00398     //update device state
00399     config_data.start_freq = start_freq;
00400     config_data.frequency_increment = freq_inc;
00401     config_data.number_increments = num_increments;
00402     config_data.number_settling_cycles = num_settling_cycles;
00403 
00404     ad5933_set_settling_time(device,multiplier,num_settling_cycles);
00405     ad5933_set_range_and_gain(device, device->current_range, device->current_gain);
00406     ad5933_config_sweep(device, start_freq, freq_inc, num_increments);
00407 
00408     return SUCCESS;
00409 
00410 }
00411 
00412 static uint8_t calculate_gain_factor()
00413 {
00414 
00415     double calibration_impedance;
00416 
00417     printf("\n\nCalculate the gain-factor (see datasheet for information)\n");
00418     printf("Calcualted gain-factor will be stored for impedance measurements and\n");
00419     printf("displayed on the terminal screen.\n");
00420     printf("Ensure that the system has been configured before\n");
00421     printf("calculating the gain factor\n");
00422               
00423     ad5933_config_sweep(device,
00424         config_data.start_freq, 
00425         config_data.frequency_increment,
00426         config_data.number_increments);
00427 
00428     // Do standby, init-start freq, start the sweep, and wait for valid data
00429     ad5933_start_sweep(device);
00430    
00431     printf("\nEnter calibration resistance in Ohms: ");
00432     scanf("%le", &calibration_impedance);
00433 
00434 
00435     printf("Calculating gain factor\n\r");
00436 
00437     gain_factor = ad5933_calculate_gain_factor(device,
00438         calibration_impedance,
00439         AD5933_FUNCTION_REPEAT_FREQ);
00440     printf("\n\r    Calculated gain factor %e\n\r", gain_factor);
00441     
00442     
00443     return SUCCESS;
00444 }   
00445 
00446 
00447 
00448 
00449 static uint8_t guide()
00450 {
00451 
00452     printf("\n\rAD5933-Demo quick-start guide: \n\n");
00453     printf("This program can be used both as a demo of the AD5933 impedance \n");
00454     printf("measurement system and as a starting point for developing a \n");
00455     printf("more advanced program for prototyping. This program is not \n");
00456     printf("provided as production-quality code, but as a helpful starting point.\n\n");
00457 
00458     printf("As a quick start, the following steps can be implemented to ensure\n");
00459     printf("firmware is communcating with the board and measurements taking place.\n\n");
00460     
00461     printf("Firstly - use menu option 1 to read the on-chip temperature.\n");
00462     printf("If a realistic temperature comes back - you are good to go :)\n\n");
00463     
00464     printf("Step 1\tConnect a 200k Resistor across the SMA terminals of the PMOD 1A\n");
00465     printf("Step 2\tSelect the 100k feedback resistor by pulling the SEL pin high\n");
00466     printf("Step 2\tConfigure the impedance system with Menu Option 2\n");
00467     printf("Step 3\tCalculate the gain factor with menu-item 3\n");
00468     printf("Step 3\tReplace the 200k impedance across the SMA terminals with a \n");
00469     printf("different 'unknown' impedance (300K perhaps)\n");
00470     printf("Step 4\tRun the impedance measurement with menu-item 4\n");
00471     printf("\tresults are dispayed on the terminal\n");
00472     
00473     return SUCCESS;
00474 }
00475 
00476 
00477 
00478 static uint8_t impedance_sweep() 
00479 {
00480     printf("\nPerform a sweep to calculate an unknown impedance (see datasheet for information)\n");
00481     printf("System should have been previously configured (Menu Option 2)\n");
00482     printf("Impedance will be caculated and results shown.\n\r");
00483 
00484     int32_t status = FAILURE;
00485     double impedance;
00486     float frequency = config_data.start_freq;
00487 
00488     
00489     ad5933_config_sweep(device,
00490         config_data.start_freq, 
00491         config_data.frequency_increment,
00492         config_data.number_increments);
00493 
00494     /*
00495         > program frequency sweep parameters into relevant registerS
00496         > place the ad5933 into standby mode.
00497         > start frequency register
00498         > number of increments register
00499     */
00500     ad5933_start_sweep(device);
00501     printf("\n  FREQUENCY MAGNITUDE   PHASE IMPEDANCE\n");
00502 
00503     do {
00504 
00505         //Fill up the results struct with data
00506         impedance = ad5933_calculate_impedance(device,
00507             gain_factor,
00508             AD5933_FUNCTION_INC_FREQ);
00509 
00510         printf("  %.2f,", frequency);
00511         printf("  %.2f\n", impedance);
00512             
00513         frequency += config_data.frequency_increment;
00514 
00515         //poll the status register to check if frequency sweep is complete.
00516         status = ad5933_get_register_value(device, AD5933_REG_STATUS, 1);
00517         
00518     } while ((status & AD5933_STAT_SWEEP_DONE) == 0);
00519 
00520     return status;
00521 }
00522 
00523 
00524 
00525