/************************************************************************** * * Copyright (c) 2019-2020 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 ModeHeatDisinfect.c * * @author (last) Quang Nguyen * @date (last) 01-Sep-2020 * * @author (original) Sean * @date (original) 20-Apr-2020 * ***************************************************************************/ #include "Timers.h" #include "ModeHeatDisinfect.h" #include "OperationModes.h" #include "Valves.h" #include "Heaters.h" #include "DrainPump.h" #include "LoadCell.h" #include "ROPump.h" #include "TemperatureSensors.h" #include "UVReactors.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Pressures.h" // TODO control composition pumps // TODO add code NVDataMgmt regarding heat disinfection // TODO add logic for water temperature above 85 C /** * @addtogroup DGHeatDisinfectMode * @{ */ // ********** private definitions ********** #define HEAT_DISINFECT_TIME_INTERVAL_DAYS 2U ///< Heat disinfect time interval in days //TODO change the interval to actual value (was it every 21 days?) #define HEAT_DISINFECT_TIME_INTERVAL_SECONDS ( HEAT_DISINFECT_TIME_INTERVAL_DAYS * SECONDS_IN_A_DAY ) ///< Heat disinfect time interval in seconds #define HEAT_DISINFECT_TARGET_TEMPERATURE 85 ///< Heat disinfection target temperature #define MAX_TPO_AND_TDI_SENSORS_DIFFERENCE 1U ///< Maximum allowed temperature difference in between TDi and TPo //TODO remove #define MAX_TEMPERATURE_DEVIATION_FROM_TARGET 1.5 ///< Maximum allowed temperature deviation from target temperature #define HEAT_DISINFECT_RECIRC_PATH_TIME_MINS 1U ///< Recirculation path heat disinfection duration in minutes #define HEAT_DISINFECT_R1_TO_R2_TIME_MINS 1U ///< Reservoir 1 to reservoir 2 heat disinfection duration in minutes #define HEAT_DISINFECT_R2_TO_R1_TIME_MINS 1U ///< Reservoir 2 to reservoir 1 heat disinfection duration in minutes #define MINUTE_TO_MS_CONVERSION 60000U ///< Minutes to milliseconds conversion #define HEAT_DISINFECT_EVAC_RECIRC_PATH_TIME_MS 4000U ///< Evacuate recirculation path time in ms //TODO do we need this? Change this to the amount of time the composite pumps will run #define HEAT_DISINFECT_RECIRC_PATH_TIME_MS ( HEAT_DISINFECT_RECIRC_PATH_TIME_MINS * MINUTE_TO_MS_CONVERSION ) ///< Recirculation path heat disinfection duration in ms #define HEAT_DISINFECT_R1_TO_R2_TIME_MS ( HEAT_DISINFECT_R1_TO_R2_TIME_MINS * MINUTE_TO_MS_CONVERSION ) ///< Reservoir 1 to reservoir 2 heat disinfection duration in ms #define HEAT_DISINFECT_R2_TO_R1_TIME_MS ( HEAT_DISINFECT_R2_TO_R1_TIME_MINS * MINUTE_TO_MS_CONVERSION ) ///< Reservoir 2 to reservoir 1 heat disinfection duration in ms #define HEAT_DISINFECT_TARGET_CYCLES 5U ///< No of cycles to run heat disinfection //TODO change this value to the actual value #define HEAT_DISINFECT_DATA_PUB_INTERVAL ( MS_PER_SECOND / (2*TASK_GENERAL_INTERVAL) ) ///< Heat disinfection data publication time interval #define DRAIN_PUMP_TARGET_DELTA_PRESSURE 0.0 ///< Drain pump target delta pressure #define DRAIN_PUMP_EVACUATE_FLUID_TARGET_RPM 2800U ///< Drain pump target RPM during evacuating the fluid path #define DRAIN_PUMP_DISINFECT_DRAIN_PATH_TARGET_RPM 1500U ///< Drain pump target RPM during heat disinfection #define RO_PUMP_TARGET_FILL_FLOW_RATE_LPM 0.8 ///< RO pump target fill flow rate #define RO_PUMP_TARGET_FILL_MAX_PRESSURE 140 ///< RO pump max allowed pressure during fillin the reservoirs #define RO_PUMP_TARGET_HEAT_UP_FLOW_RATE_LPM 0.5 ///< RO pump target flow rate during heating up the fluid #define RO_PUMP_TARGET_HEAT_UP_MAX_PRESSURE 30 ///< RO pump max allowed pressure during heating up water #define RESERVOIR1_TARGET_WEIGHT_GRAMS 2000U ///< Target weight of reservoir 1 #define RESERVOIR2_TARGET_WEIGHT_GRAMS 500U ///< Target weight of reservoir 2 #define EMPTY_RESERVOIRS_WEIGHT_GRAMS 300U ///< The weight of an empty reservoir //TODO Change this value to full value // ********** private data ********** /// Heat disinfect evacuate/fill states typedef enum heat_disinfect_internal_states { INTERNAL_HEAT_DISINFECT_STATE_OFF = 0, ///< Internal heat disinfect state off INTERNAL_HEAT_DISINFECT_STATE_FILL_WITH_WATER, ///< Internal heat disinfect fill with water INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_RECIRC_PATH, ///< Internal heat disinfect evacuate recirculation path INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R1, ///< Internal heat disinfect evacuate reservoir 1 INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R2, ///< Internal heat disinfect evacuate reservoir 2 INTERNAL_HEAT_DISINFECT_STATE_COMPLETE, ///< Internal heat disinfect complete NUM_OF_INTERNAL_STATES ///< Number of internal heat disinfect states } INTERNAL_HEAT_DISINFECT_STATE_T; static INTERNAL_HEAT_DISINFECT_STATE_T heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_OFF; ///< Currently active internal heat disinfect state static DG_HEAT_DISINFECT_STATE_T heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Currently active heat disinfect state static U32 heatDisinfectStartTime = 0; ///< Overall heat disinfection elapsed time static U32 stateTimer = 0; ///< Timer of an individual state static U32 drainPumpTargetRPM = 0; ///< Drain pump current target RPM static U32 heatDisinfectCurrentCycle = 1; ///< Current cycle count of the heat disinfect mode static U32 heatDisinfectPublishCounter = 0; ///< Current publication counter of heat disinfect mode static OVERRIDE_F32_T heatDisinfectRecircDuration = { HEAT_DISINFECT_RECIRC_PATH_TIME_MS, HEAT_DISINFECT_RECIRC_PATH_TIME_MS, 0, 0 }; ///< Duration of recirculation path heat disinfeciton static OVERRIDE_F32_T heatDisinfectR1ToR2Duration = { HEAT_DISINFECT_R1_TO_R2_TIME_MS, HEAT_DISINFECT_R1_TO_R2_TIME_MS, 0, 0 }; ///< Duration of reservoir 1 to reservoir 2 heat disinfection static OVERRIDE_F32_T heatDisinfectR2ToR1Duration = { HEAT_DISINFECT_R2_TO_R1_TIME_MS, HEAT_DISINFECT_R2_TO_R1_TIME_MS, 0, 0 }; ///< Duration of reservoir 2 to reservoir 1 heat disinfection static OVERRIDE_U32_T heatDisinfectNoOfCyclesToRun = { HEAT_DISINFECT_TARGET_CYCLES, HEAT_DISINFECT_TARGET_CYCLES, 0, 0 }; ///< Number of cycles to run heat disinfection static OVERRIDE_U32_T heatDisinfectDataPublishInterval = { HEAT_DISINFECT_DATA_PUB_INTERVAL, HEAT_DISINFECT_DATA_PUB_INTERVAL, 0, 0 }; ///< Heat disinfect mode data publish interval // ********** private function prototypes ********** static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectOffState( void ); static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterState( void ); static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacRecircPathState( void ); static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacR1State( void ); static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacR2State( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStart( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacuateDialysateFillWithWater( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectHeatWater( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRecirculationPath( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectR1ToR2( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectR2ToR1( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDrainPath( void ); static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterDeprimeReservoirs( void ); static void resetActuators( void ); static void setActuatorsToFillWater( void ); static BOOL isTemperatureInRange( void ); static void execHeatDisinfectInternalStates( void ); static void publishHeatDisinfectData( void ); static U32 getPublishHeatDisinfectDataInterval( void ); static DATA_GET_PROTOTYPE( U32, getPublishHeatDisinfectDataInterval ); static DATA_GET_PROTOTYPE( F32, getRecirculationDuration ); static DATA_GET_PROTOTYPE( F32, getR1ToR2Duration ); static DATA_GET_PROTOTYPE( F32, getR2ToR1Duration ); static DATA_GET_PROTOTYPE( U32, getNoOfCyclesToRun ); /*********************************************************************//** * @brief * The initHeatDisinfectMode function initializes the heat disinfect mode module. * @details * Inputs: none * Outputs: none * @return none *************************************************************************/ void initHeatDisinfectMode( void ) { // UV reactors will not be used in the heat disinfection since their operating temperature // range is below 85C. They will be turned off once in the beginning to make sure they are // not on. turnOffUVReactor( INLET_UV_REACTOR ); turnOffUVReactor( OUTLET_UV_REACTOR ); heatDisinfectStartTime = 0; drainPumpTargetRPM = 0; heatDisinfectCurrentCycle = 1; heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; } /*********************************************************************//** * @brief * The transitionToHeatDisinfectMode function prepares for transition * to heat disinfect mode. * @details * Inputs: none * Outputs: none * @return none *************************************************************************/ void transitionToHeatDisinfectMode( void ) { initHeatDisinfectMode(); resetActuators(); } /*********************************************************************//** * @brief * The execHeatDisinfectMode function executes the heat disinfect Mode * state machine. * @details * Inputs: none * Outputs: none * @return current state. *************************************************************************/ U32 execHeatDisinfectMode( void ) { //checkInletPressureFault(); // execute current heat disinfect state switch ( heatDisinfectState ) { case DG_HEAT_DISINFECT_STATE_START: heatDisinfectState = handleHeatDisinfectStart(); break; case DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE_FILL_WITH_WATER: heatDisinfectState = handleHeatDisinfectEvacuateDialysateFillWithWater(); break; case DG_HEAT_DISINFECT_STATE_HEAT_WATER: heatDisinfectState = handleHeatDisinfectHeatWater(); break; case DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH: heatDisinfectState = handleHeatDisinfectRecirculationPath(); break; case DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2: heatDisinfectState = handleHeatDisinfectR1ToR2(); break; case DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1: heatDisinfectState = handleHeatDisinfectR2ToR1(); break; case DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH: heatDisinfectState = handleHeatDisinfectDrainPath(); break; case DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER_DEPRIME_RESERVOIRS: heatDisinfectState = handleHeatDisinfectFillWithWaterDeprimeReservoirs(); break; case DG_HEAT_DISINFECT_STATE_COMPLETE: // Do nothing break; default: // TODO - s/w fault heatDisinfectState = DG_HEAT_DISINFECT_STATE_COMPLETE; break; } publishHeatDisinfectData(); return (U32)heatDisinfectState; } /*********************************************************************//** * @brief * The getCurrentHeatDisinfectState function returns the current state of the * heat disinfect mode. * @details * Inputs: heatState * Outputs: none * @return the current state of heat disinfect mode. *************************************************************************/ DG_HEAT_DISINFECT_STATE_T getCurrentHeatDisinfectState( void ) { return heatDisinfectState; } /*********************************************************************//** * @brief * The stopDGHeatDisinfect function stops heat disinfect mode. * @details * Inputs: heatDisinfectionState * Outputs: heatDisinfectionState * @return none *************************************************************************/ void stopDGHeatDisinfect( void ) { resetActuators(); heatDisinfectState = DG_HEAT_DISINFECT_STATE_COMPLETE; heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_OFF; requestNewOperationMode( DG_MODE_STAN ); } // ********** private function definitions ********** /*********************************************************************//** * @brief * The handleHeatDisinfectStart function handles heat disinfect start state * @details * Inputs: drainPumpTargetRPM, heatDisinfectInternalState, * heatDisinfectStartTime * Outputs: drainPumpTargetRPM, heatDisinfectInternalState, * heatDisinfectStartTime * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectStart( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE_FILL_WITH_WATER; resetActuators(); drainPumpTargetRPM = DRAIN_PUMP_EVACUATE_FLUID_TARGET_RPM; //TODO do we need this? heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_OFF; heatDisinfectStartTime = getMSTimerCount(); return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectEvacuateDialysateFillWithWater function handles \n * evacuate dialysate and fill with water state * @details * Inputs: heatDisinfectInternalState * Outputs: none * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacuateDialysateFillWithWater( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE_FILL_WITH_WATER; execHeatDisinfectInternalStates(); //heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_COMPLETE; //TODO remove this for testing only if ( heatDisinfectInternalState == INTERNAL_HEAT_DISINFECT_STATE_COMPLETE ) { // Stop the RO pump that was running during the fill process signalROPumpHardStop(); setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NC ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setROPumpTargetFlowRate( RO_PUMP_TARGET_HEAT_UP_FLOW_RATE_LPM, RO_PUMP_TARGET_HEAT_UP_MAX_PRESSURE ); setDrainPumpTargetDeltaPressure( DRAIN_PUMP_TARGET_DELTA_PRESSURE ); setPrimaryHeaterTargetTemperature( 40.0 ); //HEAT_DISINFECT_TARGET_TEMPERATURE startPrimaryHeater(); state = DG_HEAT_DISINFECT_STATE_HEAT_WATER; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectHeatWater function handles heat water state * @details * Inputs: stateTimer * Outputs: stateTimer * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectHeatWater( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_HEAT_WATER; F32 TDi = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); F32 test = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODO remove later if ( fabs( test - HEAT_DISINFECT_TARGET_TEMPERATURE ) <= MAX_TEMPERATURE_DEVIATION_FROM_TARGET ) { // Set the states to disinfect recirculation path /*setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO );*/ stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectRecirculationPath function handles disinfect \n * recirculate path state * @details * Inputs: stateTimer * Outputs: stateTimer * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectRecirculationPath( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH; // If the temperature is out of tolerance, go back to heat water if ( ! isTemperatureInRange() ) { state = DG_HEAT_DISINFECT_STATE_HEAT_WATER; } else if ( didTimeout( stateTimer, getRecirculationDuration() ) ) { // Set the state for reservoir 1 to reservoir 2 setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectReservoir1To2 function handles disinfect \n * reservoir 1 to reservoir 2 state * @details * Inputs: stateTimer * Outputs: stateTimer * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectR1ToR2( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2; // If the temperature is out of tolerance, go back to heat water if ( ! isTemperatureInRange() ) { state = DG_HEAT_DISINFECT_STATE_HEAT_WATER; } else if ( didTimeout( stateTimer, getR1ToR2Duration() ) ) { // Set the state for reservoir 1 to reservoir 2 setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectReservoir2To1 function handles disinfect \n * reservoir 2 to reservoir 1 state * @details * Inputs: heatDisinfectCurrentCycle, heatDisinfectInternalState, * drainPumpTargetRPM, stateTimer * Outputs: heatDisinfectCurrentCycle, heatDisinfectInternalState, * drainPumpTargetRPM, stateTimer * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectR2ToR1( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; // If the temperature is out of tolerance, go back to heat water if ( ! isTemperatureInRange() ) { state = DG_HEAT_DISINFECT_STATE_HEAT_WATER; } else if ( didTimeout( stateTimer, getR2ToR1Duration() ) ) { // Set the state for reservoir 1 to reservoir 2 setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setDrainPumpTargetDeltaPressure( DRAIN_PUMP_TARGET_DELTA_PRESSURE ); setROPumpTargetFlowRate( RO_PUMP_TARGET_HEAT_UP_FLOW_RATE_LPM, RO_PUMP_TARGET_HEAT_UP_MAX_PRESSURE ); if ( ++heatDisinfectCurrentCycle > getNoOfCyclesToRun() ) { drainPumpTargetRPM = DRAIN_PUMP_DISINFECT_DRAIN_PATH_TARGET_RPM; heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_OFF; state = DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH; } else { setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); stateTimer = getMSTimerCount(); heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_OFF; state = DG_HEAT_DISINFECT_STATE_DISINFECT_RECIRC_PATH; } } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectDrainPath function handles disinfect drain path \n * state * @details * Inputs: drainPumpTargetRPM, heatDisinfectInternalState * Outputs: drainPumpTargetRPM, heatDisinfectInternalState * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDrainPath( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH; execHeatDisinfectInternalStates(); //TODO test to see if it is needed to be in an if statement if ( heatDisinfectInternalState == INTERNAL_HEAT_DISINFECT_STATE_COMPLETE ) { stopPrimaryHeater(); stopTrimmerHeater(); drainPumpTargetRPM = DRAIN_PUMP_EVACUATE_FLUID_TARGET_RPM; heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_OFF; state = DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER_DEPRIME_RESERVOIRS; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectFillWithWaterDeprimeReservoirs function handles \n * fill with water and deprime the reservoirs state * @details * Inputs: none * Outputs: none * @return next state *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterDeprimeReservoirs( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER_DEPRIME_RESERVOIRS; execHeatDisinfectInternalStates(); //TODO test to see if it is needed to be in an if statement // Done with heat disinfect if ( heatDisinfectInternalState == INTERNAL_HEAT_DISINFECT_STATE_COMPLETE ) { state = DG_HEAT_DISINFECT_STATE_COMPLETE; } return state; } /*********************************************************************//** * @brief * The execHeatDisinfectInternalStates function executes the heat \n * disinfection internal state machine * @details * Inputs: heatDisinfectInternalState * Outputs: heatDisinfectInternalState * @return none *************************************************************************/ static void execHeatDisinfectInternalStates( void ) { switch ( heatDisinfectInternalState ) { case INTERNAL_HEAT_DISINFECT_STATE_OFF: heatDisinfectInternalState = handleHeatDisinfectOffState(); break; case INTERNAL_HEAT_DISINFECT_STATE_FILL_WITH_WATER: heatDisinfectInternalState = handleHeatDisinfectFillWithWaterState(); break; case INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_RECIRC_PATH: heatDisinfectInternalState = handleHeatDisinfectEvacRecircPathState(); break; case INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R1: heatDisinfectInternalState = handleHeatDisinfectEvacR1State(); break; case INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R2: heatDisinfectInternalState = handleHeatDisinfectEvacR2State(); break; case INTERNAL_HEAT_DISINFECT_STATE_COMPLETE: // Do nothing break; default: // TODO add sw fault heatDisinfectInternalState = INTERNAL_HEAT_DISINFECT_STATE_COMPLETE; break; } } /*********************************************************************//** * @brief * The handleHeatDisinfectOffState function handles internal heat disinfect \n * off state * @details * Inputs: heatDisinfectState, stateTimer * Outputs: stateTimer * @return next state *************************************************************************/ static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectOffState( void ) { INTERNAL_HEAT_DISINFECT_STATE_T state = INTERNAL_HEAT_DISINFECT_STATE_OFF; // If the state is evacuate dialysate, start with evacuating recirculate path if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE_FILL_WITH_WATER ) { // Set the actuators for evacuate recirculation path setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); //setROPumpTargetPWM( 0.85 ); //TODO remove this. It setROPumpTargetFlowRate( RO_PUMP_TARGET_FILL_FLOW_RATE_LPM, RO_PUMP_TARGET_FILL_MAX_PRESSURE ); stateTimer = getMSTimerCount(); // For evac recirc path. TODO later, it should be controlled using // the composite pump state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_RECIRC_PATH; } else if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER_DEPRIME_RESERVOIRS ) { setActuatorsToFillWater(); state = INTERNAL_HEAT_DISINFECT_STATE_FILL_WITH_WATER; } else if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH ) { // Set the actuators for draining the path signalROPumpHardStop(); signalDrainPumpHardStop(); stopPrimaryHeater(); stopTrimmerHeater(); setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setDrainPumpTargetRPM( drainPumpTargetRPM ); state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R1; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectFillWithWaterState function handles internal \n * fill with water state * @details * Inputs: heatDisinfectState, stateTimer * Outputs: stateTimer * @return next state *************************************************************************/ static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterState( void ) { INTERNAL_HEAT_DISINFECT_STATE_T state = INTERNAL_HEAT_DISINFECT_STATE_FILL_WITH_WATER; F32 reservoir1Weight = getLoadCellFilteredWeight( LOAD_CELL_A1 ); F32 reservoir2Weight = getLoadCellFilteredWeight( LOAD_CELL_B1 ); if ( reservoir1Weight >= RESERVOIR1_TARGET_WEIGHT_GRAMS && reservoir2Weight >= RESERVOIR2_TARGET_WEIGHT_GRAMS ) { if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE_FILL_WITH_WATER ) { resetActuators(); state = INTERNAL_HEAT_DISINFECT_STATE_COMPLETE; } else if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER_DEPRIME_RESERVOIRS ) { setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setROPumpTargetFlowRate( RO_PUMP_TARGET_FILL_FLOW_RATE_LPM, RO_PUMP_TARGET_FILL_MAX_PRESSURE ); stateTimer = getMSTimerCount(); state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_RECIRC_PATH; } } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectEvacRecircPathState function handles internal \n * evacuate recirculation path state * @details * Inputs: stateTimer, drainPumpTargetRPM * Outputs: none * @return next state *************************************************************************/ static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacRecircPathState( void ) { INTERNAL_HEAT_DISINFECT_STATE_T state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_RECIRC_PATH; // TODO change this to composition pump mode if ( didTimeout( stateTimer, HEAT_DISINFECT_EVAC_RECIRC_PATH_TIME_MS ) ) { // Set the state to evacuate reservoir 1 signalROPumpHardStop(); setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R2_C_TO_NO ); setValveState( VRD, VALVE_STATE_R1_C_TO_NC ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setDrainPumpTargetRPM( drainPumpTargetRPM ); //TODO commented for testing state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R1; } return state; } /*********************************************************************//** * @brief * The handleHeatDisifnectEvacReservoir1State function handles internal \n * evacuate reservoir 1 state * @details * Inputs: none * Outputs: none * @return next state *************************************************************************/ static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacR1State( void ) { INTERNAL_HEAT_DISINFECT_STATE_T state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R1; F32 reservoir1Weight = getLoadCellFilteredWeight( LOAD_CELL_A1 ); if ( reservoir1Weight <= EMPTY_RESERVOIRS_WEIGHT_GRAMS ) { // Set the state to evacuate reservoir 2 setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_OPEN ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R2_C_TO_NC ); setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R2; } return state; } /*********************************************************************//** * @brief * The handleHeatDisinfectEvacReservoir2State function handles internal \n * evacuate reservoir 2 state * @details * Inputs: heatDisinfectState * Outputs: none * @return next state *************************************************************************/ static INTERNAL_HEAT_DISINFECT_STATE_T handleHeatDisinfectEvacR2State( void ) { INTERNAL_HEAT_DISINFECT_STATE_T state = INTERNAL_HEAT_DISINFECT_STATE_EVACUATE_R2; F32 reservoir2Weight = getLoadCellFilteredWeight ( LOAD_CELL_B1 ); if ( reservoir2Weight <= EMPTY_RESERVOIRS_WEIGHT_GRAMS ) { if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_EVACUATE_DIALYSATE_FILL_WITH_WATER ) { setActuatorsToFillWater(); state = INTERNAL_HEAT_DISINFECT_STATE_FILL_WITH_WATER; } else if ( heatDisinfectState == DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER_DEPRIME_RESERVOIRS || heatDisinfectState == DG_HEAT_DISINFECT_STATE_DISINFECT_DRAIN_PATH ) { state = INTERNAL_HEAT_DISINFECT_STATE_COMPLETE; } } return state; } /*********************************************************************//** * @brief * The stopActuators function sets all the actuators in stop and \n * de-energized state * @details * Inputs: none * Outputs: none * @return none *************************************************************************/ static void resetActuators( void ) { // De-energize all the valves setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); //TODO composition pumps signalROPumpHardStop(); signalDrainPumpHardStop(); stopPrimaryHeater(); stopTrimmerHeater(); } /*********************************************************************//** * @brief * The isTemperatureInRange function checks whether the water temperature \n * is out of range * @details * Inputs: none * Outputs: none * @return TRUE if the water temperature is still in range *************************************************************************/ static BOOL isTemperatureInRange( void ) { BOOL result = FALSE; F32 TPi = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); F32 TDi = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); if ( fabs(TPi - HEAT_DISINFECT_TARGET_TEMPERATURE) <= MAX_TEMPERATURE_DEVIATION_FROM_TARGET && fabs(TDi - HEAT_DISINFECT_TARGET_TEMPERATURE) <= MAX_TEMPERATURE_DEVIATION_FROM_TARGET ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The setActuatorsToFillWater function sets the actuators to fill with \n * water mode * @details * Inputs: none * Outputs: none * @return none *************************************************************************/ static void setActuatorsToFillWater( void ) { signalDrainPumpHardStop(); setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VBF, VALVE_STATE_CLOSED ); setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_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 ); setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setROPumpTargetFlowRate( RO_PUMP_TARGET_FILL_FLOW_RATE_LPM, RO_PUMP_TARGET_FILL_MAX_PRESSURE ); } /*********************************************************************//** * @brief * The getPublishHeatDisinfectDataInterval function sets the data publish \n * interval * @details * Inputs: heatDisinfectDataPublishInterval * Outputs: none * @return result : data publish time interval *************************************************************************/ static U32 getPublishHeatDisinfectDataInterval( void ) { U32 result = heatDisinfectDataPublishInterval.data; if ( OVERRIDE_KEY == heatDisinfectDataPublishInterval.override ) { result = heatDisinfectDataPublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The publishHeatDisinfectData function publishes heat disinfect mode * @details * Inputs: heatDisinfectPublishCounter, heatDisinfectCurrentCycle, * heatDisinfectInternalState * Outputs: heatDisinfectPublishCounter * @return none *************************************************************************/ static void publishHeatDisinfectData ( void ) { if ( ++heatDisinfectPublishCounter >= getPublishHeatDisinfectDataInterval() ) { DG_HEAT_DISINFECT_DATA_T data; data.currentCycle = heatDisinfectCurrentCycle; data.elapsedTimeMins = calcTimeSince( heatDisinfectStartTime ) / MINUTE_TO_MS_CONVERSION;; data.internalState = (U32)heatDisinfectInternalState; broadcastHeatDisinfectData( &data ); heatDisinfectPublishCounter = 0; } } /*********************************************************************//** * @brief * The testSetHeatDisinfectDataPublishIntervalOverride function overrides \n * the data publication interval * @details * Inputs: heatDisinfectDataPublishInterval * Outputs: heatDisinfectDataPublishInterval * @param: value : The requested value for override * @return: result : TRUE if override was successful *************************************************************************/ BOOL testSetHeatDisinfectDataPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_GENERAL_INTERVAL; result = TRUE; heatDisinfectDataPublishInterval.ovData = intvl; heatDisinfectDataPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetHeatDisinfectDataPublishIntervalOverride function \n * resets the overridden data publication time interval * @details * Inputs: heatDisinfectDataPublishInterval * Outputs: heatDisinfectDataPublishInterval * @return: result : TRUE if reset was successful *************************************************************************/ BOOL testResetHeatDisinfectDataPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectDataPublishInterval.override = OVERRIDE_RESET; heatDisinfectDataPublishInterval.ovData = heatDisinfectDataPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetHeatDisinfectRecircDurationOverride function overrides the \n * duration of the recirculation path heat disinfection in minutes * @details * Inputs: heatDisinfectRecircDuration * Outputs: heatDisinfectRecircDuration * @param: recircMins : recirculation duration in minutes * @return: result : TRUE if override was successful *************************************************************************/ BOOL testSetHeatDisinfectRecircDurationOverride( F32 recircMins ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { heatDisinfectRecircDuration.ovInitData = heatDisinfectRecircDuration.data; heatDisinfectRecircDuration.ovData = recircMins * MINUTE_TO_MS_CONVERSION; heatDisinfectRecircDuration.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetHeatDisinfectRecircDurationOverride function resets the \n * overridden duration of recirculation path heat disinfection * @details * Inputs: heatDisinfectRecircDuration * Outputs: heatDisinfectRecircDuration * @return: result : TRUE if reset was successful *************************************************************************/ BOOL testResetHeatDisinfectRecircDurationOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectRecircDuration.ovData = heatDisinfectRecircDuration.ovInitData; heatDisinfectRecircDuration.override = OVERRIDE_RESET; } return result; } /*********************************************************************//** * @brief * The testSetHeatDisinfectR1ToR2DurationOverride function overrides\n * the duration of reservoir 1 to reservoir 2 heat disinfection in minutes * @details * Inputs: heatDisinfectR1ToR2Duration * Outputs: heatDisinfectR1ToR2Duration * @param: R1ToR2Mins : reservoir 1 to reservoir 2 duration in minutes * @return: result : TRUE if override was successful *************************************************************************/ BOOL testSetHeatDisinfectR1ToR2DurationOverride( F32 R1ToR2Mins ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectR1ToR2Duration.ovInitData = heatDisinfectR1ToR2Duration.data; heatDisinfectR1ToR2Duration.ovData = R1ToR2Mins * MINUTE_TO_MS_CONVERSION; heatDisinfectR1ToR2Duration.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetHeatDisinfectR1ToR2DurationOverride function \n * resets the overridden reservoir 1 to reservoir 2 duration * @details * Inputs: heatDisinfectR1ToR2Duration * Outputs: heatDisinfectR1ToR2Duration * @return: result : TRUE if reset was successful *************************************************************************/ BOOL testResetHeatDisinfectR1ToR2DurationOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectR1ToR2Duration.ovData = heatDisinfectR1ToR2Duration.ovInitData; heatDisinfectR1ToR2Duration.override = OVERRIDE_RESET; } return result; } /*********************************************************************//** * @brief * The testSetHeatDisinfectionR2ToR1DurationOverride function overrides \n * the duration of reservoir 2 to reservoir 1 heat disinfection in minutes * Inputs: heatDisinfectR2ToR1Duration * Outputs: heatDisinfectR2ToR1Duration * @param: R2ToR1Mins : reservoir 2 to reservoir 1 duration in minutes * @return: result : TRUE is override was successful *************************************************************************/ BOOL testSetHeatDisinfectionR2ToR1DurationOverride( F32 R2ToR1Mins ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectR2ToR1Duration.ovInitData = heatDisinfectR2ToR1Duration.data; heatDisinfectR2ToR1Duration.ovData = R2ToR1Mins * MINUTE_TO_MS_CONVERSION; heatDisinfectR2ToR1Duration.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetHeatDisinfectionR2ToR1DurationOverride function \n * resets the overridden reservoir 2 to reservoir 1 duration * @details * Inputs : heatDisinfectR2ToR1Duration * Outputs : heatDisinfectR2ToR1Duration * @return result : TRUE if reset was successful *************************************************************************/ BOOL testResetHeatDisinfectionR2ToR1DurationOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectR2ToR1Duration.ovData = heatDisinfectR2ToR1Duration.ovInitData; heatDisinfectR2ToR1Duration.override = OVERRIDE_RESET; } return result; } /*********************************************************************//** * @brief * The testSetHeatDisinfectNoOfCyclesOverride function overrides the \n * number of cycles to run during heat disinfection * @details * Inputs: heatDisinfectNoOfCyclesToRun * Outputs: heatDisinfectNoOfCyclesToRun * @param: cycles : number of cycles to run heat disinfection * @return: result : TRUE if override was successful *************************************************************************/ BOOL testSetHeatDisinfectNoOfCyclesOverride( U32 cycles ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectNoOfCyclesToRun.ovInitData = heatDisinfectNoOfCyclesToRun.data; heatDisinfectNoOfCyclesToRun.ovData = cycles; heatDisinfectNoOfCyclesToRun.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetHeatDisinfectNoOfCyclesOverride function \n * resets the cycles to run heat disinfection * @details * Inputs: heatDisinfectNoOfCyclesToRun * Outputs: heatDisinfectNoOfCyclesToRun * @return: result : TRUE if reset was successful *************************************************************************/ BOOL testResetHeatDisinfectNoOfCyclesOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; heatDisinfectNoOfCyclesToRun.ovData = heatDisinfectNoOfCyclesToRun.ovInitData; heatDisinfectNoOfCyclesToRun.override = OVERRIDE_RESET; } return result; } /*********************************************************************//** * @brief * The getRecirculationDuration function gets the duration of recirculation \n * path heat disinfection * @details * Inputs: heatDisinfectRecircDuration * Outputs: none * @return: result : the duration in minutes *************************************************************************/ static F32 getRecirculationDuration( void ) { F32 result = heatDisinfectRecircDuration.data; if ( OVERRIDE_KEY == heatDisinfectRecircDuration.override ) { result = heatDisinfectRecircDuration.ovData; } return result; } /*********************************************************************//** * @brief * The getRSVR1ToRSVR2Duration function gets the duration of reservoir 1 \n * to reservoir 2 heat disinfection * @details * Inputs: heatDisinfectR1ToR2Duration * Outputs: none * @return: result : the duration in minutes *************************************************************************/ static F32 getR1ToR2Duration( void ) { F32 result = heatDisinfectR1ToR2Duration.data; if ( OVERRIDE_KEY == heatDisinfectR1ToR2Duration.override ) { result = heatDisinfectR1ToR2Duration.ovData; } return result; } /*********************************************************************//** * @brief * The getRSVR2ToRSVR1Duration function gets the duration of reservoir 2 \n * to reservoir 1 heat disinfection * @details * Inputs: heatDisinfectR2ToR1Duration * Outputs: none * @return: result : the duration in minutes *************************************************************************/ static F32 getR2ToR1Duration() { F32 result = heatDisinfectR2ToR1Duration.data; if ( OVERRIDE_KEY == heatDisinfectR2ToR1Duration.override ) { result = heatDisinfectR2ToR1Duration.ovData; } return result; } /*********************************************************************//** * @brief * The getNoOfCyclesToRun function gets the number of cycles to run \n * heat disinfection * @details * Inputs: heatDisinfectNoOfCyclesToRun * Outputs: none * @return: result : the no of cycles *************************************************************************/ static U32 getNoOfCyclesToRun() { U32 result = heatDisinfectNoOfCyclesToRun.data; if ( OVERRIDE_KEY == heatDisinfectNoOfCyclesToRun.override ) { result = heatDisinfectNoOfCyclesToRun.ovData; } return result; } /**@}*/