Initial Commit
Dependencies: platform_drivers
Diff: main.cpp
- Revision:
- 1:bd8aea0d51e0
- Parent:
- 0:86671e9c8db0
--- a/main.cpp Tue Sep 03 17:00:18 2019 +0000 +++ b/main.cpp Mon Sep 16 14:08:37 2019 +0000 @@ -1,158 +1,526 @@ -/* Copyright (c) 2019 Analog Devices, Inc. All rights reserved. +/*************************************************************************//** + * @file main.cpp + * @brief Main application code for AD5686 firmware example program + * @author ssmith (sean.smith@analog.com) +****************************************************************************** +* Copyright (c) 2019 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 +*****************************************************************************/ -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 ma y 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. +#include <mbed.h> +#include <ctype.h> +#include "app_config.h" + +#define NOT_USED 0 +//Lower this value if storage becomes a problem +#define MAX_FREQ_INCREMENTS 511 +#define TEMP_LIMIT_MIN -40 +#define TEMP_LIMIT_MAX 125 + -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. +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(); -2019-01-10-7CBSD SLA +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 ****************************/ +/******************************************************************************/ -/***Libraries***/ -#include <stdio.h> /*Standard Library*/ -#include "mbed.h" /*mbed header file*/ -#include "AD593x.h" - -/***Defines for UART Protocol***/ -#define BAUD_RATE 115200 /*Baud Rate*/ +/** + The following definitions are a requirement for the platform_driver + Pin are changed if required in the app_config.h file + ***/ +mbed::SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS); +mbed::I2C i2c(I2C_SDA, I2C_SCL); +PinName slave_selects[MAX_SLAVE_SELECTS]; -/*Configure and instantiate UART protocol - and baud rate*/ -Serial port(USBTX, USBRX, BAUD_RATE); +i2c_init_param i2c_params = +{ + GENERIC_I2C, // i2c type + 0, // i2c id + 100000, // i2c max speed (hz) + AD5933_ADDRESS << 1, // i2c slave address //A0 tied high +}; -AD1234 device(D10); -// If you have a second device on board, define it as a new device. For e.g. AD1234 device2(D9); -/***Function Declarations***/ -static void setup_devices(void); -static void print_title(void); -static void print_prompt(void); -static void menu_1_function1(void); -static void menu_2_function2(void); -static void menu_3_function3(void); +ad5933_init_param init_params = { + i2c_params, // I2C parameters + AD5933_INTERNAL_SYS_CLK, //current_sys_clk frequency (16MHz) + AD5933_CONTROL_INT_SYSCLK, //current_clock_source + AD5933_RANGE_1000mVpp, //current_gain + AD5933_GAIN_X1, //current_range + AD5933_15_CYCLES, //current_settling +}; + +ad5933_dev *device; +int32_t connected = -1; +Serial pc(USBTX, USBRX, 115200); + int main() { - uint8_t user_command; /*User input variable*/ - uint8_t connected = 1; /*Initialize SPI*/ + uint8_t menu_select = 0; + print_title(); + connected = ad5933_init(&device, init_params); - print_title(); - while(connected == 1) { - print_prompt(); - port.scanf("%2d", (int *) &user_command); - port.printf("%2d\n", user_command); - switch (user_command) { - case 1: - menu_1_function1(); - break; + //Do a quick check to ensure basic connectivity is ok + temperature = ad5933_get_temperature(device); + if (temperature >= TEMP_LIMIT_MIN && temperature <= TEMP_LIMIT_MAX) { + pc.printf("\nTemperature: %f, AD5933 initialisation successful!\n",temperature); + } + else { + pc.printf("AD5933 initialisation reported a bad temperature - recommend debug :\n"); + } + + while (connected == SUCCESS) { + print_prompt(); + getMenuSelect(&menu_select); + config_data.start_freq = 10000; - case 2: - menu_2_function2(); - break; - - case 3: - menu_3_function3(); - break; + if (menu_select > 12) + print_prompt(); + else switch (menu_select) + { + case 0: + guide(); + wait(2); + break; - default: - port.printf(" ***Invalid Entry****\n\n"); - break; + case 1: + read_temperature(); + break; + case 2: + configure_system(); + break; + case 3: + calculate_gain_factor(); + break; + case 4: + impedance_sweep(); + break; - } - } - return 0; + default: + pc.printf("Invalid option: Ignored."); + break; + } + + wait(0.1); + } + + return 0; } -/***Function Definitions***/ - +//! Prints the title block +void print_title() +{ + pc.printf("*****************************************************************\n"); + pc.printf("* AD5933 Demonstration Program -- (mbed 1.0) *\n"); + pc.printf("* *\n"); + pc.printf("* This program demonstrates communication with the AD5933 *\n"); + pc.printf("* *\n"); + pc.printf("* 1 MSPS, 12-Bit Impedance Converter, Network analyser *\n"); + pc.printf("* *\n"); + pc.printf("* Set the baud rate to 115200 select the newline terminator. *\n"); + pc.printf("*****************************************************************\n"); +} -static void setup_devices(void) +void print_prompt() { - device.frequency(1000000); - //device2.frequency(2000000); + pc.printf("\n\n\rCommand Summary:\n\n"); + pc.printf(" 0 -Software Guide\n"); + pc.printf(" 1 -Read temperature\n"); + pc.printf(" 2 -Configure voltage-range, PGA-Gain and sweep parameters\n"); + pc.printf(" 3 -Calculate Gain-Factor\n"); + pc.printf(" 4 -Do an impedance sweep\n"); + pc.printf("\n\rMake a selection...\n"); + } -/*Function to print the title block when program first starts - Parameters: None - Return Value: None*/ -void print_title() +static void getMenuSelect(uint8_t *menuSelect) { + pc.scanf("%d", (int *)menuSelect); +} + +static uint8_t read_temperature() +{ + temperature = ad5933_get_temperature(device); + + pc.printf("Current temperature:%.3f C", temperature); + return SUCCESS; +} + +static uint8_t set_system_clock() +{ + pc.printf(" Select Internal (1) or external clock (2): "); + + int input = 0; + pc.scanf("%d", &input); + if (isdigit(input) == 0 && (input == 1 || input == 2)) + { + input == 1 ? pc.printf("\n You selected Internal clock source\n") : + pc.printf(" You selected external Source clock source\n"); + } + else + { + pc.printf("Invalid entry\n"); + wait(2); + return FAILURE; + } + + if (input == 2) + { + + pc.printf(" Enter external clock frequency in Hz "); + pc.scanf("%d", &input); + if (isdigit(input) == 0 && input > 0 && input < 20000000) + { + pc.printf(" External clk-source frequency set to %d \n", input); + } + else + { + pc.printf("Invalid entry\n"); + wait(2); + 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() { - port.printf("\n*****************************************************************\n"); - port.printf("* EVAL-AD1234 Demonstration Program *\n"); - port.printf("* *\n"); - port.printf("* This program demonstrates how to measure strain gauge or *\n"); - port.printf("* other form of a Wheatstone bridge sensors with the AD1234 *\n"); - port.printf("* *\n"); - port.printf("* *\n"); - port.printf("* Set the baud rate to 115200 and select the newline terminator.*\n"); - port.printf("* *\n"); - port.printf("*****************************************************************\n"); + int input; + uint8_t v_range = AD5933_RANGE_1000mVpp; + + pc.printf(" Select output voltage range:\n"); + pc.printf(" 0: 2Vpp typical:\n"); + pc.printf(" 1: 200mVpp typical:\n"); + pc.printf(" 2: 400mVpp typical:\n"); + pc.printf(" 3: 1Vpp typical:\n"); + + + pc.scanf("%d", &input); + if (input >= 0 && input < 4) + { + switch (input) + { + case AD5933_RANGE_2000mVpp: { + pc.printf(" Selected 2V pp typical.\n"); + break; + } + case AD5933_RANGE_200mVpp: { + pc.printf(" Selected 200mV pp typical.\n"); + break; + } + case AD5933_RANGE_400mVpp: { + pc.printf(" Selected 400mV pp typical.\n"); + break; + } + case AD5933_RANGE_1000mVpp: { + pc.printf(" Selected 1V pp typical.\n"); + break; + } + } + v_range = input; + } + else + { + pc.printf("Invalid entry\n"); + wait(2); + return FAILURE; + } + + pc.printf("\n Select PGA Gain (0=X5, 1=X1)\n"); + pc.scanf("%d", &input); + if (input >= 0 && input < 2) + { + config_data.pga_gain = input; + config_data.output_voltage_range = v_range; + + pc.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 + { + pc.printf("Invalid entry: write aborted\n"); + wait(2); + return FAILURE; + } + + + return SUCCESS; } -/*Function to print command summary - Parameters: None - Return Value: None */ -void print_prompt() { - port.printf("\nCommand Summary\n"); - port.printf(" 1 - CS high\n"); - port.printf(" 2 - CS low\n"); - port.printf(" 3 - Spi transaction\n"); - port.printf(" x - Put More Menu Items Here\n"); - port.printf("Select an option: "); +static int32_t configure_system() +{ + + pc.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; + + pc.printf("\n Enter start-frequency as a decimal number: "); + if (pc.scanf("%d", &start_freq) == 1) + { + if (start_freq <= 0) + { + pc.printf(" Invalid entry, write aborted: \n"); + return FAILURE; + } + } + + + pc.printf("\n Enter frequency-increment as a decimal number: "); + pc.scanf("%d", &freq_inc); + if (isdigit(freq_inc) != 0 || freq_inc <= 0) + { + pc.printf(" Invalid entry, write aborted: \n"); + return FAILURE; + } + + pc.printf("\n Enter the number of increments as a decimal number: "); + pc.printf("\n Number of increments must be less than %d\n", MAX_FREQ_INCREMENTS); + pc.scanf("%d", &num_increments); + if (isdigit(num_increments) != 0 || num_increments > MAX_FREQ_INCREMENTS) + { + pc.printf(" Invalid entry, write aborted: \n"); + return FAILURE; + } + + pc.printf("Enter the number of settling-time cycles before ADC is triggered.\n"); + pc.scanf("%d", &num_settling_cycles); + if (num_settling_cycles > AD5933_MAX_SETTLING_CYCLES ) + { + pc.printf(" Invalid entry, write aborted: \n"); + return FAILURE; + } + + pc.printf("Set the settling time multiplier (X1=0, X2=1, X4=2).\n"); + pc.scanf("%d", &multiplier); + if (multiplier > 2) + { + pc.printf(" Invalid entry, write aborted: \n"); + return FAILURE; + } + else + { //adjust X4 option to match memory map + if (multiplier == 2) + multiplier = AD5933_SETTLING_X4; + } + + pc.printf("\n Setting start frequency to %d\n\r", (unsigned int)start_freq); + pc.printf(" Setting frequency increment to %d\n\r", (unsigned int)freq_inc); + pc.printf(" Setting the number of increments to %d\n\r", (unsigned int)num_increments); + pc.printf(" Setting the number of settling-cycles to %d\n\r", (unsigned int)num_settling_cycles); + pc.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; + + pc.printf("\n\nCalculate the gain-factor (see datasheet for information)\n"); + pc.printf("Calcualted gain-factor will be stored for impedance measurements and\n"); + pc.printf("displayed on the terminal screen.\n"); + pc.printf("Ensure that the system has been configured before\n"); + pc.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); + + pc.printf("\nEnter calibration resistance in Ohms: "); + pc.scanf("%le", &calibration_impedance); + + + pc.printf("Calculating gain factor\n\r"); + + gain_factor = ad5933_calculate_gain_factor(device, + calibration_impedance, + AD5933_FUNCTION_REPEAT_FREQ); + pc.printf("\n\r Calculated gain factor %e\n\r", gain_factor); + + + return SUCCESS; +} + + + + +static uint8_t guide() +{ + + pc.printf("\n\rAD5933-Demo quick-start guide: \n\n"); + pc.printf("This program can be used both as a demo of the AD5933 impedance \n"); + pc.printf("measurement system and as a starting point for developing a \n"); + pc.printf("more advanced program for prototyping. This program is not \n"); + pc.printf("provided as production-quality code, but as a helpful starting point.\n\n"); + + pc.printf("As a quick start, the following steps can be implemented to ensure\n"); + pc.printf("firmware is communcating with the board and measurements taking place.\n\n"); + + pc.printf("Firstly - use menu option 1 to read the on-chip temperature.\n"); + pc.printf("If a realistic temperature comes back - you are good to go :)\n\n"); + + pc.printf("Step 1\tConnect a 200k Resistor across the SMA terminals of the PMOD 1A\n"); + pc.printf("Step 2\tSelect the 100k feedback resistor by pulling the SEL pin high\n"); + pc.printf("Step 2\tConfigure the impedance system with Menu Option 2\n"); + pc.printf("Step 3\tCalculate the gain factor with menu-item 3\n"); + pc.printf("Step 3\tReplace the 200k impedance across the SMA terminals with a \n"); + pc.printf("different 'unknown' impedance (300K perhaps)\n"); + pc.printf("Step 4\tRun the impedance measurement with menu-item 4\n"); + pc.printf("\tresults are dispayed on the terminal\n"); + + return SUCCESS; } -/*Function to - Parameters: None - Return Value: None */ -void menu_1_function1() -{ - device.AD1234_function1(); - port.printf("In function 1\n"); + +static uint8_t impedance_sweep() { + + ad5933_result results; + + pc.printf("\nPerform a sweep to calculate an unknown impedance (see datasheet for information)\n"); + pc.printf("System should have been previously configured (Menu Option 2)\n"); + pc.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); + pc.printf("\n FREQUENCY MAGNITUDE PHASE IMPEDANCE\n"); + + do { + + //Fill up the results struct with data + results = ad5933_calculate_impedance(device, + gain_factor, + AD5933_FUNCTION_INC_FREQ); + + impedance = 1 / (results.magnitude * gain_factor); + + pc.printf(" %.2f,", frequency); + pc.printf(" %.2f", results.magnitude); + pc.printf(" %.2f", results.phase); + pc.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; } -/*Function to - Parameters: None - Return Value: None */ -void menu_2_function2() -{ - device.AD1234_function2(); - port.printf("In function 2\n"); -} -void menu_3_function3() -{ - device.write_16b_spi(0x5050); - port.printf("In function 3\n"); -} \ No newline at end of file + +