Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r5857de39a15c4c373c853e0856a7d7f06665848e -rf581314a2793e712cf6da87b211911a615ca3456 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 5857de39a15c4c373c853e0856a7d7f06665848e) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision f581314a2793e712cf6da87b211911a615ca3456) @@ -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 TemperatureSensors.c * * @author (last) Dara Navaei -* @date (last) 13-Jun-2023 +* @date (last) 30-May-2024 * * @author (original) Dara Navaei * @date (original) 08-Apr-2020 @@ -182,6 +182,7 @@ TEMP_SENSORS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Temperature sensors publish time interval override. static DG_TEMP_SENSORS_CAL_RECORD_T tempSensorCalRecord; ///< Temperature sensors calibration record. static DIAL_TEMP_MOVING_AVG_DATA_T dialTempMovingAvgData[ NUM_OF_DIAL_TEMPS ]; ///< Dialysate temperature moving average data. +static BOOL tempDriftEventCheck; ///< Temperature sensor drift event boolean. static const F32 POSITIVE_TC_EXP_A0 = 0.118597600000E0; ///< K TC positive temperature exponent coefficient A0. static const F32 POSITIVE_TC_EXP_A1 = -0.118343200000E-3; ///< K TC positive temperature exponent coefficient A1. static const F32 POSITIVE_TC_EXP_A2 = 0.126968600000E3; ///< K TC positive temperature exponent coefficient A2. @@ -222,6 +223,7 @@ static void adjustTemperatureSensorsRefResistance( void ); static void checkBaroSensorCRC( void ); static void processDialTemperatureData( void ); +static void getCalibrationAppliedTemperatureValue( U32 sesnorIndex, F32* temperature ); /*********************************************************************//** * @brief @@ -244,6 +246,7 @@ baroConvConsts.coeffsCRC.data = 0; baroConvConsts.hasCRCBeenChecked = FALSE; baroConvConsts.waitForCoeffStartTimeMS = 0; + tempDriftEventCheck = FALSE; /* NOTE: The temperature sensors do not have conversion coefficient. * The conversion coefficients are used for the heaters internal temperature sensors and @@ -386,7 +389,7 @@ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; BOOL calStatus = getNVRecord2Driver( GET_CAL_TEMP_SENSORS, (U08*)&tempSensorCalRecord, sizeof( DG_TEMP_SENSORS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_NO_ALARM ); + NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_DG_TEMPERATURE_SENSORS_INVALID_CAL_RECORD ); if ( TRUE == calStatus ) { @@ -410,6 +413,13 @@ *************************************************************************/ void execTemperatureSensors( void ) { + // Check if a new calibration is available + if ( TRUE == isNewCalibrationRecordAvailable() ) + { + getNVRecord2Driver( GET_CAL_TEMP_SENSORS, (U08*)&tempSensorCalRecord, sizeof( DG_TEMP_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_DG_TEMPERATURE_SENSORS_INVALID_CAL_RECORD ); + } + // Check the status of the software configuration adjustTemperatureSensorsRefResistance(); @@ -453,65 +463,79 @@ *************************************************************************/ void checkInletWaterTemperature( void ) { + F32 temperature = getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ); + + if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) + { + #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif - { - if ( getTestConfigStatus( TEST_CONFIG_DISABLE_INLET_WATER_TEMP_CHECK ) != TRUE ) { - DG_OP_MODE_T opMode = getCurrentOperationMode(); - 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 ); - - switch( opMode ) + if ( getTestConfigStatus( TEST_CONFIG_DISABLE_INLET_WATER_TEMP_CHECK ) != TRUE ) { - case DG_MODE_GENE: - case DG_MODE_FILL: - case DG_MODE_DRAI: - case DG_MODE_STAN: - if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE ) ) - { - isWaterTempInHighRange = ( temperature <= MIN_WATER_TEMPERATURE_WARNING_HIGH_RANGE ? FALSE : TRUE ); - } + DG_OP_MODE_T opMode = getCurrentOperationMode(); + BOOL isWaterTempInHighRange = ( temperature > MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ? TRUE : FALSE ); + BOOL isWaterTempInLowRange = ( temperature < MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ? TRUE : FALSE ); - // Per PRS 406 - checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, isWaterTempInHighRange, temperature, - MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); + switch( opMode ) + { + case DG_MODE_GENE: + case DG_MODE_FILL: + case DG_MODE_DRAI: + case DG_MODE_STAN: + if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE ) ) + { + isWaterTempInHighRange = ( temperature <= MIN_WATER_TEMPERATURE_WARNING_HIGH_RANGE ? FALSE : TRUE ); + } - if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_LOW_RANGE ) ) - { - isWaterTempInLowRange = ( temperature >= MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ? FALSE : TRUE ); - } + // Per PRS 406 + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, isWaterTempInHighRange, temperature, + MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); - // Per PRS 405 - checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, isWaterTempInLowRange, temperature, - MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ); - break; + if ( TRUE == isAlarmActive( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_LOW_RANGE ) ) + { + isWaterTempInLowRange = ( temperature >= MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ? FALSE : TRUE ); + } - case DG_MODE_FLUS: - case DG_MODE_HEAT: - case DG_MODE_HCOL: - case DG_MODE_CHEM: - case DG_MODE_CHFL: - case DG_MODE_ROPS: - if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) - { + // Per PRS 405 + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, isWaterTempInLowRange, temperature, + MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ); + break; + + case DG_MODE_FLUS: + case DG_MODE_HEAT: + case DG_MODE_HCOL: + case DG_MODE_CHEM: + case DG_MODE_CHFL: + case DG_MODE_ROPS: isWaterTempInHighRange = ( temperature > MAX_CLEANING_MODE_WATER_TEMPERATURE_WARNING_HIGH_RANGE ? TRUE : FALSE ); // Per PRS 557 checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH, isWaterTempInHighRange, temperature, MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_LOW, isWaterTempInLowRange, temperature, MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ); - } - break; + break; - default: - // NOTE: Do nothing in the rest of the modes - break; + default: + // NOTE: Do nothing in the rest of the modes + break; + } } } } + else + { + // VPI is closed - clear all alarms + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, FALSE, temperature, + MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); + checkPersistentAlarm( ALARM_ID_DG_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, FALSE, temperature, + MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH, FALSE, temperature, + MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_LOW, FALSE, temperature, + MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ); + } } /*********************************************************************//** @@ -604,15 +628,42 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_TEMPERATURE_SENSORS_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif { - if ( getMeasuredRawFlowRateLPM( DIALYSATE_FLOW_SENSOR ) > NEARLY_ZERO ) + DG_OP_MODE_T op = getCurrentOperationMode(); + + switch ( op ) { - F32 TDi = dialTempMovingAvgData[ DIAL_TEMP_TDI ].dialTempAvgC; - F32 TRo = dialTempMovingAvgData[ DIAL_TEMP_TRO ].dialTempAvgC; - DG_OP_MODE_T op = getCurrentOperationMode(); - F32 driftC = ( DG_MODE_HEAT == op ? TDI_TRO_TEMP_SENSORS_MAX_DEVIATION_IN_HEAT_DIS_C : TDI_TRO_TEMP_SENSORS_MAX_DEVIATION_C ); - BOOL isDriftOut = ( fabs( TDi - TRo ) > driftC ? TRUE : FALSE ); + case DG_MODE_GENE: + case DG_MODE_FILL: + case DG_MODE_DRAI: + case DG_MODE_HEAT: + case DG_MODE_CHEM: + if ( getMeasuredRawFlowRateLPM( DIALYSATE_FLOW_SENSOR ) > NEARLY_ZERO ) + { + F32 TDi = dialTempMovingAvgData[ DIAL_TEMP_TDI ].dialTempAvgC; + F32 TRo = dialTempMovingAvgData[ DIAL_TEMP_TRO ].dialTempAvgC; + F32 driftC = ( DG_MODE_HEAT == op ? TDI_TRO_TEMP_SENSORS_MAX_DEVIATION_IN_HEAT_DIS_C : TDI_TRO_TEMP_SENSORS_MAX_DEVIATION_C ); + BOOL isDriftOut = ( fabs( TDi - TRo ) > driftC ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE, isDriftOut, fabs( TDi - TRo ), driftC ); + checkPersistentAlarm( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE, isDriftOut, fabs( TDi - TRo ), driftC ); + + if ( ( FALSE == tempDriftEventCheck ) && ( TRUE == isDriftOut ) ) + { + // Send event only condition trigger, not continuously. + tempDriftEventCheck = TRUE; + SEND_EVENT_WITH_2_U32_DATA(DG_EVENT_TEMPERATURE_DRIFT, TDi, TRo) + } + + if ( ( TRUE == tempDriftEventCheck ) && ( FALSE == isDriftOut ) ) + { + tempDriftEventCheck = FALSE; + } + + } + break; + + default: + // Do not raise alarm (ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE) in other modes. + break; } } } @@ -815,10 +866,12 @@ case TEMPSENSORS_BAROMETRIC_TEMP_SENSOR: { - tempSensors[ sensorIndex ].baroTempSnsrDiff = (S32)avgADCReads - ( baroConvConsts.refTemperature * TWO_TO_POWER_OF_8 ); - S64 baroSnsrTemperature = BARO_SENSOR_REFERENCE_TEMP_C + ( ( tempSensors[ sensorIndex ].baroTempSnsrDiff * - baroConvConsts.temperatureCoeff ) / TWO_TO_POWER_OF_23 ); - temperature = (F32)( (U32)( baroSnsrTemperature ) / 100 ); + 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; @@ -830,6 +883,7 @@ break; } + getCalibrationAppliedTemperatureValue( sensorIndex, &temperature ); // Update the temperature tempSensors[ sensorIndex ].temperatureValues.data = temperature; } @@ -883,9 +937,7 @@ processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2, getFPGACD2Temp() ); processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp() ); -#ifndef _RELEASE_ - if ( ( getHardwareConfigStatus() != HW_CONFIG_BETA ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) -#endif + if ( getCurrentOperationMode() != DG_MODE_INIT ) { readCount = (U32)getFPGATHdReadCount(); @@ -1156,7 +1208,72 @@ } } +/*********************************************************************//** + * @brief + * The getCalibrationAppliedTemperatureValue function applies the calibration + * values to the provided temperature value + * @details Inputs: tempSensorCalRecord + * @details 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_DG_TEMP_SENSORS_T calId; + F32 tempTemperature = *temperature; + switch( sesnorIndex ) + { + case TEMPSENSORS_INLET_PRIMARY_HEATER: + calId = CAL_DATA_INLET_PRIMARY_HEATER_TEMP; + break; + + case TEMPSENSORS_OUTLET_PRIMARY_HEATER: + calId = CAL_DATA_OUTLET_PRIMARY_HEATER_TEMP; + break; + + case TEMPSENSORS_CONDUCTIVITY_SENSOR_1: + calId = CAL_DATA_COND_SENSOR_1_TEMP; + break; + + case TEMPSENSORS_CONDUCTIVITY_SENSOR_2: + calId = CAL_DATA_COND_SENSOR_2_TEMP; + break; + + case TEMPSENSORS_OUTLET_REDUNDANT: + calId = CAL_DATA_OUTLET_REDUNDANT_TEMP; + break; + + case TEMPSENSORS_INLET_DIALYSATE: + calId = CAL_DATA_INLET_DIALYSATE_TEMP; + break; + + case TEMPSENSORS_HEAT_DISINFECT: + calId = CAL_DATA_HEAT_DISINFECT_TEMP; + break; + + case TEMPSENSORS_BAROMETRIC_TEMP_SENSOR: + 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 *************************************************************************/