Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r0c296cef29037819be204c45a23d4d38a52b2718 -r5738118966dd400f3d985329cf5a521dfe41c703 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 0c296cef29037819be204c45a23d4d38a52b2718) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 5738118966dd400f3d985329cf5a521dfe41c703) @@ -76,7 +76,7 @@ /// Initial conversion factor from target flow rate to PWM duty cycle estimate. #define ROP_FLOW_TO_PWM_DC(flow) ( ROP_FLOW_TO_PWM_SLOPE * flow + ROP_FLOW_TO_PWM_INTERCEPT ) #define MAX_ALLOWED_FLOW_DEVIATION 0.1F ///< Max allowed deviation from target flow. -#define FLOW_OUT_OF_RANGE_TIME_OUT_MS ( 12 * MS_PER_SECOND ) ///< Flow out of range time out in counts. +#define FLOW_OUT_OF_RANGE_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Flow out of range time out in counts. #define MAX_PRESSURE_TARGET_TOLERANCE 5 ///< Pressure tolerance from maximum set pressure by user in psi. #define MAX_ALLOWED_PRESSURE_PSI 130 ///< Maximum allowed pressure that the RO pump can go to. #define MIN_ALLOWED_PRESSURE_PSI 10 ///< Minimum allowed pressure that the RO pump can go to. @@ -366,6 +366,11 @@ checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_UPPER_RANGE, isFlowOutOfUpperRange, currentFlow, targetFlow ); checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_LOWER_RANGE, isFlowOutOfLowerRange, currentFlow, targetFlow ); } + else + { + checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_UPPER_RANGE, FALSE, 0.0F, 0.0F ); + checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_LOWER_RANGE, FALSE, 0.0F, 0.0F ); + } #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) != SW_CONFIG_ENABLE_VALUE ) @@ -450,6 +455,22 @@ /*********************************************************************//** * @brief + * The execROPumpSelfTest function executes the RO pump's self-test. + * @details Inputs: none + * @details Outputs: none + * @return PressuresSelfTestResult (SELF_TEST_STATUS_T) + *************************************************************************/ +SELF_TEST_STATUS_T execROPumpSelfTest( void ) +{ + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + + // TODO is there anything else needed in POST for the RO pump? + + return result; +} + +/*********************************************************************//** + * @brief * The isROPumpRunning function returns the on/off status of RO pump. * @details Inputs: isROPumpOn * @details Outputs: none @@ -479,7 +500,7 @@ * The getTargetROPumpPressurePSI function gets the current target RO pump * pressure. * @details Inputs: none - * @details Outputs: none + * @details Outputs: targetROPumpMaxPressure * @return the current target RO pump pressure in psi. *************************************************************************/ F32 getTargetROPumpPressurePSI( void ) Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r95327b1ffd45471bd37e514b04074d061a9c2e90 -r5738118966dd400f3d985329cf5a521dfe41c703 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 95327b1ffd45471bd37e514b04074d061a9c2e90) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 5738118966dd400f3d985329cf5a521dfe41c703) @@ -8,7 +8,7 @@ * @file TemperatureSensors.c * * @author (last) Dara Navaei -* @date (last) 04-Aug-2022 +* @date (last) 03-Oct-2022 * * @author (original) Dara Navaei * @date (original) 08-Apr-2020 @@ -76,15 +76,13 @@ #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. #define EXTERNAL_TEMP_SENSORS_ERROR_VALUE 0x80 ///< External temperature sensors error value. #define HEATERS_INTERNAL_TEMP_SENSOR_FAULT 0x01 ///< Heaters internal temperature sensor fault. #define TEMP_SENSORS_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Temperature sensors publish data time interval. #define TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Temperature sensors FPGA error timeout in milliseconds. -#define TEMP_SENSORS_ERROR_BIT_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Temperature sensors error bit 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. @@ -95,15 +93,6 @@ #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. -// The count cannot be within 0.1V of the rail on both sides therefore: -// ADC count = ((2^12) - 1 / ref voltage) * voltage -// Max allowed voltage = 3.0 - 0.1 = 2.0V -// Min allowed voltage = 0.1 - 0.0 = 0.1V -// Max count = ((2^12) - 1 / ref voltage) * voltage -> ((4096 - 1)/3.0) * (3.0 - 0.1) -// Min count = ((2^12) - 1 / ref voltage) * voltage -> ((4096 - 1)/3.0) * (0.1 - 0.0) -#define TEMP_SENSORS_MAX_ALLOWED_ADC_COUNT 3959U ///< Temperature sensors max allowed ADC count. -#define TEMP_SESNORS_MIN_ALLOWED_ADC_COUNT 137U ///< Temperature sensors min allowed ADC count. - /// Temperature sensor exec states. typedef enum tempSensors_Exec_States { @@ -122,7 +111,6 @@ S32 rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES ]; ///< Raw ADC reads array S32 adcNextIndex; ///< Next ADC read index S32 adcRunningSum; ///< ADC running sum - U32 readCount; ///< Read counts from FPGA OVERRIDE_F32_T temperatureValues; ///< Temperature values with override F32 maxAllowedTemp; ///< Maximum allowed temperature of the sensor U32 alarmStartTime; ///< Alarm start time @@ -142,6 +130,19 @@ BOOL hasCRCBeenChecked; ///< Barometric sensor has CRC been checked flag. } BARO_SENSOR_CONSTS_T; +/// Barometric sensor 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 TEMPSENSORS_EXEC_STATES_T tempSensorsExecState; ///< TemperatureSensor exec state. @@ -178,8 +179,11 @@ static const U32 TWO_TO_POWER_OF_8 = ( 1 << 8 ); ///< 2^8. static const U32 TWO_TO_POWER_OF_23 = ( 1 << 23 ); ///< 2^23. -static U32 temporaryTODORemove[2][ 300 ]; -static U32 temporaryIdx = 0; +// The count cannot be within 0.1V of the rail on both sides therefore: +// Maximum ADC count -> (2^24) * ( 3.0V - 0.1V ) / 3V +// Minimum ADC count -> (2^24) * ( 0.1V - 0.0V ) / 3V +static const U32 TEMP_SENSORS_MAX_ADC_COUNT = ( BITS_24_FULL_SCALE * ( 3.0F - 0.1F ) ) / 3.0F; ///< Temperature sensors max allowed ADC count. +static const U32 TEMP_SESNORS_MIN_ADC_COUNT = ( BITS_24_FULL_SCALE * ( 0.1F - 0.0F ) ) / 3.0F; ///< Temperature sensors min allowed ADC count. // ********** private function prototypes ********** @@ -188,9 +192,8 @@ static F32 getADC2TempConversion( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance, F32 adcConversionCoeff ); static void getHeaterInternalTemp( U32 TCIndex, U32 CJIndex ); -static void processTempSnsrsADCRead( U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount, BOOL fpgaCheck ); -static void processHtrsTempSnsrsADCRead( U32 sensorIndex, U16 adc, U32 fpgaError, U32 fpgaCount ); -static BOOL isADCReadValid( U32 sensorIndex, U32 fpgaError, U32 fpgaCount ); +static void processTempSnsrsADCRead( U32 sensorIndex, U32 adc ); +static void processHtrsTempSnsrsADCRead( U32 sensorIndex, U16 adc ); static void processADCRead( U32 sensorIndex, S32 adc ); static void publishTemperatureSensorsData( void ); static void monitorTemperatureSenors( void ); @@ -209,6 +212,7 @@ void initTemperatureSensors( void ) { U08 i; + tempSensorsExecState = TEMPSENSORS_EXEC_STATE_START; elapsedTime = 0; internalHeatersConversionTimer = 0; @@ -289,7 +293,7 @@ tempSensors[ TEMPSENSORS_TRIMMER_HEATER_INTERNAL ].maxAllowedTemp = HEATERS_INTERNAL_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // FPGA board temperature conversion coefficient - tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].conversionCoeff = 503.975 / (F32)TWELVE_BIT_RESOLUTION; + tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].conversionCoeff = 503.975 / (F32)BITS_12_FULL_SCALE; tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].maxAllowedTemp = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; F32 conversionCoeff = 1.0 / 13584.0; @@ -325,15 +329,12 @@ // Persistent alarm for the temperature sensors range check initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS, TEMP_SENSORS_OUT_OF_RANGE_TIME_OUT_MS ); - // Persistent alarm for the temperature sensors error bit fault check - initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ERROR_BIT_FAULT, TEMP_SENSORS_ERROR_BIT_TIMEOUT_MS, TEMP_SENSORS_ERROR_BIT_TIMEOUT_MS ); - - // 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 - // driver. This is internal because FPGA does not error out if the FPGA read count does not increment. - initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS ); - - initFPGAPersistentAlarm( TWO_WIRE_ADC_TEMP_SENSORS, ALARM_ID_DG_TEMPERATURE_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); + // Initialize the FPGA persistent alarms + initFPGAPersistentAlarm( FPGA_PERS_ERROR_TWO_WIRE_ADC_TEMP_SENSORS, ALARM_ID_DG_TWO_WIRE_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); + initFPGAPersistentAlarm( FPGA_PERS_ERROR_THD_ADC_TEMP_SENSORS, ALARM_ID_DG_THD_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); + initFPGAPersistentAlarm( FPGA_PERS_ERROR_TDI_ADC_TEMP_SENSORS, ALARM_ID_DG_TDI_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); + initFPGAPersistentAlarm( FPGA_PERS_ERROR_TRO_ADC_TEMP_SENSORS, ALARM_ID_DG_TRO_SENSORS_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); + initFPGAPersistentAlarm( FPGA_PERS_ERROR_BARO_SENSOR, ALARM_ID_DG_BARO_SENSOR_FPGA_FAULT, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS); } /*********************************************************************//** @@ -454,7 +455,7 @@ *************************************************************************/ F32 getTemperatureValue( U32 sensorIndex ) { - F32 temperature = 0.0; + F32 temperature = 0.0F; if ( sensorIndex < NUM_OF_TEMPERATURE_SENSORS ) { @@ -533,7 +534,7 @@ *************************************************************************/ static F32 getADC2TempConversion( F32 avgADC, U32 gain, U32 refResistance, U32 zeroDegResistance, F32 adcConversionCoeff ) { - F32 temperature = 0.0; + F32 temperature = 0.0F; if ( fabs( adcConversionCoeff ) <= NEARLY_ZERO ) { @@ -624,29 +625,14 @@ * @details Outputs: none * @param sensorIndex ID of temperature sensor to process * @param adc ADC value for the temperature sensor - * @param fpgaError reported FPGA error status - * @param fpgaCount reported FPGA read count - * @param fpgaCheck whether to check the FPGA error and count prior to converting - * the ADC to temperature * @return none *************************************************************************/ -static void processTempSnsrsADCRead( U32 sensorIndex, U32 adc, U32 fpgaError, U32 fpgaCount, BOOL fpgaCheck ) +static void processTempSnsrsADCRead( U32 sensorIndex, U32 adc ) { - BOOL isADCValid = TRUE; - S32 convertedADC = (S32)( adc & MASK_OFF_U32_MSB ); + // Some of the temperature sensors have an MSB bit that is used as an error flag. This flag will be a TRUE by default. + BOOL isErrorBitNotValid = FALSE; + S32 convertedADC = (S32)( adc & MASK_OFF_U32_MSB ); - if ( TRUE == fpgaCheck ) - { - // All the sensors have ADC read and count values that have to be checked - // but the FPGA read and error counts are shared among some of the sensors so if that counts has been checked - // once, do not check it again - isADCValid = isADCReadValid( sensorIndex, fpgaError, fpgaCount ); - } - - // Some of the temperature sensors have an MSB bit that is used as an - // error flag. This flag will be a TRUE by default. - BOOL isTemperatureNotValid = FALSE; - switch( sensorIndex ) { case TEMPSENSORS_LOAD_CELL_A1_B1: @@ -668,26 +654,18 @@ // Shift bits by 31 to right to check the error bit status tempSensors[ sensorIndex ].sensorErrorBitStatus = adc >> SHIFT_BITS_BY_31; - /*for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) + for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) { // If that bit is a 1, there is either CRC error or Status error that are ored on top of each other // NOTE: only a few sensors have the error bit available but for simplicity, all the sensors are looped. - // This variable is zeroed in the init function and the sensors that do not use this bit are never checked ( and set) to + // This variable is zeroed in the init function and the sensors that do not use this bit are never checked (and set) to // any other values so those sensors will never trigger this fault. // If any of the sensors have this bit to be 1, set the error occurred be 1 - isTemperatureNotValid |= ( tempSensors[ i ].sensorErrorBitStatus > 0 ? TRUE : FALSE ); - }*/ - -#ifndef DISABLE_FPGA_ALARMS_UNTIL_THE_NEW_PERSISTENT - // TODO for debugging only remove - if ( TRUE == isTemperatureNotValid ) - { - BOOL test = FALSE; + if ( tempSensors[ i ].sensorErrorBitStatus > 0 ) + { + isErrorBitNotValid = TRUE; + } } - // TODO remove for debugging only - - checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_ERROR_BIT_FAULT, isTemperatureNotValid, sensorIndex, TEMP_SENSORS_ERROR_BIT_TIMEOUT_MS ); -#endif } break; @@ -698,10 +676,9 @@ break; } - // To update the moving average of a temperature sensor, both ADC and internal - // error flags must be valid - if ( ( TRUE == isADCValid ) && ( FALSE == isTemperatureNotValid ) ) + if ( FALSE == isErrorBitNotValid ) { + // Make sure the error bit is not true before processADCRead( sensorIndex, convertedADC ); } } @@ -717,62 +694,13 @@ * @details Outputs: none * @param sensorIndex ID of temperature sensor to process * @param adc reported ADC value for temperature sensor - * @param fpgaError reported error status by FPGA - * @param fpgaCount reported read count by FPGA * @return none *************************************************************************/ -static void processHtrsTempSnsrsADCRead( U32 sensorIndex, U16 adc, U32 fpgaError, U32 fpgaCount ) +static void processHtrsTempSnsrsADCRead( U32 sensorIndex, U16 adc ) { - if ( TRUE == isADCReadValid( sensorIndex, fpgaError, fpgaCount ) ) - { - S16 convert = (S16)adc; - processADCRead( sensorIndex, (S32)convert ); - } -} + S16 convert = (S16)adc; -/*********************************************************************//** - * @brief - * The isADCReadValid function checks if there is an FPGA error and FPGA - * count. If there is any FPGA, it raises an alarm. If the count has changed - * and the ADC value is not the same as the previous ADC read, it returns a - * TRUE, signaling that the ADC is valid to be processed. - * @details Inputs: tempSensors - * @details Outputs: tempSensors - * @param sensorIndex Temperature sensor index - * @param fpgaError FPGA error count - * @param fpgaCount FPGA read count - * @return returns TRUE if ADC was valid otherwise FALSE - *************************************************************************/ -static BOOL isADCReadValid( U32 sensorIndex, U32 fpgaError, U32 fpgaCount ) -{ - U08 i; - BOOL isADCValid = FALSE; - BOOL isTemperatureNotValid = FALSE; - // Check the status of FPGA error and FPGA count - BOOL isFPGAErrorZero = ( 0 == fpgaError ? TRUE : FALSE ); - BOOL isFPGACountChanging = ( tempSensors[ sensorIndex ].readCount != fpgaCount ? TRUE : FALSE ); - - if ( ( TRUE == isFPGAErrorZero ) && ( TRUE == isFPGACountChanging ) ) - { - tempSensors[ sensorIndex ].readCount = fpgaCount; - isADCValid = TRUE; - } - - tempSensors[ sensorIndex ].fpgaErrorStatus = ( ( FALSE == isFPGACountChanging ) || ( FALSE == isFPGAErrorZero ) ? TRUE : FALSE ); - - for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) - { - // Loop through all the sensors and read their FPGA error status - isTemperatureNotValid |= tempSensors[ sensorIndex ].fpgaErrorStatus; - } - -#ifndef DISABLE_FPGA_ALARMS_UNTIL_THE_NEW_PERSISTENT - checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_FPGA_FAULT, isTemperatureNotValid, sensorIndex, TEMP_SENSORS_FPGA_ERROR_TIMEOUT_MS ); - - return isADCValid; -#else - return TRUE; -#endif + processADCRead( sensorIndex, (S32)convert ); } /*********************************************************************//** @@ -802,17 +730,16 @@ avgADCReads = tempSensors[ sensorIndex ].adcRunningSum >> SHIFT_BITS_BY_2_FOR_AVERAGING; // Calculate the average // Check if the average ADC is within the accepted range - tempSensors[ sensorIndex ].adcErrorStatus = ( ( (U32)avgADCReads < TEMP_SESNORS_MIN_ALLOWED_ADC_COUNT ) || - ( (U32)avgADCReads > TEMP_SENSORS_MAX_ALLOWED_ADC_COUNT ) ? TRUE : FALSE ); + tempSensors[ sensorIndex ].adcErrorStatus = ( ( (U32)avgADCReads < TEMP_SESNORS_MIN_ADC_COUNT ) || + ( (U32)avgADCReads > TEMP_SENSORS_MAX_ADC_COUNT ) ? TRUE : FALSE ); for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) { // Loop through the ADC errors isADCNotValid |= tempSensors[ sensorIndex ].adcErrorStatus; } -#ifndef DISABLE_FPGA_ALARMS_UNTIL_THE_NEW_PERSISTENT + checkPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, isADCNotValid, sensorIndex, avgADCReads ); -#endif // Different sensors have different ADC to temperature conversion methods switch( sensorIndex ) @@ -853,7 +780,7 @@ case TEMPSENSORS_BAROMETRIC_TEMP_SENSOR: { tempSensors[ sensorIndex ].baroTempSnsrDiff = (S32)avgADCReads - ( baroConvConsts.refTemperature * TWO_TO_POWER_OF_8 ); - U64 baroSnsrTemperature = BARO_SENSOR_REFERENCE_TEMP_C + ( ( tempSensors[ sensorIndex ].baroTempSnsrDiff * + S64 baroSnsrTemperature = BARO_SENSOR_REFERENCE_TEMP_C + ( ( tempSensors[ sensorIndex ].baroTempSnsrDiff * baroConvConsts.temperatureCoeff ) / TWO_TO_POWER_OF_23 ); temperature = (F32)( (U32)( baroSnsrTemperature ) / 100 ); } @@ -912,20 +839,15 @@ U32 errorCount = 0; U32 readCount = 0; - // TODO remove - //temporaryTODORemove[0][temporaryIdx] = (U32)getFPGARTDErrorCount(); - //temporaryTODORemove[1][temporaryIdx] = (U32)getFPGARTDReadCount(); - //temporaryIdx = INC_WRAP(temporaryIdx, 0, 300); - // TODO remove - errorCount = (U32)getFPGARTDErrorCount(); readCount = (U32)getFPGARTDReadCount(); - //checkFPGAPersistentAlarms( TWO_WIRE_ADC_TEMP_SENSORS, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_INLET_PRIMARY_HEATER, getFPGATPiTemp(), errorCount, readCount, TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_OUTLET_PRIMARY_HEATER, getFPGATPoTemp(), errorCount, readCount, FALSE ); - processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_1, getFPGACD1Temp(), errorCount, readCount, FALSE ); - processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2, getFPGACD2Temp(), errorCount, readCount, FALSE ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_TWO_WIRE_ADC_TEMP_SENSORS, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_INLET_PRIMARY_HEATER, getFPGATPiTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_OUTLET_PRIMARY_HEATER, getFPGATPoTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_1, getFPGACD1Temp() ); + processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2, getFPGACD2Temp() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp() ); #ifndef _RELEASE_ if ( ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) != SW_CONFIG_ENABLE_VALUE ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) @@ -934,55 +856,49 @@ errorCount = (U32)getFPGATHdErrorCount(); readCount = (U32)getFPGATHdReadCount(); - //checkFPGAPersistentAlarms( THD_ADC_TEMP_SENSORS, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_HEAT_DISINFECT, getFPGATHdTemp(), errorCount, readCount, TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THD_RTD, getFPGATHdInternalTemp(), errorCount, readCount, FALSE ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_THD_ADC_TEMP_SENSORS, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_HEAT_DISINFECT, getFPGATHdTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THD_RTD, getFPGATHdInternalTemp() ); + // Make sure the baro sensor coefficients are not corrupted checkBaroSensorCRC(); baroConvConsts.refTemperature = getFPGABaroReferenceTemperature(); baroConvConsts.temperatureCoeff = getFPGABaroTempCoeffOfTemperature(); errorCount = getFPGABaroErrorCount(); readCount = getFPGABaroReadCount(); - //checkFPGAPersistentAlarms( BARO_SENSORS, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR, getFPGABaroTemperature(), errorCount, readCount, TRUE ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_BARO_SENSOR, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR, getFPGABaroTemperature() ); } errorCount = (U32)getFPGATRoErrorCount(); readCount = (U32)getFPGATRoReadCount(); - checkFPGAPersistentAlarms( TRO_ADC_TEMP_SENSORS, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_OUTLET_REDUNDANT, getFPGATRoTemp(), errorCount, readCount, TRUE ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_TRO_ADC_TEMP_SENSORS, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_OUTLET_REDUNDANT, getFPGATRoTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_TRO_RTD, getFPGATRoInternalTemp() ); errorCount = (U32)getFPGATDiErrorCount(); readCount = (U32)getFPGATDiReadCount(); - checkFPGAPersistentAlarms( TDI_ADC_TEMP_SENSORS, errorCount, readCount ); - processTempSnsrsADCRead( TEMPSENSORS_INLET_DIALYSATE, getFPGATDiTemp(), errorCount, readCount, TRUE ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_TDI_ADC_TEMP_SENSORS, errorCount, readCount ); + processTempSnsrsADCRead( TEMPSENSORS_INLET_DIALYSATE, getFPGATDiTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_TDI_RTD, getFPGATDiInternalTemp() ); - errorCount = (U32)getFPGAPrimaryHeaterFlags(); // TODO remove these and do not check in the new persistent alarm - readCount = (U32)getFPGAPrimaryHeaterReadCount(); // TODO remove these and do not check in the new persistent alarm - //processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, getFPGAPrimaryHeaterTemp(), errorCount, readCount ); - //processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION, getFPGAPrimaryColdJunctionTemp(), errorCount, readCount ); + // The heaters' temperature sensors have read and error counts but the heaters' internal sensors are only updated for information + // and no alarm shall be raised on them including the read and error counts + processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_THERMO_COUPLE, getFPGAPrimaryHeaterTemp() ); + processHtrsTempSnsrsADCRead( TEMPSENSORS_PRIMARY_HEATER_COLD_JUNCTION, getFPGAPrimaryColdJunctionTemp() ); + processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, getFPGATrimmerHeaterTemp() ); + processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION, getFPGATrimmerColdJunctionTemp() ); - errorCount = (U32)getFPGATrimmerHeaterFlags(); - readCount = (U32)getFPGATrimmerHeaterReadCount(); - //processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_THERMO_COUPLE, getFPGATrimmerHeaterTemp(), errorCount, readCount ); - //processHtrsTempSnsrsADCRead( TEMPSENSORS_TRIMMER_HEATER_COLD_JUNCTION, getFPGATrimmerColdJunctionTemp(), errorCount, readCount ); + // The FPGA board sensor does not have read and error count. + // The load cells' temperature sensors are not read and a constant value is reported to firmware by FPGA + processTempSnsrsADCRead( TEMPSENSORS_FPGA_BOARD_SENSOR, getFPGABoardTemp() ); + processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A1_B1, getFPGALoadCellsA1B1Temp() ); + processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A2_B2, getFPGALoadCellsA2B2Temp() ); - // NOTE: FPGA board temperature sensor is different from the rest of the sensors. This sensor does not have FPGA count and error - // coming from FPGA. It is kept here to do moving average on the values. The supporting functions need to see the FPGA read count - // incrementing internally so there will not be any errors. - U32 simulatedCounter = tempSensors[ TEMPSENSORS_FPGA_BOARD_SENSOR ].readCount; - processTempSnsrsADCRead( TEMPSENSORS_FPGA_BOARD_SENSOR, getFPGABoardTemp(), 0, ++simulatedCounter, TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A1_B1, getFPGALoadCellsA1B1Temp(), getFPGAADC1ErrorCount(), getFPGAADC1ReadCount(), TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A2_B2, getFPGALoadCellsA2B2Temp(), getFPGAADC2ErrorCount(), getFPGAADC2ReadCount(), TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_TRO_RTD, getFPGATRoInternalTemp(), getFPGATRoErrorCount(), getFPGATRoReadCount(), TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_TDI_RTD, getFPGATDiInternalTemp(), getFPGATDiErrorCount(), getFPGATDiReadCount(), TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp(), getFPGARTDErrorCount(), getFPGARTDReadCount(), TRUE ); - processTempSnsrsADCRead( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR, getFPGABaroTemperature(), getFPGABaroErrorCount(), getFPGABaroReadCount(), TRUE ); - // Check if time has elapsed to calculate the internal temperature of the heaters if ( ++internalHeatersConversionTimer >= HEATERS_INTERNAL_TEMPERTURE_CALCULATION_INTERVAL ) { @@ -1026,13 +942,9 @@ data.loadCellA2B2 = getTemperatureValue( TEMPSENSORS_LOAD_CELL_A2_B2 ); data.internalTHDORTD = getTemperatureValue( TEMPSENSORS_INTERNAL_TRO_RTD ); data.internalTDIRTD = getTemperatureValue( TEMPSENSORS_INTERNAL_TDI_RTD ); + data.interalTHDRTD = getTemperatureValue( TEMPSENSORS_INTERNAL_THD_RTD ); data.internalCondSnsrTemp = getTemperatureValue( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR ); - data.primaryThermoCoupleRaw = getFPGAPrimaryHeaterTemp(); - data.primaryColdjuncRaw = getFPGAPrimaryColdJunctionTemp(); - data.trimmerThermoCoupleRaw = getFPGATrimmerHeaterTemp(); - data.trimmerColdjuncRaw = getFPGATrimmerColdJunctionTemp(); - data.cond1Raw = tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_1 ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; - data.cond2Raw = tempSensors[ TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ].rawADCReads[ MAX_NUM_OF_RAW_ADC_SAMPLES - 1 ]; + data.baroTempSensor = getTemperatureValue( TEMPSENSORS_BAROMETRIC_TEMP_SENSOR ); broadcastData( MSG_ID_DG_TEMPERATURE_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); dataPublicationTimerCounter = 0; @@ -1055,9 +967,9 @@ #endif { U08 i; - F32 temperature = 0.0; + F32 temperature = 0.0F; BOOL isTemperatureOutOfRange = FALSE; - F32 alarmTemperature = 0.0; + F32 alarmTemperature = 0.0F; U08 alarmIndex = 0; for ( i = 0; i < NUM_OF_TEMPERATURE_SENSORS; i++ ) @@ -1079,6 +991,8 @@ case TEMPSENSORS_INTERNAL_THD_RTD: case TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR: case TEMPSENSORS_BAROMETRIC_TEMP_SENSOR: + // All the temperature sensors are monitored except the heaters' temperature sensors. + // The heaters' temperature sensors are only broadcast for information temperature = getTemperatureValue( i ); // Check both temperature and to be in range @@ -1154,17 +1068,7 @@ if ( TRUE == hasCRCChanged ) { U08 calculatedCRC; - struct - { - U16 mfgInfo; - U16 pressSensitivity; - U16 pressOffset; - U16 tempCoeffOfPressSens; - U16 tempCoeffPressOffset; - U16 referenceTemp; - U16 tempCoeffOfTemp; - U16 crc; - } baroCoeffs; + BARO_SENSORS_COEFFS_T baroCoeffs; baroCoeffs.mfgInfo = getFPGABaroMfgInfo(); baroCoeffs.pressSensitivity = getFPGABaroPressureSensitivity(); @@ -1191,6 +1095,7 @@ } } + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -1214,7 +1119,7 @@ { if ( TRUE == isTestingActivated() ) { - result = TRUE; + result = TRUE; tempSensors[ sensorIndex ].temperatureValues.ovData = temperature; tempSensors[ sensorIndex ].temperatureValues.override = OVERRIDE_KEY; } @@ -1240,7 +1145,7 @@ { if ( TRUE == isTestingActivated() ) { - result = TRUE; + result = TRUE; tempSensors[ sensorIndex ].temperatureValues.override = OVERRIDE_RESET; tempSensors[ sensorIndex ].temperatureValues.ovData = tempSensors[ sensorIndex ].temperatureValues.ovInitData; } Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r0c296cef29037819be204c45a23d4d38a52b2718 -r5738118966dd400f3d985329cf5a521dfe41c703 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 0c296cef29037819be204c45a23d4d38a52b2718) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 5738118966dd400f3d985329cf5a521dfe41c703) @@ -89,8 +89,10 @@ // R1 to R2 & R2 to R1 heat disinfect circulation #define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.3F ///< Heat disinfect target RO flow rate in L/min. +#define HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM 0.8F ///< Heat disinfect target RO flow rate in L/min when transferring between reservoirs. #define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 ///< Heat disinfect maximum RO pressure in psi. #define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 12.0F ///< Heat disinfect target drain outlet pressure in psi. +#define HEAT_DISINFECT_TARGET_DRAIN_FILL_R2_PSI 9.0F ///< Heat disinfect target drain R2 fill outplet pressure in PSI #define HEAT_DISINFECT_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time for each section in milliseconds. #define HEAT_DISINFECT_START_TEMP_TIMOUT_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. #define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 0.5F * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disinfect. TODO change this to 5 seconds @@ -103,6 +105,7 @@ #define THD_REACH_BELOW_45_AFTER_CIRC_TIME_MS ( 5 * MS_PER_SECOND ) ///< Number of circulations that are needed to make the RO filter is below 45 C. #define ROF_COOL_DOWN_TARGET_FLOW_LPM 0.3F ///< RO filter cool down target flow in L/min. #define ROF_COOL_DOWN_CIRCULATION_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down circulation timer in milliseconds. +#define ROF_COOL_DOWN_MAX_TIME_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down maximum state time in milliseconds. #define TARGET_THD_SENSOR_FOR_RINSING_C 44.0F ///< Target THd temperature sensor value before rinsing in C. // Mix drain R1 and R2 @@ -170,9 +173,7 @@ static U32 rsrvrFillStableTimeCounter; ///< Reservoirs fill stable time counter. static ALARM_ID_T alarmDetectedPendingTrigger; ///< Heat disinfect alarm to raise. static BOOL isDrainPumpInMixDrainOn = FALSE; ///< Flag to indicate the drain pump is on during mix drain. -static U32 ROFCirculationTimer = 0; ///< RO filter circulation timer. static U32 ROFCoolingTimer = 0; ///< RO filter cooling timer. -static BOOL hasROFCirculationBeenStarted = FALSE; ///< Flag to indicate the water in RO filter has been recirculated. static U32 targetDisinfectTime = 0; ///< Target disinfect time. static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Boolean flag to indicate whether the drain parameters have been reset or not. static U32 tempGradOutOfRangeTimer; ///< Temperature gradient out of range start timer. @@ -245,9 +246,7 @@ rsrvrFillStableTimeCounter = 0; isPartialDisinfectInProgress = FALSE; isDrainPumpInMixDrainOn = FALSE; - ROFCirculationTimer = 0; ROFCoolingTimer = 0; - hasROFCirculationBeenStarted = FALSE; concentratePumpsPrimeTimer = 0; targetDisinfectTime = 0; haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; @@ -637,7 +636,7 @@ BOOL hasConductivityPassed = FALSE; // If the inlet temperature and conductivity are in range, move onto the next state - if ( ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) > MIN_INLET_TEMPERATURE_C ) && + if ( ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) >= MIN_INLET_TEMPERATURE_C ) && ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) <= MAX_INLET_CONDUCTIVITY_US_PER_CM ) ) { hasConductivityPassed = TRUE; @@ -1135,6 +1134,13 @@ setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter + // at inlet temperature > 45 C + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_TRANSFER_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + + // Set the drain pump to control mode + setDrainPumpTargetOutletPressure( HEAT_DISINFECT_TARGET_DRAIN_FILL_R2_PSI ); // Although there is fluid in both reservoirs, but they are set to empty // to begin the transition of hot water from R1 to R2. rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; @@ -1143,8 +1149,9 @@ // Reset the timer for the next disinfect state tempGradOutOfRangeTimer = 0; state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; - break; + break; + case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: default: heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER; @@ -1188,7 +1195,15 @@ // Get the current volumes to be monitored during R2 to R1 heat disinfect state R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); R2HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + // Set the drain pump to control mode + setDrainPumpTargetOutletPressure( HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI ); + + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter + // at inlet temperature > 45 C + setROPumpTargetFlowRateLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) @@ -1237,6 +1252,10 @@ stopHeater( DG_TRIMMER_HEATER ); stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; + + // Set the disinfect flags + setDisinfectStatus( TRUE ); + setLastDisinfectDate( USAGE_INFO_HEAT_DISINFECT, getRTCTimestamp() ); break; case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS: @@ -1254,7 +1273,7 @@ * disinfect cool down heaters state. The state continues running the fluid * while the heaters are off for a certain period of time. * @details Inputs: stateTimer - * @details Outputs: stateTimer + * @details Outputs: stateTimer, heatDisinfectUIState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownHeatersState( void ) @@ -1274,17 +1293,21 @@ // De-energize all the valves that are not in the path anymore // and wait for the RO membrane to be cooled down. - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPI, VALVE_STATE_CLOSED ); - setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); - ROFCoolingTimer = getMSTimerCount(); - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + setValveState( VBF, VALVE_STATE_OPEN ); + setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + + setROPumpTargetFlowRateLPM( ROF_COOL_DOWN_TARGET_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + + ROFCoolingTimer = 0; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + } return state; @@ -1295,23 +1318,59 @@ * The handleHeatDisinfectCoolDownROFilterState function handles the heat * disinfect cool down RO filter state. The state monitors the temperature * at THd and if it is less than 45 C, it transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, - * ROFCirculationCoolingCounter - * @details Outputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, - * ROFCirculationCoolingCounter + * @details Inputs: stateTimer, ROFCoolingTimer + * @details Outputs: stateTimer, ROFcoolingTimer, heatDisinfectUIState * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownROFilterState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; + // THd is the closet sensor to the RO filter and this temperature is monitored + // until it is dropped below 45 C to be able to run fluid through the RO filter + F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); // Set the heat disinfect UI state heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COOL_DOWN_DEVICE; - // THd is the closet sensor to the RO filter and this temperature is monitored - // until it is dropped below 45 C to be able to run fluid through the RO filter - F32 THdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); + if ( ( 0 == ROFCoolingTimer ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) + { + // Temperature is below target - perform mandatory cool down + ROFCoolingTimer = getMSTimerCount(); + } + else if ( THdTemp >= TARGET_THD_SENSOR_FOR_RINSING_C ) + { + // Temperature is not below target - reset the timer and keep looking + ROFCoolingTimer = 0; + } + if ( ( 0 != ROFCoolingTimer ) && ( TRUE == didTimeout( ROFCoolingTimer, ROF_COOL_DOWN_CIRCULATION_TIME_MS ) ) ) + { + // Temperature is below target, transition to next state + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + + signalROPumpHardStop(); + + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; + } + else if ( ( TRUE == didTimeout( stateTimer, ROF_COOL_DOWN_MAX_TIME_MS ) ) ) + { + prevHeatDisinfectState = state; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; // TODO - cool down alarm? + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + } + + return state; + +#if 0 // Check if the coldest spot temperature is less than 45 C so the RO filter can safely run if ( ( FALSE == isROPumpRunning() ) && ( THdTemp < TARGET_THD_SENSOR_FOR_RINSING_C ) ) { @@ -1355,8 +1414,8 @@ ROFCoolingTimer = getMSTimerCount(); signalROPumpHardStop(); } - return state; +#endif } /*********************************************************************//** @@ -1777,16 +1836,15 @@ failHeatDisinfect(); } - else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) - { - setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VRD2, VALVE_STATE_CLOSED ); - signalDrainPumpHardStop(); - - prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; - } } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) + { + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + signalDrainPumpHardStop(); + prevHeatDisinfectState = state; + state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + } return state; } @@ -1860,10 +1918,20 @@ { if ( ++rsrvrFillStableTimeCounter >= RSRVRS_FULL_STABLE_TIME_COUNT ) { - status = DG_RESERVOIR_REACHED_TARGET; + status = DG_RESERVOIR_REACHED_TARGET; rsrvrFillStableTimeCounter = 0; // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); + if ( ( DG_HEAT_DISINFECT_STATE_FLUSH_R2_AND_DRAIN_R1 == heatDisinfectState) && ( DG_RESERVOIR_2 == reservoir ) ) + { + if ( rsrvr1Status == DG_RESERVOIR_REACHED_TARGET ) + { + stateTimer = getMSTimerCount(); + } + } + else + { + stateTimer = getMSTimerCount(); + } } } else if ( TRUE == didTimeout( stateTimer, timeout ) ) @@ -1906,8 +1974,18 @@ if ( TRUE == isDrainComplete ) { - // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); + if ( ( DG_HEAT_DISINFECT_STATE_FLUSH_R2_AND_DRAIN_R1 == heatDisinfectState) && ( DG_RESERVOIR_1 == r) ) + { + if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status) && ( 0 == getDrainPumpTargetRPM() ) ) + { + stateTimer = getMSTimerCount(); + } + } + else + { + stateTimer = getMSTimerCount(); + } + haveDrainParamsBeenInit[ r ] = FALSE; status = DG_RESERVOIR_REACHED_TARGET; } @@ -1948,14 +2026,29 @@ // Check if the temperature gradient in between the coldest and the hottest spot is more than the specified temperature and // the timer has not started yet, start it - if ( ( TPoTemp - ThdTemp > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && ( 0 == tempGradOutOfRangeTimer ) ) + bool gradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) ? TRUE : FALSE; + if ( !gradientOutOfRange ) { + tempGradOutOfRangeTimer = 0; + } + else if ( 0 == tempGradOutOfRangeTimer ) + { tempGradOutOfRangeTimer = getMSTimerCount(); } - else if ( ( TPoTemp - ThdTemp > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && + else if ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) + { + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANGE; + status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; + } + + if ( ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && ( 0 == tempGradOutOfRangeTimer ) ) + { + tempGradOutOfRangeTimer = getMSTimerCount(); + } + else if ( ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ) && ( TRUE == didTimeout( tempGradOutOfRangeTimer, HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ) ) ) { - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANAGE; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TEMP_GRAD_OUT_OF_RANGE; status = HEAT_DISINFECT_TEMP_GRADIENT_OUT_OF_RANGE; } @@ -2035,6 +2128,7 @@ isPartialDisinfectInProgress = FALSE; } + return status; }