/************************************************************************** * * Copyright (c) 2024-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 TemperatureSensors.c * * @author (last) Vinayakam Mani * @date (last) 23-Sep-2024 * * @author (original) Vinayakam Mani * @date (original) 23-Sep-2024 * ***************************************************************************/ #include // For temperature calculation #include // For memset() #include "FpgaDD.h" #include "MessageSupport.h" #include "Messaging.h" //#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "TemperatureSensors.h" #include "Timers.h" #include "Utilities.h" /** * @addtogroup TemperatureSensors * @{ */ // ********** private definitions ********** #define USE_PT_100 1 ///< flag to check PT100 use in calculations #define PRIMARY_HEATER_TEMP_SENSORS_GAIN 8U ///< Primary heater temperature sensors gain. #define PRIMARY_HEATER_TEMP_SENSORS_REF_RESISTANCE 20000 ///< Primary heater temperature sensors reference resistance. #define PRIMARY_HEATER_TEMP_SENSORS_0_DEGREE_RESISTANCE 1000U ///< Primary heater temperature sensors zero degree resistance. #define PT100_TEMP_SENSORS_GAIN 8U ///< PT100 temperature sensors gain. #define PT100_TEMP_SENSORS_REF_RESISTANCE 4700 ///< PT100 temperature sensors reference resistance. #define PT100_TEMP_SENSORS_0_DEGREE_RESISTANCE 100U ///< PT100 temperature sensors zero degree resistance. #define TEMP_SENSORS_ADC_BITS 24U ///< External temperature sensors ADC bits. #define MAX_NUM_OF_RAW_ADC_SAMPLES 4U ///< Number of ADC reads for moving average calculations. #define SHIFT_BITS_BY_2 2U ///< Shift bits by 2 to create a 4 for averaging 4 samples. #define SHIFT_BITS_BY_2_FOR_AVERAGING 2U ///< Shift the ADCs of the temperature sensors by 2 to average them. #define CELSIUS_TO_KELVIN_CONVERSION 273.15F ///< Celsius to Kelvin temperature conversion. #define ADC_BOARD_TEMP_SENSORS_CONVERSION_CONST 272.5F ///< ADC board temperature sensors conversion constant. #define ADC_BOARD_TEMP_SENSORS_CONST 0x800000 ///< ADC board temperature sensors constant. #define TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Temperature sensors FPGA error timeout in milliseconds. #define TEMP_SENSORS_MIN_ALLOWED_DEGREE_C 0.0F ///< Temperature sensors minimum allowed temperature in C. #define TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 120.0F ///< Temperature sensors maximum allowed temperature in C. #define HEATERS_INTERNAL_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 200.0F ///< Heaters' internal temperature sensors maximum allowed temperature in C. #define NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 80.0F ///< Non fluid temperature sensors path maximum allowed temperature in C. #define TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS ( 5 * MS_PER_SECOND ) ///< Temperature sensor out of range persistent period in milliseconds. #define DATA_PUBLISH_COUNTER_START_COUNT 30 ///< Data publish counter start count. #define BARO_SENSOR_REFERENCE_TEMP_C 2000 ///< Barometric sensor reference temperature in C. #define BARO_SENSOR_WAIT_FOR_COEFF_TIME_OUT_MS ( 20 * MS_PER_SECOND ) ///< Barometric sensor wait for coefficients timeout in milliseconds. #define TEMP_READ_COUNTER_MAX_VALUE 255 ///< FPGA temperature sensor read counter max value. #define BARO_SENSOR_CRC_MAX_VALUE 65535 ///< Baro sensor coefficients CRC max value static const U32 TEMP_EQUATION_RESISTOR_CALC = 1 << ( TEMP_SENSORS_ADC_BITS - 1 ); ///< Temperature sensors resistor calculation (2^(24 - 1)). static const F32 TEMP_EQUATION_COEFF_A = 3.9083E-3; ///< ADC to temperature conversion coefficient A. static const F32 TEMP_EQUATION_COEFF_B = -5.775E-7; ///< ADC to temperature conversion coefficient B. static const U32 TWO_TO_POWER_OF_8 = ( 1 << 8 ); ///< 2^8. static const U32 TWO_TO_POWER_OF_23 = ( 1 << 23 ); ///< 2^23. /// Temperature sensor struct. typedef struct { F32 gain; ///< ADC gain F32 refResistance; ///< ADC reference resistance F32 conversionCoeff; ///< ADC conversion coefficient F32 zeroDegreeResistance; ///< ADC zero degree resistance S32 rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES ]; ///< Raw ADC reads array S32 adcNextIndex; ///< Next ADC read index S32 adcRunningSum; ///< ADC running sum F32 maxAllowedTemp; ///< Maximum allowed temperature of the sensor S32 baroTempSnsrDiff; ///< Barometric sensor temperature difference } TEMP_SENSOR_T; /// Barometric sensor temperature conversion typedef struct { U16 refTemperature; ///< Barometric sensor reference temperature. U16 temperatureCoeff; ///< Barometric sensor temperature coefficient. OVERRIDE_U32_T coeffsCRC; ///< Barometric sensor coefficients CRC. U32 waitForCoeffStartTimeMS; ///< Barometric sensor wait for coefficients start time in milliseconds. BOOL hasCRCBeenChecked; ///< Barometric sensor has CRC been checked flag. } BARO_SENSOR_CONSTS_T; /// Barometric sensor - 6 type of coefficients typedef struct { U16 mfgInfo; ///< Barometric sensor manufacturing info. U16 pressSensitivity; ///< Barometric sensor pressure sensitivity. U16 pressOffset; ///< Barometric sensor pressure offset. U16 tempCoeffOfPressSens; ///< Barometric sensor temperature coefficient of pressure sensor. U16 tempCoeffPressOffset; ///< Barometric sensor temperature coefficient of pressure offset. U16 referenceTemp; ///< Barometric sensor reference temperature. U16 tempCoeffOfTemp; ///< Barometric sensor temperature coefficient of Temperature sensor. U16 crc; ///< Barometric sensor CRC of the coefficients. } BARO_SENSORS_COEFFS_T; // ********** private data ********** static TEMP_SENSOR_T tempSensors [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors' data structure. static OVERRIDE_F32_T temperatureValue[ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature values with override static OVERRIDE_U32_T lastTemperatureReadCounter; ///< Temperature sensors read count from FPGA. static OVERRIDE_U32_T lastBaroTempReadCounter; ///< Barometric sensor read count from FPGA. static BARO_SENSOR_CONSTS_T baroConvConsts; ///< Barometric sensor conversion constants. //static DD_TEMP_SENSORS_CAL_RECORD_T tempSensorCalRecord; ///< Temperature sensors calibration record. // ********** private function prototypes ********** static F32 getADC2TempConversion( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance, F32 adcConversionCoeff ); static void processTempSnsrsADCRead( U32 sensorIndex, U32 adc ); static void processADCRead( U32 sensorIndex, S32 adc ); static void checkBaroSensorCRC( void ); static void checkTemperatureSensors( void ); static void getCalibrationAppliedTemperatureValue( U32 sesnorIndex, F32* temperature ); /*********************************************************************//** * @brief * The initTemperatureSensors function initializes the temperature sensors unit. * @details \b Inputs: none * @details \b Outputs: unit variables initialized * @return none *************************************************************************/ void initTemperatureSensors( void ) { U08 i; F32 conversionCoeff = 1.0F / 13584.0F; baroConvConsts.coeffsCRC.data = 0; baroConvConsts.hasCRCBeenChecked = FALSE; baroConvConsts.waitForCoeffStartTimeMS = 0; for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; ++i ) { memset( &tempSensors[ i ], 0x0, sizeof( TEMP_SENSOR_T ) ); //benignPolynomialCalRecord( &tempSensorCalRecord.tempSensors[ i ] ); } // Initialize the barometric sensor's temperature conversion constants memset( &baroConvConsts, 0x0, sizeof( BARO_SENSOR_CONSTS_T ) ); // Initialize TH1 (primary heater), TH2(outlet Heat Exchanger), TAUX ( Inlet Heat exchanger), // TH3 ( Trim Heater) constants. // Based on the PT100/PT1000,define the constants for all temperature sensors #ifdef USE_PT_100 tempSensors[ D1_TEMP ].gain = PT100_TEMP_SENSORS_GAIN; tempSensors[ D1_TEMP ].refResistance = PT100_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ D1_TEMP ].zeroDegreeResistance = PT100_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ D1_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ X6_TEMP ].gain = PT100_TEMP_SENSORS_GAIN; tempSensors[ X6_TEMP ].refResistance = PT100_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ X6_TEMP ].zeroDegreeResistance = PT100_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ X6_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ D4_TEMP ].gain = PT100_TEMP_SENSORS_GAIN; tempSensors[ D4_TEMP ].refResistance = PT100_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ D4_TEMP ].zeroDegreeResistance = PT100_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ D4_TEMP ].maxAllowedTemp = HEATERS_INTERNAL_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ D50_TEMP ].gain = PT100_TEMP_SENSORS_GAIN; tempSensors[ D50_TEMP ].refResistance = PT100_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ D50_TEMP ].zeroDegreeResistance = PT100_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ D50_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; #else tempSensors[ D1_TEMP ].gain = PRIMARY_HEATER_TEMP_SENSORS_GAIN; tempSensors[ D1_TEMP ].refResistance = PRIMARY_HEATER_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ D1_TEMP ].zeroDegreeResistance = PRIMARY_HEATER_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ D1_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ X6_TEMP ].gain = PRIMARY_HEATER_TEMP_SENSORS_GAIN; tempSensors[ X6_TEMP ].refResistance = PRIMARY_HEATER_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ X6_TEMP ].zeroDegreeResistance = PRIMARY_HEATER_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ X6_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ D4_TEMP ].gain = PRIMARY_HEATER_TEMP_SENSORS_GAIN; tempSensors[ D4_TEMP ].refResistance = PRIMARY_HEATER_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ D4_TEMP ].zeroDegreeResistance = PRIMARY_HEATER_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ D4_TEMP ].maxAllowedTemp = HEATERS_INTERNAL_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ D50_TEMP ].gain = PRIMARY_HEATER_TEMP_SENSORS_GAIN; tempSensors[ D50_TEMP ].refResistance = PRIMARY_HEATER_TEMP_SENSORS_REF_RESISTANCE; tempSensors[ D50_TEMP ].zeroDegreeResistance = PRIMARY_HEATER_TEMP_SENSORS_0_DEGREE_RESISTANCE; tempSensors[ D50_TEMP ].maxAllowedTemp = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; #endif // Board temperature sensors conversion coefficient tempSensors[ BRD_TEMP ].conversionCoeff = conversionCoeff; tempSensors[ BRD_TEMP ].maxAllowedTemp = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ BARO_TEMP ].maxAllowedTemp = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // Persistent alarm for the temperature sensors range check initPersistentAlarm( ALARM_ID_DD_TEMPERATURE_SENSOR_OUT_OF_RANGE, TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS, TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS ); // Initialize the FPGA persistent alarms initFPGAPersistentAlarm( FPGA_PERS_ERROR_RTD_ADC_TEMP_SENSORS, ALARM_ID_DD_RTD_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); initFPGAPersistentAlarm( FPGA_PERS_ERROR_BARO_SENSOR, ALARM_ID_DD_BARO_SENSOR_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); } /*********************************************************************//** * @brief * The getTemperatureValue function gets the temperature of the requested * sensor. * @details \b Inputs: tempSensors * @details \b Outputs: none * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid temperature * sensor is seen. * @param sensorIndex which is the temperature sensor index * @return temperature of the requested sensor *************************************************************************/ F32 getTemperatureValue( U32 sensorIndex ) { F32 temperature = 0.0F; if ( sensorIndex < NUM_OF_TEMPERATURE_SENSORS ) { temperature = getF32OverrideValue( &temperatureValue[ sensorIndex ] ); } else { // Wrong sensor was called, raise an alarm SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_TEMPERATURE_SENSOR_SELECTED1, sensorIndex ); } return temperature; } /*********************************************************************//** * @brief * The getBaroSensorTemperatureDiff function returns the barometric pressure * sensor's temperature difference. * @details \b Inputs: tempSensors * @details \b Outputs: none * @return barometric pressure sensor temperature difference *************************************************************************/ S32 getBaroSensorTemperatureDiff( void ) { return tempSensors[ BARO_TEMP ].baroTempSnsrDiff; } /*********************************************************************//** * @brief * The setBaroSensorCoefficientReadStartTime function populates the start * time of baro sensor coefficient read transaction initiated to FPGA. * @details \b Inputs: none * @details \b Outputs: baroConvConsts * @return none *************************************************************************/ void setBaroSensorCoefficientReadStartTime( void ) { baroConvConsts.waitForCoeffStartTimeMS = getMSTimerCount(); } /*********************************************************************//** * @brief * The readTemperatureSensors function reads the temperature sensor * value from FPGA. * @details \b Inputs: FPGA * @details \b Outputs: lastTemperatureReadCounter,lastBaroTempReadCounter * @return none *************************************************************************/ void readTemperatureSensors( void ) { // Temperature sensor read count from FPGA lastTemperatureReadCounter.data = (U32)getFPGARTDReadCount(); //Read temperature sensors processTempSnsrsADCRead( D1_TEMP, getFPGAD1Temp() ); processTempSnsrsADCRead( X6_TEMP, getFPGAX6Temp() ); processTempSnsrsADCRead( D4_TEMP, getFPGAD4Temp() ); processTempSnsrsADCRead( D50_TEMP, getFPGAD50Temp() ); //TODO: Read Board temperture //processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp() ); //Read Baro temperature sensor if ( getCurrentOperationMode() != DD_MODE_INIT ) { // Make sure the baro sensor coefficients are not corrupted checkBaroSensorCRC(); baroConvConsts.refTemperature = getFPGABaroReferenceTemperature(); baroConvConsts.temperatureCoeff = getFPGABaroTempCoeffOfTemperature(); lastBaroTempReadCounter.data = (U32)getFPGABaroReadCount(); processTempSnsrsADCRead( BARO_TEMP, getFPGABaroTemperature() ); } } /*********************************************************************//** * @brief * The getTemperatureSensorsReadCount function gets the current temperature sensor * read count for the RTD temperature sensors. * @details \b Inputs: lastTemperatureReadCounter * @details \b Outputs: none * @return The RTD temperature sensor read count. *************************************************************************/ U32 getTemperatureSensorsReadCount( void ) { U32 result = lastTemperatureReadCounter.data; if ( OVERRIDE_KEY == lastTemperatureReadCounter.override ) { result = lastTemperatureReadCounter.ovData; } return result; } /*********************************************************************//** * @brief * The getBaroTempSensorsReadCount function gets the barometric temperature sensor * read count. * @details \b Inputs: lastBaroTempReadCounter * @details \b Outputs: none * @return The barometric temperature sensor read count. *************************************************************************/ U32 getBaroTempSensorsReadCount( void ) { U32 result = lastBaroTempReadCounter.data; if ( OVERRIDE_KEY == lastBaroTempReadCounter.override ) { result = lastBaroTempReadCounter.ovData; } return result; } /*********************************************************************//** * @brief * The checkTemperatureSensors function checks the temperature sensor * freshness and see if there is any read failures from FPGA. * @details \b Inputs: Temperature sensors reading from FPGA * @details \b Outputs: none * @details \b Alarms: ALARM_ID_DD_RTD_SENSORS_FPGA_FAULT when temperature sensor * read count not updated periodically * @details \b Alarms: ALARM_ID_DD_BARO_SENSOR_FPGA_FAULT when baro temperature sensor * read count not updated periodically * @return none *************************************************************************/ static void checkTemperatureSensors( void ) { checkFPGAPersistentAlarms( FPGA_PERS_ERROR_RTD_ADC_TEMP_SENSORS, getTemperatureSensorsReadCount() ); checkFPGAPersistentAlarms( FPGA_PERS_ERROR_BARO_SENSOR, getBaroTempSensorsReadCount() ); } /*********************************************************************//** * @brief * The getADC2TempConversion function calculates the temperature from the * moving average ADC samples. * @details \b Inputs: tempEquationCoeffA, tempEquationCoeffB * @details \b Outputs: none * @param avgADC moving average ADC * @param gain ADC gain * @param refResistance ADC reference resistance * @param zeroDegResistance ADC zero degree resistance * @param adcConversionCoeff ADC conversion coefficient * @return calculated temperature *************************************************************************/ static F32 getADC2TempConversion( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance, F32 adcConversionCoeff ) { F32 temperature = 0.0F; if ( fabs( adcConversionCoeff ) <= NEARLY_ZERO ) { // R(RTD) = R(ref) * ( adc – 2^(N - 1) ) / ( G * 2^(N - 1) ); F32 resistance = ( refResistance * ( avgADC - TEMP_EQUATION_RESISTOR_CALC ) ) / ( gain * TEMP_EQUATION_RESISTOR_CALC ); // T = (-A + √( A^2 - 4B * ( 1 - R_T / R_0 ) ) ) / 2B F32 secondSqrtPart = 4 * TEMP_EQUATION_COEFF_B * ( 1 - ( resistance / zeroDegResistance ) ); temperature = ( -TEMP_EQUATION_COEFF_A + sqrt( pow( TEMP_EQUATION_COEFF_A, 2 ) - secondSqrtPart ) ) / ( 2 * TEMP_EQUATION_COEFF_B ); } else { temperature = avgADC * adcConversionCoeff; } return temperature; } /*********************************************************************//** * @brief * The processTemperatureSensorsADCRead function masks the MSB of the ADC * read from FPGA and converts it to an S32. Then it calls the routine * that checks if the read ADC is valid or not and if it is, to process * the ADC value and covert it to temperature. * @details \b Inputs: none * @details \b Outputs: none * @param sensorIndex ID of temperature sensor to process * @param adc ADC value for the temperature sensor * @return none *************************************************************************/ static void processTempSnsrsADCRead( U32 sensorIndex, U32 adc ) { S32 convertedADC = (S32)( adc & MASK_OFF_U32_MSB ); // Make sure the error bit is not true before processADCRead( sensorIndex, convertedADC ); } /*********************************************************************//** * @brief * The processADCRead function updates the ADC count moving average for a * given temperature sensor. * @details \b Inputs: tempSensors * @details \b Outputs: tempSensors * @details \b Alarms: ALARM_ID_DD_SOFTWARE_FAULT when invalid temperature * sensor is seen. * @param sensorIndex Temperature sensor index * @param adc adc reading from FPGA * @return none *************************************************************************/ static void processADCRead( U32 sensorIndex, S32 adc ) { F32 temperature; F32 avgADCReads; U32 index = tempSensors[ sensorIndex ].adcNextIndex; S32 indexValue = tempSensors[ sensorIndex ].rawADCReads[ index ]; // Update the temperature sensors' structure tempSensors[ sensorIndex ].rawADCReads[ index ] = adc; tempSensors[ sensorIndex ].adcNextIndex = INC_WRAP( index, 0, MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ); tempSensors[ sensorIndex ].adcRunningSum = tempSensors[ sensorIndex ].adcRunningSum - indexValue + adc; avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_2_FOR_AVERAGING; // Calculate the average // Different sensors have different ADC to temperature conversion methods switch( sensorIndex ) { case D1_TEMP: case X6_TEMP: case D4_TEMP: case D50_TEMP: temperature = getADC2TempConversion( avgADCReads, (U32)tempSensors [ sensorIndex ].gain, (U32)tempSensors [ sensorIndex ].refResistance, (U32)tempSensors [ sensorIndex ].zeroDegreeResistance, tempSensors [ sensorIndex ].conversionCoeff ); break; case BRD_TEMP: //TODO : Need details on calculations. break; case BARO_TEMP: { S32 baroTempSensorsDiff = (S32)avgADCReads - ( baroConvConsts.refTemperature * TWO_TO_POWER_OF_8 ); S64 differenceTimesCoefficient = (S64)baroTempSensorsDiff * (S64)baroConvConsts.temperatureCoeff; S64 baroSnsrTemperature = BARO_SENSOR_REFERENCE_TEMP_C + ( differenceTimesCoefficient / TWO_TO_POWER_OF_23 ); temperature = (F32)( baroSnsrTemperature / 100.0F ); tempSensors[ sensorIndex ].baroTempSnsrDiff = baroTempSensorsDiff; } break; default: // Wrong sensor was called, raise an alarm SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_TEMPERATURE_SENSOR_SELECTED2, sensorIndex ); // Wrong sensor, return temperature to be -1 temperature = -1.0F; break; } getCalibrationAppliedTemperatureValue( sensorIndex, &temperature ); // Update the temperature temperatureValue[ sensorIndex ].data = temperature; } /*********************************************************************//** * @brief * The monitorTemperatureSensors function monitors the temperature sensors' * temperature value and raises an alarm if any of them are out of range * for more than the specified time. * @details \b Inputs: tempSensors * @details \b Outputs: tempSensors * @details \b Alarms: ALARM_ID_DD_TEMPERATURE_SENSOR_OUT_OF_RANGE when the * measured temperature exceeds the maximum limit temperature. * @return none *************************************************************************/ void monitorTemperatureSenors( void ) { TEMPERATURE_SENSORS_T sensorId; TEMPERATURE_SENSORS_T sensorInAlarm = TEMPSENSORS_FIRST; F32 temperature = 0.0F; BOOL isTemperatureOutOfRange = FALSE; F32 alarmTemperature = 0.0F; for ( sensorId = TEMPSENSORS_FIRST; sensorId < NUM_OF_TEMPERATURE_SENSORS; sensorId++ ) { // Get temperature value. temperature = getTemperatureValue( sensorId ); // Check both temperature and to be in range if ( ( ( temperature < TEMP_SENSORS_MIN_ALLOWED_DEGREE_C ) || ( temperature > tempSensors[ sensorId ].maxAllowedTemp ) ) && ( getCurrentOperationMode() != DD_MODE_INIT ) ) { isTemperatureOutOfRange |= TRUE; sensorInAlarm = sensorId; alarmTemperature = temperature; } } checkPersistentAlarm( ALARM_ID_DD_TEMPERATURE_SENSOR_OUT_OF_RANGE, isTemperatureOutOfRange, sensorInAlarm, alarmTemperature ); //check freshness of temperature read checkTemperatureSensors(); } /*********************************************************************//** * @brief * The checkBaroSensorCRC function gets all the barometric sensor coefficients * and calls crc4 function to calculate the CRC of the coefficients and compares * them to the provided CRC by the manufacturer. * @details \b Inputs: hasBaroCoeffsBeenChecked * @details \b Outputs: hasBaroCoeffsBeenChecked * @details \b Alarms: ALARM_ID_DD_BAROMETRIC_SENSOR_COEFFS_BAD_CRC when baro * temperature sensor coefficient CRC mismatch or timeout. * @return none *************************************************************************/ static void checkBaroSensorCRC( void ) { U32 baroCRC = (U32)getFPGABaroCoeffsCRC(); BOOL hasCRCChanged = ( baroCRC != getU32OverrideValue( &baroConvConsts.coeffsCRC ) ? TRUE : FALSE ); // Once FPGA is ready get the barometric sensor's temperature conversion constants if ( TRUE == hasCRCChanged ) { U08 calculatedCRC; BARO_SENSORS_COEFFS_T baroCoeffs; baroCoeffs.mfgInfo = getFPGABaroMfgInfo(); baroCoeffs.pressSensitivity = getFPGABaroPressureSensitivity(); baroCoeffs.pressOffset = getFPGABaroPressureOffset(); baroCoeffs.tempCoeffOfPressSens = getFPGABaroTempCoeffOfPressSensitvity(); baroCoeffs.tempCoeffPressOffset = getFPGABaroTempCoeffOfPressOffset(); baroCoeffs.referenceTemp = getFPGABaroReferenceTemperature(); baroCoeffs.tempCoeffOfTemp = getFPGABaroTempCoeffOfTemperature(); baroCoeffs.crc = MASK_OFF_LSB & getFPGABaroCoeffsCRC(); calculatedCRC = crc4( (U16*)&baroCoeffs, sizeof( baroCoeffs ) ); baroConvConsts.coeffsCRC.data = baroCRC; baroCRC = (U16)( baroCRC & MASK_OFF_MSB ) & MASK_OFF_NIBBLE_MSB; baroConvConsts.hasCRCBeenChecked = TRUE; if ( calculatedCRC != baroCRC ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_BAROMETRIC_SENSOR_COEFFS_BAD_CRC, calculatedCRC, baroCoeffs.crc ); } } else if ( ( TRUE == didTimeout( baroConvConsts.waitForCoeffStartTimeMS, BARO_SENSOR_WAIT_FOR_COEFF_TIME_OUT_MS ) ) && ( FALSE == baroConvConsts.hasCRCBeenChecked ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DD_BAROMETRIC_SENSOR_COEFFS_BAD_CRC, 0, baroCRC ); } } /*********************************************************************//** * @brief * The getCalibrationAppliedTemperatureValue function applies the calibration * values to the provided temperature value * @details \b Inputs: tempSensorCalRecord * @details \b Outputs: none * @param sensorIndex Temperature sensor index * @param temperature pointer to the calculated temperature value * @return none *************************************************************************/ static void getCalibrationAppliedTemperatureValue( U32 sesnorIndex, F32* temperature ) { //CAL_DATA_DD_TEMP_SENSORS_T calId; F32 tempTemperature = *temperature; switch( sesnorIndex ) { case D1_TEMP: //calId = CAL_DATA_INLET_HEAT_EXCHANGER_TEMP; break; case X6_TEMP: //calId = CAL_DATA_OUTLET_HEAT_EXCHANGER_TEMP; break; case D4_TEMP: //calId = CAL_DATA_HYD_PRIMARY_HEATER_TEMP; break; case D50_TEMP: //calId = CAL_DATA_TRIM_HEATER_TEMP; break; case BARO_TEMP: //calId = CAL_DATA_BARMOTERIC_TEMP; break; default: // Set the calibration temperature value as num of meaning calibration is not needed for the provided sensor //calId = NUM_OF_CAL_DATA_TEMP_SENSORS; break; } // if ( calId != NUM_OF_CAL_DATA_TEMP_SENSORS ) // { // *temperature = pow( tempTemperature, 4 ) * tempSensorCalRecord.tempSensors[ calId ].fourthOrderCoeff + // pow( tempTemperature, 3 ) * tempSensorCalRecord.tempSensors[ calId ].thirdOrderCoeff + // pow( tempTemperature, 2 ) * tempSensorCalRecord.tempSensors[ calId ].secondOrderCoeff + // tempTemperature * tempSensorCalRecord.tempSensors[ calId ].gain + // tempSensorCalRecord.tempSensors[ calId ].offset; // } } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetMeasuredTemperatureOverride function sets the override value * for a specific temperature sensor. * @details Inputs: tempSensors * @details Outputs: tempSensors * @param message Override message from Dialin which includes an ID of * the sensor to override and the state to override the sensor to. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testMeasuredTemperatureOverride( MESSAGE_T *message ) { BOOL result = f32ArrayOverride( message, &temperatureValue[0], NUM_OF_TEMPERATURE_SENSORS - 1 ); return result; } /*********************************************************************//** * @brief * The testTemperatureReadCounterOverride function sets the override value * of the temperature read counter. * @details Inputs: lastTemperatureReadCounter * @details Outputs: lastTemperatureReadCounter * @param message Override message from Dialin which includes the read * counter value to override for the set of temperature sensors. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testTemperatureReadCounterOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &lastTemperatureReadCounter, 0, TEMP_READ_COUNTER_MAX_VALUE ); return result; } /*********************************************************************//** * @brief * The testBaroTemperatureReadCounterOverride function sets the override value * of the baro temperature read counter. * @details Inputs: lastBaroTempReadCounter * @details Outputs: lastBaroTempReadCounter * @param message Override message from Dialin which includes the read * counter value to override for the baro sensor. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testBaroTemperatureReadCounterOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &lastBaroTempReadCounter, 0, TEMP_READ_COUNTER_MAX_VALUE ); return result; } /*********************************************************************//** * @brief * The testBaroTemperatureReadCounterOverride function sets the override value * of the baro temperature read counter. * @details Inputs: lastBaroTempReadCounter * @details Outputs: lastBaroTempReadCounter * @param message Override message from Dialin which includes the CRC * value to override for the baro sensor. * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testBaroTemperatureCRCOverride( MESSAGE_T *message ) { BOOL result = u32Override( message, &baroConvConsts.coeffsCRC, 0, BARO_SENSOR_CRC_MAX_VALUE ); return result; } /**@}*/