Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rb77808c306061c4ee874ddb6608a7da803d26ee4 -rfd84d51bd0177b49578859572d24f68571280ea4 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision b77808c306061c4ee874ddb6608a7da803d26ee4) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision fd84d51bd0177b49578859572d24f68571280ea4) @@ -7,8 +7,8 @@ * * @file ModeHeatDisinfect.c * -* @author (last) Dara Navaei -* @date (last) 12-Jul-2023 +* @author (last) Michael Garthwaite +* @date (last) 29-Aug-2023 * * @author (original) Sean * @date (original) 20-Apr-2020 @@ -66,6 +66,9 @@ #define FLUSH_CIRCULATION_CONC_PUMPS_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Flush circulation concentrate pumps on time in milliseconds. #define MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C 3.0F ///< Maximum flush circulation temperature difference tolerance in C. #define NUM_OF_TEMP_SENSORS_TO_AVG 3.0F ///< Number of temperature sensors to average to check the difference. +#define ACID_PUMP_FLUSH_RECIRCULATE_SPEED_MLPM -30.0F ///< Acid pump in flush recirculate speed in mL/min. +#define BICARB_PUMP_FLUSH_RECIRCULATE_SPEED_MLPM 30.6F ///< Bicarb pump in flush recirculate speed in mL/min. + #define ACID_PUMP_SPEED_ML_PER_MIN 30.6F ///< Acid concentrate pump speed in mL/min. // The acid pump is 2% faster than the bicarb pump to create a flow from acid to bicarb line during heat disinfect #define BICARB_PUMP_SPEED_ML_PER_MIN -30.0F ///< Bicarb concentrate pump speed in mL/min. @@ -103,6 +106,7 @@ #define HEAT_DISINFECT_REF_RSRVR_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Heat disinfect getting reference reservoirs value timeout in milliseconds. #define HEAT_DISINFECT_AT_82_C_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time at 82 C in milliseconds. #define HEAT_DISINFECT_AT_77_C_TIME_MS ( 32 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time at 77 C in milliseconds. +#define HEAT_DISNFECT_MIN_OVERRIDE_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect minimum override time. // Mix drain R1 and R2 #define RSRVRS_MIX_DRAIN_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 mix drain timeout in ms. @@ -184,6 +188,8 @@ static HEAT_DISINFECT_TIME_STATUS_T timeStatus[ NUM_OF_HEAT_DISINFECT_TIMES ]; ///< Heat disinfect time status. static F32 concPumpsStartTemperatureC; ///< Heat disinfect concentrate pumps start temperature in C. static BOOL isRODisinfectDone; ///< Heat disinfect is RO disinfect done flag. +static OVERRIDE_U32_T targetTimer77C = { HEAT_DISINFECT_AT_77_C_TIME_MS, 0, 0, 0 }; ///< Heat disinfection override target timer at 77 C +static OVERRIDE_U32_T targetTimer82C = { HEAT_DISINFECT_AT_82_C_TIME_MS, 0, 0, 0 }; ///< Heat disinfection override target timer at 82 C #ifndef _RELEASE_ /* Nelson Labs is in charge of testing the efficacy of the disinfects (heat and chem). The codes that contain the name Nelson are used to @@ -278,25 +284,25 @@ timeStatus[ RO_AT_77_C ].startTempC = HEAT_DISINFECT_START_TEMP_AT_77_C; timeStatus[ RO_AT_77_C ].startTimeMS = 0; timeStatus[ RO_AT_77_C ].stopTempC = HEAT_DISINFECT_STOP_TEMP_AT_76_C; - timeStatus[ RO_AT_77_C ].targetTimeMS = HEAT_DISINFECT_AT_77_C_TIME_MS; + timeStatus[ RO_AT_77_C ].targetTimeMS = getU32OverrideValue( &targetTimer77C ); timeStatus[ RO_AT_77_C ].tempSensor = TEMPSENSORS_HEAT_DISINFECT; timeStatus[ RO_AT_82_C ].startTempC = HEAT_DISINFECT_START_TEMP_AT_82_C; timeStatus[ RO_AT_82_C ].startTimeMS = 0; timeStatus[ RO_AT_82_C ].stopTempC = HEAT_DISINFECT_STOP_TEMP_AT_81_C; - timeStatus[ RO_AT_82_C ].targetTimeMS = HEAT_DISINFECT_AT_82_C_TIME_MS; + timeStatus[ RO_AT_82_C ].targetTimeMS = getU32OverrideValue( &targetTimer82C );; timeStatus[ RO_AT_82_C ].tempSensor = TEMPSENSORS_HEAT_DISINFECT; timeStatus[ RSRVR_AT_77_C ].startTempC = HEAT_DISINFECT_START_TEMP_AT_77_C; timeStatus[ RSRVR_AT_77_C ].startTimeMS = 0; timeStatus[ RSRVR_AT_77_C ].stopTempC = HEAT_DISINFECT_STOP_TEMP_AT_76_C; - timeStatus[ RSRVR_AT_77_C ].targetTimeMS = HEAT_DISINFECT_AT_77_C_TIME_MS; + timeStatus[ RSRVR_AT_77_C ].targetTimeMS = getU32OverrideValue( &targetTimer77C ); timeStatus[ RSRVR_AT_77_C ].tempSensor = TEMPSENSORS_INLET_DIALYSATE; timeStatus[ RSRVR_AT_82_C ].startTempC = HEAT_DISINFECT_START_TEMP_AT_82_C; timeStatus[ RSRVR_AT_82_C ].startTimeMS = 0; timeStatus[ RSRVR_AT_82_C ].stopTempC = HEAT_DISINFECT_STOP_TEMP_AT_81_C; - timeStatus[ RSRVR_AT_82_C ].targetTimeMS = HEAT_DISINFECT_AT_82_C_TIME_MS; + timeStatus[ RSRVR_AT_82_C ].targetTimeMS = getU32OverrideValue( &targetTimer82C ); timeStatus[ RSRVR_AT_82_C ].tempSensor = TEMPSENSORS_INLET_DIALYSATE; #ifndef _RELEASE_ @@ -318,7 +324,7 @@ deenergizeActuators( NO_PARK_CONC_PUMPS ); initHeatDisinfectMode(); - setCurrentSubState( heatDisinfectState ); + setCurrentSubState( NO_SUB_STATE ); setCPLDCleanLEDColor( CPLD_CLEAN_LED_ORANGE ); return heatDisinfectState; @@ -694,8 +700,8 @@ { areTempSensorsInRange = TRUE; // Turn the pumps on in reverse - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_FLUSH_RECIRCULATE_SPEED_MLPM ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_FLUSH_RECIRCULATE_SPEED_MLPM ); // Turn on the concentrate pumps requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); @@ -1329,6 +1335,8 @@ } else { + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; @@ -1363,7 +1371,7 @@ setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VRD1, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); @@ -1462,7 +1470,8 @@ * If the drain is completed within the define time, it transitions to the * complete state. * @details Inputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer - * @details Outputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer + * @details Outputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer, + * haveDrainParamsBeenInit * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeWaterPathState( void ) @@ -1498,16 +1507,17 @@ cancellationMode = CANCELLATION_MODE_HOT; } - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; + stateTimer = getMSTimerCount(); // The drain is set to start from reservoir 2 since all the actuators have been de-energized // Set the drain valve to reservoir 2 setValveState( VRD2, VALVE_STATE_OPEN ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setDrainPumpTargetRPM( targetRPM ); - - // Start the timer for drain timeout - stateTimer = getMSTimerCount(); } // If reservoir 2 is empty, set to drain reservoir 1 @@ -1600,14 +1610,16 @@ *************************************************************************/ static void failHeatDisinfect( void ) { + // If a fault alarm is active go to mode fault otherwise for cleaning mode alarms, transition to standby + DG_OP_MODE_T nextOpMode = ( FALSE == isDGFaultAlarmActive() ? DG_MODE_STAN : DG_MODE_FAUL ); + // In the cleaning modes the alarms are triggered but the mode is not transitioned to fault automatically // so transition to fault mode is done here if ( alarmDetectedPendingTrigger != ALARM_ID_NO_ALARM ) { SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevHeatDisinfectState ) } - - requestNewOperationMode( DG_MODE_STAN ); + requestNewOperationMode( nextOpMode ); } /*********************************************************************//** @@ -1840,8 +1852,8 @@ if ( TPoTempC >= concPumpsStartTemperatureC ) { - F32 acidSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP1_ACID ); - F32 bicarbSpeed = getMeasuredPumpSpeed( CONCENTRATEPUMPS_CP2_BICARB ); + F32 acidSpeed = getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP1_ACID ); + F32 bicarbSpeed = getMeasuredPumpSpeedMLPM( CONCENTRATEPUMPS_CP2_BICARB ); if ( ( acidSpeed < NEARLY_ZERO ) || ( bicarbSpeed < NEARLY_ZERO ) ) { @@ -2003,6 +2015,104 @@ } } + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testSetDG77CStateTimerOverride function checks whether the disinfection + * time of either reservoirs or the RO filter has been elapsed. + * @details Inputs: none + * @details Outputs: targetTimer77C + * @param timer which is the time to check at 77 C + * @return TRUE if request successful, FALSE if not + *************************************************************************/ +BOOL testSetDG77CStateTimerOverride( U32 timer ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( timer >= HEAT_DISNFECT_MIN_OVERRIDE_TIME_MS ) ) + { + targetTimer77C.ovData = timer; + targetTimer77C.override = OVERRIDE_KEY; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetDG77CStateTimerOverride function checks whether the disinfection + * time of either reservoirs or the RO filter has been elapsed. + * @details Inputs: none + * @details Outputs: targetTimer77C + * @param timer which is the time to check at 77 C + * @return TRUE if request successful, FALSE if not + *************************************************************************/ +BOOL testResetDG77CStateTimerOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + targetTimer77C.override = OVERRIDE_RESET; + targetTimer77C.ovData = targetTimer77C.ovInitData; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testSetDG82CStateTimerOverride function checks whether the disinfection + * time of either reservoirs or the RO filter has been elapsed. + * @details Inputs: none + * @details Outputs: targetTimer82C + * @param timer which is the time to check at 82 C + * @return TRUE if request successful, FALSE if not + *************************************************************************/ +BOOL testSetDG82CStateTimerOverride( U32 timer ) +{ + BOOL result = FALSE; + + if ( ( TRUE == isTestingActivated() ) && ( timer >= HEAT_DISNFECT_MIN_OVERRIDE_TIME_MS ) ) + { + targetTimer82C.ovData = timer; + targetTimer82C.override = OVERRIDE_KEY; + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The testResetDG82CStateTimerOverride function checks whether the disinfection + * time of either reservoirs or the RO filter has been elapsed. + * @details Inputs: none + * @details Outputs: targetTimer82C + * @param timer which is the time to check at 82 C + * @return TRUE if request successful, FALSE if not + *************************************************************************/ +BOOL testResetDG82CStateTimerOverride( void ) +{ + BOOL result = FALSE; + + if ( TRUE == isTestingActivated() ) + { + targetTimer82C.override = OVERRIDE_RESET; + targetTimer82C.ovData = targetTimer82C.ovInitData; + result = TRUE; + } + + return result; +} + /**@}*/ // ********** Nelson Support Functions **********