Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -ra9315539f527b92523b1598ff91e47db4d71dae2 -r883fd708ff96bcad6d6a03f8ea54984c8d20f2dd --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision a9315539f527b92523b1598ff91e47db4d71dae2) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 883fd708ff96bcad6d6a03f8ea54984c8d20f2dd) @@ -8,7 +8,7 @@ * @file TemperatureSensors.c * * @author (last) Dara Navaei -* @date (last) 02-Mar-2022 +* @date (last) 31-Mar-2022 * * @author (original) Dara Navaei * @date (original) 08-Apr-2020 @@ -55,18 +55,23 @@ #define SHIFT_BITS_BY_2_FOR_AVERAGING 2U ///< Shift the ADCs of the temperature sensors by 2 to average them. #define INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for temperature sensors out of range error period. -#define MIN_WATER_INPUT_TEMPERATURE 22U ///< Minimum water input temperature. -#define MAX_WATER_INPUT_TEMPERATURE 35U ///< Maximum water input temperature. +#define MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE 22.0F ///< Low range minimum water input temperature. +#define MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE 24.0F ///< Low range maximum water input temperature. +#define MIN_WATER_TEMPERATURE_WARNING_HIGH_RANGE 37.0F ///< High range minimum water input temperature. +#define MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE 39.0F ///< High range maximum water input temperature. + +#define MAX_WATER_TEMPERATURE_ALARM 50.0F ///< High water temperature alarm. + #define HEATERS_INTERNAL_TEMPERTURE_CALCULATION_INTERVAL 20U ///< Time interval that is used to calculate the heaters internal temperature. -#define HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF 0.25 ///< Heaters internal temperature sensors ADC to temperature conversion coefficient. -#define HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF 0.0625 ///< Heaters cold junction temperature sensors ADC to temperature conversion coefficient. +#define HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF 0.25F ///< Heaters internal temperature sensors ADC to temperature conversion coefficient. +#define HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF 0.0625F ///< Heaters cold junction temperature sensors ADC to temperature conversion coefficient. -#define K_THERMOCOUPLE_TEMP_2_MILLI_VOLT_CONVERSION_COEFF 0.041276 ///< K thermocouple temperature to millivolt conversion coefficient. +#define K_THERMOCOUPLE_TEMP_2_MILLI_VOLT_CONVERSION_COEFF 0.041276F ///< K thermocouple temperature to millivolt conversion coefficient. #define SIZE_OF_THERMOCOUPLE_COEFFICIENTS 10U ///< Size of the thermocouple coefficients. -#define CELSIUS_TO_KELVIN_CONVERSION 273.15 ///< Celsius to Kelvin temperature conversion. -#define ADC_BOARD_TEMP_SENSORS_CONVERSION_CONST 272.5 ///< ADC board temperature sensors conversion constant. +#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 TWELVE_BIT_RESOLUTION 4096U ///< 12 bit resolution conversion. #define ADC_BOARD_TEMP_SENSORS_CONST 0x800000 ///< ADC board temperature sensors constant. @@ -79,9 +84,9 @@ #define FPGA_RAW_ADC_READ_INTERVAL_COUNT 8 ///< Time interval in counts to read the raw ADC reads from FPGA. #define TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ( 5 * MS_PER_SECOND ) ///< Temperature sensors error flag persistent period. -#define TEMP_SENSORS_MIN_ALLOWED_DEGREE_C 0.0 ///< Temperature sensors minimum allowed temperature in C. -#define TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 120.0 ///< Temperature sensors maximum allowed temperature in C. -#define NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C 80.0 ///< Non fluid temperature sensors path maximum allowed temperature in C. +#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 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_PERSISTENT_PEROID_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. @@ -115,15 +120,16 @@ U32 readCount; ///< Read counts from FPGA OVERRIDE_F32_T temperatureValues; ///< Temperature values with override F32 maxAllowedTemperature; ///< Maximum allowed temperature of the sensor + U32 alarmStartTime; ///< Alarm start time } TEMP_SENSOR_T; // ********** private data ********** static TEMPSENSORS_EXEC_STATES_T tempSensorsExecState; ///< TemperatureSensor exec state. static TEMP_SENSOR_T tempSensors [ NUM_OF_TEMPERATURE_SENSORS ]; ///< Temperature sensors' data structure. -static U32 fpgaRawADCReadInterval = 0; ///< FPGA raw ADC read interval count. -static U32 elapsedTime = 0; ///< Elapsed time variable. -static U32 internalHeatersConversionTimer = 0; ///< Conversion timer variable to calculate the heaters internal temperature. +static U32 fpgaRawADCReadInterval; ///< FPGA raw ADC read interval count. +static U32 elapsedTime; ///< Elapsed time variable. +static U32 internalHeatersConversionTimer; ///< Conversion timer variable to calculate the heaters internal temperature. static U32 dataPublicationTimerCounter; ///< Temperature sensors data publish timer counter. static OVERRIDE_U32_T tempSensorsPublishInterval = { TEMP_SENSORS_DATA_PUBLISH_INTERVAL, @@ -167,6 +173,7 @@ static void processADCRead( U32 sensorIndex, S32 adc ); static void publishTemperatureSensorsData( void ); static void monitorTemperatureSnsrs( U32 sensorIndex ); +static void checkAlarmStatus( U32 sensorIndex, ALARM_ID_T alarm, BOOL alarmOccurred, U32 alarmTimeout ); /*********************************************************************//** * @brief @@ -199,6 +206,8 @@ for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; ++i ) { memset( &tempSensors[ i ], 0x0, sizeof( TEMP_SENSOR_T ) ); + + benignPolynomialCalRecord( &tempSensorCalRecord.tempSensors[ i ] ); } // Initialize TPi and TPo constants @@ -236,11 +245,15 @@ // Initialize the heaters internal thermocouples constants tempSensors[ TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ].conversionCoeff = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ].conversionCoeff = HEATERS_INTERNAL_TC_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // Initialize the heaters cold junction constants tempSensors[ TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ].conversionCoeff = HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; tempSensors[ TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ].conversionCoeff = HEATERS_COLD_JUNCTION_ADC_TO_TEMP_CONVERSION_COEFF; + tempSensors[ TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION ].maxAllowedTemperature = TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // FPGA board temperature conversion coefficient tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].conversionCoeff = 503.975 / (F32)TWELVE_BIT_RESOLUTION; @@ -267,9 +280,12 @@ initPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_TEMPERATURE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_INLET_WATER_LOW_TEMPERATURE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, - INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, + INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD, + INLET_WATER_TEMPERATURE_PERSISTENCE_PERIOD ); + // Persistent alarm for the temperature sensors range check initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE, TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS, TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ); @@ -280,7 +296,7 @@ // Persistent alarm for the temperature sensors error bit fault check initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS, - TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ); + TEMP_SENSORS_OUT_OF_RANGE_PERSISTENT_PEROID_MS ); // TODO remove? // Persistent alarm for temperature sensors ADC error // When the FPGA read count does not increment for a period of time, it is considered as an internal error of the temperature sensors @@ -349,7 +365,7 @@ /*********************************************************************//** * @brief - * The checkInletWaterTemperature checks inlet water temperature value + * The checkInletWaterTemperature function checks inlet water temperature value * and triggers an alarm when temperature value is out of allowed range. * @details Inputs: none * @details Outputs: none @@ -358,12 +374,37 @@ void checkInletWaterTemperature( void ) { #ifndef DISABLE_WATER_QUALITY_CHECK - F32 const temperature = getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ); - BOOL const isWaterTempTooHigh = temperature > MAX_WATER_INPUT_TEMPERATURE; - BOOL const isWaterTempTooLow = temperature < MIN_WATER_INPUT_TEMPERATURE; +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + F32 temperature = getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ); + BOOL isWaterTempInHighRange = ( temperature > MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ? TRUE : FALSE ); + BOOL isWaterTempInLowRange = ( temperature < MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ? TRUE : FALSE ); + BOOL isWaterTempTooHigh = ( temperature > MAX_WATER_TEMPERATURE_ALARM ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_TEMPERATURE, isWaterTempTooHigh, temperature, MAX_WATER_INPUT_TEMPERATURE ); - checkPersistentAlarm( ALARM_ID_INLET_WATER_LOW_TEMPERATURE, isWaterTempTooLow, temperature, MIN_WATER_INPUT_TEMPERATURE ); + // Fault alarm per PRS 557 for high temperature + checkPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_TEMPERATURE, isWaterTempTooHigh, temperature, MAX_WATER_TEMPERATURE_ALARM ); + + if ( TRUE == isWaterTempInHighRange ) // warning alarm per PRS 406 + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, isWaterTempInHighRange, temperature, MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); + } + else if ( temperature <= MIN_WATER_TEMPERATURE_WARNING_HIGH_RANGE ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, FALSE, temperature, MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); + } + + + if ( TRUE == isWaterTempInLowRange ) // warning alarm per PRS 405 + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, isWaterTempInLowRange, temperature, MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ); + } + else if ( temperature >= MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ) + { + checkPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, FALSE, temperature, MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ); + } + } #endif } @@ -497,11 +538,6 @@ temperature = temperature + ( POSITIVE_TC_INVERSER_COEFFS[ i ] * pow( correctedVoltage, i ) ); } } - else - { - temperature = -1.0; - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_HEATERS_NEGATIVE_COLD_JUNCTION_TEMPERATURE, CJTemp ) - } // Check which heater's internal temperature is being calculated if ( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE == TCIndex ) @@ -557,10 +593,23 @@ // is shifted 31 bits to the first bit of the U32 variable. // If that bit is a 1, there is either CRC error or Status error // that are ored on top of each other - U32 errorBit = adc >> 31; - isTemperatureNotValid = errorBit > 0; - checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, isTemperatureNotValid, sensorIndex, - TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ); + U32 errorBit = adc >> 31; + isTemperatureNotValid = ( errorBit > 0 ? TRUE : FALSE ); + + // TODO for debugging only remove + if ( TRUE == isTemperatureNotValid ) + { + BOOL test = FALSE; + } + // TODO remove + + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, sensorIndex ); + + //checkAlarmStatus( sensorIndex, ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, isTemperatureNotValid, TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ); + + // TODO remove this + //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, isTemperatureNotValid, sensorIndex, + // TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ); } break; @@ -619,28 +668,27 @@ static BOOL isADCReadValid( U32 sensorIndex, U32 fpgaError, U32 fpgaCount ) { BOOL isADCValid = FALSE; -#ifndef _VECTORCAST_ - isADCValid = TRUE; // TODO remove this line. Temporary set to true until FPGA error count is fixed - //THIS ISSUE HAS BEEN FIXED. TRY IT. -#endif // Check the status of FPGA error and FPGA count - BOOL isFPGAErrorZero = ( fpgaError == 0 ? TRUE : FALSE ); + BOOL isFPGAErrorZero = ( fpgaError == 0 ? TRUE : FALSE ); BOOL isFPGACountChanging = ( tempSensors[ sensorIndex ].readCount != fpgaCount ? TRUE : FALSE ); if ( TRUE == isFPGAErrorZero ) { if ( TRUE == isFPGACountChanging ) { tempSensors[ sensorIndex ].readCount = fpgaCount; - isADCValid = TRUE; + isADCValid = TRUE; } } BOOL isThereAnError = ( ( FALSE == isFPGACountChanging ) || ( FALSE == isFPGAErrorZero ) ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, isThereAnError, sensorIndex, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); + //checkAlarmStatus( sensorIndex, ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, isThereAnError, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); + // TODO remove + //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, isThereAnError, sensorIndex, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); + return isADCValid; } @@ -659,22 +707,26 @@ { F32 temperature; - U32 const index = tempSensors[ sensorIndex ].adcNextIndex; - S32 const indexValue = tempSensors[ sensorIndex ].rawADCReads [ index ]; + U32 index = tempSensors[ sensorIndex ].adcNextIndex; + S32 indexValue = tempSensors[ sensorIndex ].rawADCReads [ index ]; 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; // Calculate the average - F32 const avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_2_FOR_AVERAGING; + F32 avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_2_FOR_AVERAGING; // Check if the ADC value of the sensor is not out of range if ( ( (U32)avgADCReads < TEMP_SESNORS_MIN_ALLOWED_ADC_COUNT ) || ( (U32)avgADCReads > TEMP_SENSORS_MAX_ALLOWED_ADC_COUNT ) ) { - // TODO investigate why the new count check is out of range - //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ADC_OUT_OF_RANGE, TRUE, sensorIndex, avgADCReads ); + checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ADC_OUT_OF_RANGE, TRUE, sensorIndex, avgADCReads ); } + else + { + // Clear the alarm if it there was no alarm + checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ADC_OUT_OF_RANGE, FALSE, sensorIndex, avgADCReads ); + } // Different sensors have different ADC to temperature conversion methods switch( sensorIndex ) @@ -762,9 +814,9 @@ *************************************************************************/ static TEMPSENSORS_EXEC_STATES_T handleExecGetADCValues( void ) { - U32 rawADC = 0; + U32 rawADC = 0; U32 errorCount = 0; - U32 readCount = 0; + U32 readCount = 0; // Look at the error counter and the specific error flag to make sure the error is a temperature sensor // Add a byte array to have bits for each sensor to find out exactly what sensor failed @@ -893,14 +945,52 @@ *************************************************************************/ static void monitorTemperatureSnsrs( U32 sensorIndex ) { - F32 temperature = getTemperatureValue( sensorIndex ); +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_TEMPERATURE_SENSORS_ALARM ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + F32 temperature = getTemperatureValue( sensorIndex ); - // Check both temperature and to be in range - if ( ( temperature < TEMP_SENSORS_MIN_ALLOWED_DEGREE_C ) || ( temperature > tempSensors[ sensorIndex ].maxAllowedTemperature ) ) + // Check both temperature and to be in range + if ( ( temperature < TEMP_SENSORS_MIN_ALLOWED_DEGREE_C ) || ( temperature > tempSensors[ sensorIndex ].maxAllowedTemperature ) ) + { + checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE, TRUE, sensorIndex, temperature ); + } + } +} + +/*********************************************************************//** + * @brief + * The checkAlarmStatus function checks the status of an alarm and check whether + * it has timed out. + * @details Inputs: tempSensors + * @details Outputs: tempSensors + * @param sensorIndex the index of the temperature sensor + * @param alarm the alarm ID + * @param alarmOccures the boolean signal that indicates whether the error has + * occurred. + * @param alarmTimeout the timeout of the provided timeout + * @return none + *************************************************************************/ +static void checkAlarmStatus( U32 sensorIndex, ALARM_ID_T alarm, BOOL alarmOccurred, U32 alarmTimeout ) +{ + U32 startTime = tempSensors[ sensorIndex ].alarmStartTime; + + if ( TRUE == alarmOccurred ) { - // TODO investigate - //checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_OUT_OF_RANGE, TRUE, sensorIndex, temperature ); + if ( 0 == startTime ) + { + tempSensors[ sensorIndex ].alarmStartTime = getMSTimerCount(); + } + else if ( TRUE == didTimeout( startTime, alarmTimeout ) ) + { + SET_ALARM_WITH_2_U32_DATA( alarm, sensorIndex, alarmTimeout ); + } } + else if ( ( FALSE == alarmOccurred ) && ( startTime != 0 ) ) + { + tempSensors[ sensorIndex ].alarmStartTime = 0; + } }