Index: firmware/App/Controllers/Thermistors.c =================================================================== diff -u -r5b735aaed9feb2168f612b65c34849dc95e28577 -r7d4711edd7b40cd3e29f43e766f79a8a09586fe9 --- firmware/App/Controllers/Thermistors.c (.../Thermistors.c) (revision 5b735aaed9feb2168f612b65c34849dc95e28577) +++ firmware/App/Controllers/Thermistors.c (.../Thermistors.c) (revision 7d4711edd7b40cd3e29f43e766f79a8a09586fe9) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file Thermistors.c * * @author (last) Dara Navaei -* @date (last) 03-Nov-2022 +* @date (last) 18-Apr-2023 * * @author (original) Dara Navaei * @date (original) 25-Nov-2020 @@ -20,6 +20,7 @@ #include "FPGA.h" #include "InternalADC.h" #include "MessageSupport.h" +#include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "Thermistors.h" @@ -37,7 +38,9 @@ #define THERMISTORS_ADC_READ_INTERVAL ( MS_PER_SECOND / ( 2 * TASK_GENERAL_INTERVAL ) ) ///< Thermistors ADC read time interval. #define ADC_FPGA_READ_DELAY_COUNT 1.0F ///< FGPA read delay upon startup. #define TWELVE_BIT_RESOLUTION 4096U ///< 12 bit resolution conversion. +#define TEN_BIT_RESOLUTION 1024U ///< 10 bit resolution conversion. #define THERMISTOR_REFERENCE_VOLTAGE 3.0F ///< Thermistors source voltage. +#define THERMISTOR_FPGA_REF_VOLTAGE 5.0F ///< Onboard NTC, PS2 source voltage (read by FPGA). #define THERMISTOR_REFERENCE_RESISTOR_AT_25 10000.0F ///< Thermistors reference resistor in ohms. #define THERMISTOR_REFERENCE_TEMPERATURE 298.0F ///< Thermistors reference temperature in kelvin. #define THERMISTOR_BETA_VALUE 3380.0F ///< Thermistors beta value. @@ -60,6 +63,8 @@ { S32 rawADCRead; ///< Thermistor raw ADC read. OVERRIDE_F32_T temperatureValue; ///< Thermistor temperature value. + F32 voltageReference; ///< Thermistor voltage reference. + F32 adcBitResolution; ///< Thermistor ADC Bit resolution } THERMISTOR_T; static THERMISTORS_EXEC_STATES_T thermistorsExecState; ///< Thermistors exec state. @@ -69,8 +74,6 @@ static U32 dataPublishCounter; ///< Thermistors data publish timer counter. static U32 adcReadCounter; ///< Thermistors ADC read counter. -static const F32 THERMISTOR_VOLTAGE_CONV_COEFF = THERMISTOR_REFERENCE_VOLTAGE / - (F32)TWELVE_BIT_RESOLUTION; ///< Thermistors ADC to voltage conversion coefficient. static const F32 THERMISTOR_REF_TEMP_INV = 1 / THERMISTOR_REFERENCE_TEMPERATURE; ///< Thermistors reference inverse. // ********** private function prototypes ********** @@ -80,8 +83,9 @@ static void monitorThermistors( void ); static void convertADC2Temperature( void ); -static F32 calculateThemristorTemperature( U32 adcValue ); +static F32 calculateThermistorTemperature( THERMISTORS_TEMP_SENSORS_T thermistor, U32 adcValue ); static void publishThermistorsData( void ); +static void adjustThermistorSensorsRefResistance( void ); /*********************************************************************//** * @brief @@ -92,12 +96,13 @@ *************************************************************************/ void initThermistors( void ) { - // Reset the thermistors values for a run - thermistorsExecState = THERMISTORS_EXEC_STATE_START_STATE; - dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; - // Initialize a persistent alarm for thermistors temeprature out of range - initPersistentAlarm( ALARM_ID_DG_THERMISTORS_TEMPERATURE_OUT_OF_RANGE, MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD, MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD ); + // Reset the thermistors values for a run + thermistorsExecState = THERMISTORS_EXEC_STATE_START_STATE; + dataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; + + // Initialize a persistent alarm for thermistors temeprature out of range + initPersistentAlarm( ALARM_ID_DG_THERMISTORS_TEMPERATURE_OUT_OF_RANGE, MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD, MAX_ALLOWED_TEMP_OUT_OF_RANGE_PERIOD ); } /*********************************************************************//** @@ -126,6 +131,10 @@ *************************************************************************/ void execThermistors( void ) { + + // Adjust thermistors based upon hardware configuration + adjustThermistorSensorsRefResistance(); + switch ( thermistorsExecState ) { case THERMISTORS_EXEC_STATE_START_STATE: @@ -229,13 +238,21 @@ #ifndef _RELEASE_ if ( HW_CONFIG_BETA == getHardwareConfigStatus() ) { - thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getIntADCReading( INT_ADC_BOARD_THERMISTOR ); + // In Beta thermistor power supply 2 is printed as thermistor power supply 1. The corresponding ADC channel has been + // reassigned to non-isolated power supply voltage in DVT. So its enums has been renamed. + thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getIntADCReading( INT_ADC_BOARD_THERMISTOR ); + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].rawADCRead = getIntADCReading( INT_ADC_POWER_SUPPLY_1_THERMISTOR ); + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].rawADCRead = getIntADCReading( INT_ADC_POWER_SUPPLY_1_THERMISTOR ); } + else #endif + { + thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getFPGAOnBoardThermistorCount(); + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].rawADCRead = getIntADCReading( INT_ADC_POWER_SUPPLY_1_THERMISTOR ); + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].rawADCRead = getFPGAPowerSupply2ThermistorCount(); + + } // Get all the raw readings in ADC - thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].rawADCRead = getFPGAOnBoardThermistorCount(); - thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].rawADCRead = getIntADCReading( INT_ADC_POWER_SUPPLY_1_THERMISTOR ); - thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].rawADCRead = getIntADCReading( INT_ADC_POWER_SUPPLY_2_THERMISTOR ); // Zero the counter for the next round of reading adcReadCounter = 0; @@ -254,16 +271,28 @@ *************************************************************************/ static void monitorThermistors( void ) { - THERMISTORS_TEMP_SENSORS_T thermistor; - F32 temperature; + THERMISTORS_TEMP_SENSORS_T sensorId; + THERMISTORS_TEMP_SENSORS_T sensorInAlarm = THERMISTOR_FIRST; + F32 temperature = 0.0F; + BOOL isTempOutOfRange = FALSE; + F32 alarmTemperature = 0.0F; - for ( thermistor = THERMISTOR_ONBOARD_NTC; thermistor < NUM_OF_THERMISTORS; thermistor++ ) + for ( sensorId = THERMISTOR_FIRST; sensorId < NUM_OF_THERMISTORS; sensorId++ ) { - temperature = getThermistorTemperatureValue( thermistor ); - BOOL isTempOutOfRange = ( temperature > MAX_ALLOWED_TEMPERATURE ) || ( temperature < MIN_ALLOWED_TEMPERATURE ); + temperature = getThermistorTemperatureValue( sensorId ); - checkPersistentAlarm( ALARM_ID_DG_THERMISTORS_TEMPERATURE_OUT_OF_RANGE, isTempOutOfRange, temperature, MAX_ALLOWED_TEMPERATURE ); - } + // Check if thermistor is out of range + if ( ( ( temperature < MIN_ALLOWED_TEMPERATURE ) || ( temperature > MAX_ALLOWED_TEMPERATURE ) ) && + ( getCurrentOperationMode() != DG_MODE_INIT ) ) + { + isTempOutOfRange = TRUE; + sensorInAlarm = sensorId; + alarmTemperature = temperature; + } + } + + checkPersistentAlarm( ALARM_ID_DG_THERMISTORS_TEMPERATURE_OUT_OF_RANGE, isTempOutOfRange, sensorInAlarm, alarmTemperature); + } /*********************************************************************//** @@ -284,37 +313,30 @@ for ( thermistor = THERMISTOR_ONBOARD_NTC; thermistor < NUM_OF_THERMISTORS; thermistor++ ) { rawADC = (S32)thermistorsStatus[ thermistor ].rawADCRead; - - temperature = calculateThemristorTemperature( rawADC ); + temperature = calculateThermistorTemperature( thermistor, rawADC ); thermistorsStatus[ thermistor ].temperatureValue.data = temperature; } } /*********************************************************************//** * @brief - * The calculateThemristorTemperature function converts the ADC value - * of thermistors into temperature in C. Below are the calculation - * steps: - * voltage = ADC x 3 / 2^12 - * voltage = 3 x 10 / ( 10 + R(T) ) - * R(T) = 10000 x e^(beta x (1/T - 1/298)) - * Solve for T which is temperature in Kelvin + * The calculateThermistorTemperature function converts the ADC value + * of thermistors into temperature in C. * @details Inputs: none * @details Outputs: none * @param ADC value to be converted into temperature in C * @return calculated temperature in C *************************************************************************/ -static F32 calculateThemristorTemperature( U32 adcValue ) +static F32 calculateThermistorTemperature( THERMISTORS_TEMP_SENSORS_T thermistor, U32 adcValue ) { - // Voltage = ADC x 3 / 2^12 for 12 bits resolution and a 3V ADC - // The value of 3 / 2^12 has been calculated in a const to prevent the division again - F32 thermistorVoltage = adcValue * THERMISTOR_VOLTAGE_CONV_COEFF; + // Voltage = ADC x (voltage reference) / (ADC bit resolution) + F32 thermistorVoltage = adcValue * ( thermistorsStatus[ thermistor ].voltageReference / thermistorsStatus[ thermistor ].adcBitResolution ); - // Calculate the thermistor resistor by solving: thermistorVoltage = (3 x 10) / (10 + R(T)) - F32 thermistorResistor = ( ( THERMISTOR_REFERENCE_RESISTOR_AT_25 * THERMISTOR_REFERENCE_VOLTAGE ) - + // Calculate the thermistor resistor voltage reference - current voltage (at 25 degrees C) + F32 thermistorResistor = ( ( THERMISTOR_REFERENCE_RESISTOR_AT_25 * thermistorsStatus[ thermistor ].voltageReference ) - ( THERMISTOR_REFERENCE_RESISTOR_AT_25 * thermistorVoltage ) ) / thermistorVoltage; - // 1/T = Ln(thermistorResistor/10000)/3380 + 1/298 + // 1/T = Ln(thermistorResistor/THERMISTOR_REFERENCE_RESISTOR_AT_25)/THERMISTOR_BETA_VALUE + THERMISTOR_REF_TEMP_INV F32 invTemperature = ( logf( thermistorResistor / THERMISTOR_REFERENCE_RESISTOR_AT_25 ) / THERMISTOR_BETA_VALUE ) + THERMISTOR_REF_TEMP_INV; // Inverse the value to get the temperature in Kelvin and then convert it to Celsius @@ -420,14 +442,9 @@ if ( ( thermistor < NUM_OF_THERMISTORS ) && ( TRUE == isTestingActivated() ) ) { - // There is a temperature range that the thermistors can be set to, otherwise, the driver - // will throw an alarm. Also, the fans driver depends on these values to continuously control the fans - if ( ( temperature >= MIN_ALLOWED_TEMPERATURE ) && ( temperature < MAX_ALLOWED_TEMPERATURE ) ) - { - result = TRUE; - thermistorsStatus[ thermistor ].temperatureValue.ovData = temperature; - thermistorsStatus[ thermistor ].temperatureValue.override = OVERRIDE_KEY; - } + result = TRUE; + thermistorsStatus[ thermistor ].temperatureValue.ovData = temperature; + thermistorsStatus[ thermistor ].temperatureValue.override = OVERRIDE_KEY; } return result; @@ -459,4 +476,38 @@ return result; } +/*********************************************************************//** + * @brief + * The adjustTemperatureSensorsRefResistance function adjusts the temperature + * sensors V3 or DVT reference resistance values. + * @details Inputs: tempSensors + * @details Outputs: tempSensors + * @return none + *************************************************************************/ +static void adjustThermistorSensorsRefResistance( void ) +{ + + // Set voltage reference and ADC bit resolution for each thermistor +#ifndef _RELEASE_ + if ( HW_CONFIG_BETA == getHardwareConfigStatus() ) + { + thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].voltageReference = THERMISTOR_REFERENCE_VOLTAGE; + thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].adcBitResolution = TWELVE_BIT_RESOLUTION; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].voltageReference = THERMISTOR_REFERENCE_VOLTAGE; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].adcBitResolution = TWELVE_BIT_RESOLUTION; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].voltageReference = THERMISTOR_FPGA_REF_VOLTAGE; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].adcBitResolution = TWELVE_BIT_RESOLUTION; + } + else +#endif + { + thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].voltageReference = THERMISTOR_FPGA_REF_VOLTAGE; + thermistorsStatus[ THERMISTOR_ONBOARD_NTC ].adcBitResolution = TEN_BIT_RESOLUTION; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].voltageReference = THERMISTOR_REFERENCE_VOLTAGE; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_1 ].adcBitResolution = TWELVE_BIT_RESOLUTION; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].voltageReference = THERMISTOR_FPGA_REF_VOLTAGE; + thermistorsStatus[ THERMISTOR_POWER_SUPPLY_2 ].adcBitResolution = TEN_BIT_RESOLUTION; + } +} + /**@}*/