Eval-TempSense-ARDZ application code
Dependencies: platform_drivers ADT73xx-ADT74xx
main.cpp
- Committer:
- EndaKilgarriff
- Date:
- 2019-08-28
- Revision:
- 1:af9efbb9e9c5
- Parent:
- 0:782471fb58f7
File content as of revision 1:af9efbb9e9c5:
/*************************************************************************//** * @file main.cpp * @brief Main application code for EVAL-TempSense-ARDZ mbed 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 *****************************************************************************/ #include <cstdio> #include <mbed.h> #include "app_config.h" #include <cmath> #define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt))) #define TEMP_MIN -40 #define TEMP_MAX 150 #define MAX_HYST_TEMP 15 #define MIN_HYST_TEMP 0 #define RESET_DELAY 500 #define WAIT_MENU_TIME 1 #define NOT_USED 0 static void print_title(void); static void print_prompt(void); static uint8_t select_device(); static void print_active_device(int ext_int_value); static int get_menu_select(uint8_t *menu_select); static uint8_t read_temperature(); static uint8_t set_resolution(); static uint8_t set_op_mode(); static uint8_t bunch_of_temps(); static uint8_t readback_reg(); static uint8_t reset_interface(); static uint8_t write_to_setpoint_reg(); static uint8_t set_fault_queue(); static uint8_t set_ct_int_config(); static void microcontroller_reset(); static int input_check(int input_val, int lowest_accepted_val, int highest_accepted_val, int invalid_check); #ifdef __cplusplus extern "C" { #endif #include "adt7420.h" #ifdef __cplusplus } #endif // __cplusplus /******************************************************************************/ /************************** Variables Declarations ****************************/ /******************************************************************************/ /** The following definitions are a requirement for the platform_driver Pin are changed if required in the app_config.h file ***/ PinName slave_selects[MAX_SLAVE_SELECTS] = { SPI_CS, SPI_CSE }; mbed::SPI spi(SPI_MOSI, SPI_MISO, SPI_SCK); mbed::I2C i2c(I2C_SDA, I2C_SCL); i2c_init_param i2c_params = { GENERIC_I2C, // i2c type NOT_USED, // i2c id 100000, // i2c max speed (hz) INTERNAL_I2C, // i2c slave address (defined in app_config.h) }; spi_init_param spi_params = { MBED, //For future ADI use GENERIC_SPI, //For future ADI use NOT_USED, //id 1000000, //SPI frequency (Hz) SPI_MODE_3, //CPOL/CPHA settings for your device INTERNAL_SPI, //CS index for PinName (defined in app_config.h) }; adt7420_init_param init_params = { i2c_params, // I2C parameters spi_params, // SPI parameters NOT_USED, //Resolution setting ACTIVE_DEVICE, //Set this in app_config.h }; adt7420_dev *device; registers_e registers; int32_t connected = -1; uint8_t device_id = 0; //Configure and instantiate the UART - PB10/11 Serial pc(USBTX, USBRX, 115200); int main() { uint8_t menu_select = 0; print_title(); device_id = select_device(); connected = adt7420_init(&device, init_params); if (connected != SUCCESS) { pc.printf("\n\n Connection to device failed :(\n"); pc.printf(" ...Restarting application... \n\n"); wait(WAIT_MENU_TIME); microcontroller_reset(); } else { pc.printf("\n\n Connection to device succeeded!\n"); } while (connected == SUCCESS) { menu_select = 0; print_active_device(device_id); print_prompt(); if (get_menu_select(&menu_select) == FAILURE) pc.printf("\n***** Returning to main menu *****\n"); else { switch (menu_select) { case 1: read_temperature(); break; case 2: set_resolution(); break; case 3: set_op_mode(); break; case 4: bunch_of_temps(); break; case 5: readback_reg(); break; case 6: reset_interface(); break; case 7: write_to_setpoint_reg(); break; case 8: set_fault_queue(); break; case 9: set_ct_int_config(); break; case 10: /*Restore device registers to default values before restarting microcontroller*/ reset_interface(); microcontroller_reset(); break; default: pc.printf("Invalid option"); break; } } wait(WAIT_MENU_TIME); //wait 1 second } } /***************************************************************************//** * @brief Prints the title block. *******************************************************************************/ void print_title() { pc.printf("*****************************************************************\n"); pc.printf("* EVAL-TempeSense-ARDZ Demonstration Program -- (mbed) *\n"); pc.printf("* *\n"); pc.printf("* This program demonstrates communication with the ADT7xx *\n"); pc.printf("* High-Accuracy digital temperature sensor family *\n"); pc.printf("* It will also work with both SPI & I2C versions *\n"); pc.printf("* *\n"); pc.printf("* Set the baud rate to 115200 select the newline terminator. *\n"); pc.printf("*****************************************************************\n"); } /***************************************************************************//** * @brief Prints the "main menu" prompt to the console. *******************************************************************************/ void print_prompt() { pc.printf("\n\nCommand Summary:\n\n"); pc.printf(" 1 -Read temperature\n"); pc.printf(" 2 -Set resolution\n"); pc.printf(" 3 -Set operation mode\n"); pc.printf(" 4 -Poll temperature\n"); pc.printf(" 5 -Read a register\n"); pc.printf(" 6 -Reset the interface\n"); pc.printf(" 7 -Write to a setpoint register\n"); pc.printf(" 8 -Set Fault Queue configuration\n"); pc.printf(" 9 -Set CT/INT polarity and mode\n"); pc.printf(" 10 -Full System Reset\n"); pc.printf("\n"); } static int get_menu_select(uint8_t *menu_select) { int invalid_check = pc.scanf("%d",(int *) menu_select); return input_check(*menu_select, 1, 10, invalid_check); } /***************************************************************************//** * @brief - Select the serial interface (SPI/I2C) and device * based on the part family. * - Only one device and interface can be active. * Example: ADT7320 - SPI (Internal or Remote device) * ADT7420 - I2C (Internal or Remote device) * * @param None * * @return new_dev - Return device selected * Example: 1 - Internal(Main PCB) * 2 - Remote (External PCB) *******************************************************************************/ uint8_t select_device() { pc.printf("Please select interface by choosing a device:\n"); pc.printf(" 1- ADT7320 (SPI)\n"); pc.printf(" 2- ADT7420 (I2C)\n"); pc.printf(" Select an option: "); int invalid_check, new_interface = 0; invalid_check = pc.scanf("%d", &new_interface); //Prompts for user input while correct interface is not selected while (input_check(new_interface, 1, 2, invalid_check) == FAILURE) { pc.printf("Please select interface by choosing a device:\n"); pc.printf(" 1- ADT7320 (SPI)\n"); pc.printf(" 2- ADT7420 (I2C)\n"); pc.printf(" Select an option: "); invalid_check = pc.scanf("%d", &new_interface); } pc.printf("%d", new_interface); switch (new_interface) { case 1: pc.printf(" ADT7320 sensor selected!\n\n"); init_params.act_device = ID_ADT7320; break; case 2: pc.printf(" ADT7420 sensor selected!\n\n"); init_params.act_device = ID_ADT7420; break; } pc.printf("Available devices:\n"); pc.printf(" 1- Internal (Main PCB)\n"); pc.printf(" 2- Remote (External PCB)\n"); pc.printf(" Select an option: "); int new_dev = 0; invalid_check = pc.scanf("%d", &new_dev); //Prompts for user input while correct device is not selected while (input_check(new_dev, 1, 2, invalid_check) == FAILURE) { pc.printf("Device select:\n"); pc.printf(" 1- Internal (Main PCB)\n"); pc.printf(" 2- Remote (External PCB)\n"); pc.printf(" Select an option: "); invalid_check = pc.scanf("%d", &new_dev); } pc.printf("%d", new_dev); switch (new_dev) { case 1: pc.printf(" Internal sensor selected!"); init_params.mbed_i2c_init.slave_address = INTERNAL_I2C; init_params.mbed_spi_init.chip_select = INTERNAL_SPI; break; case 2: pc.printf(" External sensor selected!"); init_params.mbed_i2c_init.slave_address = EXTERNAL_I2C; init_params.mbed_spi_init.chip_select = EXTERNAL_SPI; break; } return new_dev; } /***************************************************************************//** * @brief - Reads and prints the temperature in Celsius Degree * * @param None * * @return - Return SUCCESS flag - currently unused. *******************************************************************************/ static uint8_t read_temperature() { float temp = adt7420_get_temperature(device); pc.printf("Current temperature:%.3f C", temp); return SUCCESS; } /***************************************************************************//** * @brief -Set the device resolution for 13 or 16 bits * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t set_resolution() { pc.printf(" Available resolutions:\n"); pc.printf(" 1- 13-bit\n"); pc.printf(" 2- 16-bit\n"); pc.printf(" Select an option: "); int new_res, invalid_check = 0; invalid_check = pc.scanf("%d", &new_res); if (input_check(new_res, 1, 2, invalid_check) == FAILURE) { return FAILURE; } else { pc.printf("%d\n", new_res); new_res = (new_res == 1) ? 0 : 1; adt7420_set_resolution(device, new_res); pc.printf("Set resolution to %d-bit", (13 + 3 * new_res)); return SUCCESS; } } /***************************************************************************//** * @brief - Set the device operation mode * (Continuous conversion, One-shot, SPS, Shutdown). * - Consult datasheet for more information. * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t set_op_mode() { pc.printf(" Available operation modes:\n"); pc.printf(" 1- Continuous conversion mode (default)\n"); pc.printf(" 2- One-shot mode\n"); pc.printf(" 3- 1 SPS mode\n"); pc.printf(" 4- Shutdown\n"); pc.printf(" Select a mode: "); int new_mode, invalid_check = 0; invalid_check = pc.scanf("%d", &new_mode); if (input_check(new_mode, 1, 4, invalid_check) == FAILURE) { return FAILURE; } else { pc.printf("%d\n", new_mode); switch (new_mode) { case 1: adt7420_set_operation_mode(device, ADT7420_OP_MODE_CONT_CONV); break; case 2: /*When One shot mode is set completes one conversion and immediately goes to shutdown mode*/ adt7420_set_operation_mode(device, ADT7420_OP_MODE_ONE_SHOT); pc.printf("\n One Shot mode enabled, device will enter shutdown mode once a conversion is complete.\n"); pc.printf(" See page 10 in datasheet for details.\n"); break; case 3: adt7420_set_operation_mode(device, ADT7420_OP_MODE_1_SPS); break; case 4: adt7420_set_operation_mode(device, ADT7420_OP_MODE_SHUTDOWN); break; default: pc.printf("Invalid option\n"); break; } return SUCCESS; } } /***************************************************************************//** * @brief - Prints poll of temperature based on the frequency of readings and * number of samples. * * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t bunch_of_temps() { pc.printf(" Enter number of desired samples: "); int num_samples, invalid_check = 1; invalid_check = pc.scanf("%d", &num_samples); if (input_check(num_samples, 1, 2000000, invalid_check) == FAILURE) { return FAILURE; } pc.printf("%d\n", num_samples); pc.printf(" Enter a desired frequency in samples/sec (max 10): "); int sample_freq = 1; invalid_check = pc.scanf("%d", &sample_freq); if (input_check(sample_freq, 1, 10, invalid_check) == FAILURE) { return FAILURE; } sample_freq = constrain(sample_freq, 1, 10); pc.printf("%d", sample_freq); uint32_t delay_sec = 1000000 / sample_freq; pc.printf(" Gathering %d seconds of samples\n", num_samples/sample_freq); pc.printf("Press enter to continue and then press again to quit\n"); getchar(); for (int i = 0; i < num_samples; i++) { if(pc.readable()) { return SUCCESS; } else { pc.printf(" Sample:%d: Temperature:", i + 1); float temp = adt7420_get_temperature(device); pc.printf("%.4f\n", temp); wait_us(delay_sec); } } return SUCCESS; } /***************************************************************************//** * @brief - Reads back data store in device registers * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t readback_reg() { pc.printf(" Available registers:\n"); pc.printf(" 1- Status\n"); pc.printf(" 2- Configuration\n"); pc.printf(" 3- Temperature\n"); pc.printf(" 4- ID\n"); pc.printf(" 5- Critical Temperature setpoint\n"); pc.printf(" 6- Hysteresis Temperature setpoint\n"); pc.printf(" 7- Temperature high setpoint\n"); pc.printf(" 8- Temperature low setpoint\n"); pc.printf(" Select a mode: "); uint16_t read_value = 0; int new_mode, invalid_check = 0; invalid_check = pc.scanf("%d", &new_mode); if (input_check(new_mode, 1, 8, invalid_check) == FAILURE) { return FAILURE; } pc.printf("%d\n", new_mode); switch (new_mode) { case 1: read_value = get_register_value(device, REG_STATUS); break; case 2: read_value = get_register_value(device, REG_CONFIG); break; case 3: read_value = get_register_value(device, REG_TEMP); break; case 4: read_value = get_register_value(device, REG_ID); break; case 5: read_value = get_register_value(device, REG_T_CRIT); break; case 6: read_value = get_register_value(device, REG_HIST); break; case 7: read_value = get_register_value(device, REG_T_HIGH); break; case 8: read_value = get_register_value(device, REG_T_LOW); break; default: break; } pc.printf("Read value: 0x%x\n", read_value); return SUCCESS; } /***************************************************************************//** * @brief - Resets device interface (SPI/I2C) (power-on reset) * * @param None * * @return - Return SUCCESS flag - currently unused. *******************************************************************************/ static uint8_t reset_interface() { pc.printf(" Resetting interface...\n"); adt7420_reset_interface(device); wait_us(RESET_DELAY); return SUCCESS; } /***************************************************************************//** * @brief - Write to setpoint registers THIGH, TLOW, TCRIT and THYST. - Values entered in Celsius and rounded to a near integer value. * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t write_to_setpoint_reg() { pc.printf(" Available registers:\n"); pc.printf(" 1- Critical setpoint\n"); pc.printf(" 2- Hystersis setpoint\n"); pc.printf(" 3- Temperature high setpoint\n"); pc.printf(" 4- Temperature low setpoint\n"); pc.printf(" Select a mode: "); int new_mode, invalid_check = 0; invalid_check = pc.scanf("%d", &new_mode); if (input_check(new_mode, 1, 4, invalid_check) == FAILURE) { return FAILURE; } pc.printf("%d\n", new_mode); float temp_c; if(new_mode == 2) { pc.printf("Enter value to write (0 to 15) Celsius:"); invalid_check = pc.scanf("%f", &temp_c); if(input_check(temp_c, MIN_HYST_TEMP, MAX_HYST_TEMP, invalid_check) == FAILURE) { return FAILURE; } } else { pc.printf("Enter value to write (in Celsius):"); invalid_check = pc.scanf("%f", &temp_c); if(input_check(temp_c, TEMP_MIN, TEMP_MAX, invalid_check) == FAILURE){ return FAILURE; } } pc.printf(" %.2f", temp_c); int16_t write_value; if(new_mode == 2) write_value = round(temp_c); else write_value = round(128 * temp_c); switch (new_mode) { case 1: if (adt7420_wr_setpoint_reg(device, REG_T_CRIT, write_value) == SUCCESS) pc.printf("\n0x%x successfuly written\n", write_value); else pc.printf("\n0x%x NOT successfuly written\n", write_value); break; case 2: if (adt7420_wr_setpoint_reg(device, REG_HIST, write_value) == SUCCESS) pc.printf("\n0x%x successfuly written (bits 7:4 are fixed at 0)\n", write_value); else pc.printf("\n0x%x NOT successfuly written\n", write_value); break; case 3: if (adt7420_wr_setpoint_reg(device, REG_T_HIGH, write_value) == SUCCESS) pc.printf("\n0x%x successfuly written\n", write_value); else pc.printf("\n0x%x NOT successfuly written\n", write_value); break; case 4: if (adt7420_wr_setpoint_reg(device, REG_T_LOW, write_value) == SUCCESS) pc.printf("\n0x%x successfuly written\n", write_value); else pc.printf("\n0x%x NOT successfuly written\n", write_value); break; default: pc.printf("Invalid selection - try again.\n"); wait(2); break; } return SUCCESS; } /***************************************************************************//** * @brief - Set the number of undertemperature/overtemperature faults * that can occur before setting the INT and CT output pins * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t set_fault_queue() { pc.printf(" Available fault queue options:\n"); pc.printf(" 1- 1 fault (default) \n"); pc.printf(" 2- 2 faults\n"); pc.printf(" 3- 3 faults\n"); pc.printf(" 4- 4 faults\n"); pc.printf(" Select a mode: "); int new_fault, invalid_check = 0; invalid_check = pc.scanf("%d", &new_fault); if (input_check(new_fault, 1, 4, invalid_check) == FAILURE) { return FAILURE; } else { pc.printf("%d\n", new_fault); switch (new_fault) { case 1: adt7420_set_fault_queue(device, ADT7420_FAULT_QUEUE_1_FAULT); break; case 2: adt7420_set_fault_queue(device, ADT7420_FAULT_QUEUE_2_FAULTS); break; case 3: adt7420_set_fault_queue(device, ADT7420_FAULT_QUEUE_3_FAULTS); break; case 4: adt7420_set_fault_queue(device, ADT7420_FAULT_QUEUE_4_FAULTS); break; default: pc.printf("Invalid option\n"); break; } return SUCCESS; } } /***************************************************************************//** * @brief - Set INT/CT Outputs pins to Comparator or Interrupt mode * * @param None * * @return - Return SUCCESS/FAILURE flags *******************************************************************************/ static uint8_t set_ct_int_config() { int new_polarity = 0; int new_mode, invalid_check = 0; pc.printf(" Choose INT/CT mode:\n"); pc.printf(" 1- Interrupt (default) \n"); pc.printf(" 2- Comparator \n"); pc.printf(" Select a mode: "); invalid_check = pc.scanf("%d", &new_mode); if (input_check(new_mode, 1, 2, invalid_check) == FAILURE) { return FAILURE; } else { pc.printf("%d\n", new_mode); new_mode = (new_mode == 1) ? 0 : 1; adt7420_set_ct_int_mode(device, new_mode); } pc.printf("\n Set output polarity for Critical and Over/Under Temperature pin:\n"); pc.printf(" (Feature available only for internal sensors).\n"); if(init_params.mbed_i2c_init.slave_address == INTERNAL_I2C || init_params.mbed_spi_init.chip_select == INTERNAL_SPI) { pc.printf(" 1- Active Low (default) \n"); pc.printf(" 2- Active High\n"); pc.printf(" Select a mode: "); invalid_check = pc.scanf("%d", &new_polarity); if (input_check(new_polarity, 1, 2, invalid_check) == FAILURE) { return FAILURE; } else { pc.printf("%d\n", new_polarity); new_polarity = (new_polarity == 1) ? 0 : 1; adt7420_set_ct_int_polarity(device, new_polarity); } } return SUCCESS; } /***************************************************************************//** * @brief Reset microcontroller * * @param None * * @return None. *******************************************************************************/ static void microcontroller_reset() { NVIC_SystemReset(); } /***************************************************************************//** * @brief Prints the active device every time the main menu is redrawn * * @param external_internal_selection - External or Internal Chip Selected * * @return None. *******************************************************************************/ static void print_active_device(int external_internal_selection) { const char* devices[7] = { "\n\n Active Device: ADT7410 I2C" , "\n\n Active Device: ADT7420 I2C", "\n\n Active Device: ADT7422 I2C", "\n\n Active Device: ADT7310 SPI", "\n\n Active Device: ADT7311 SPI", "\n\n Active Device: ADT7312 SPI", "\n\n Active Device: ADT7320 SPI"}; const char* external_internal_print[] = {" - Internal Chip \n", " - External Chip \n" }; pc.printf("%s %s", devices[init_params.act_device], external_internal_print[external_internal_selection - 1]); } /***************************************************************************//** * @brief Checks is an input is a digit and within valid range * * @param input_val - Value inputed by user * @param lowest_accepted_val - Lowest acceptable value * @param highest_accepted_val - Highest acceptable value * @param invalid_check - Checks if unexpected type of data was entered in scanf * * @return SUCCESS/FAILURE Flags. *******************************************************************************/ static int input_check(int input_val, int lowest_accepted_val, int highest_accepted_val, int invalid_check) { if(invalid_check == 0 || input_val < lowest_accepted_val || input_val > highest_accepted_val) { pc.printf("\n\n***** Invalid entry: No changes made *****\n"); wait(WAIT_MENU_TIME); return FAILURE; } return SUCCESS; }