Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rc1ef106ed0f97dc998230c6e154aa2362aa476d8 -r28672c1c97532a025a2ca23148760904bde814e5 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision c1ef106ed0f97dc998230c6e154aa2362aa476d8) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 28672c1c97532a025a2ca23148760904bde814e5) @@ -15,88 +15,1281 @@ * ***************************************************************************/ +#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 ********** -static DG_HEAT_DISINFECT_STATE_T heatState = DG_HEAT_DISINFECT_STATE_START; ///< Currently active heat disinfect state. +/// 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 : Initialized heat disinfect mode module + * Inputs: none + * Outputs: none * @return none *************************************************************************/ void initHeatDisinfectMode( void ) { - heatState = DG_HEAT_DISINFECT_STATE_START; + // 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. + * The transitionToHeatDisinfectMode function prepares for transition + * to heat disinfect mode. * @details - * Inputs : none - * Outputs : Prepare for transition to heat disinfect mode + * Inputs: none + * Outputs: none * @return none *************************************************************************/ void transitionToHeatDisinfectMode( void ) { initHeatDisinfectMode(); + resetActuators(); } /*********************************************************************//** * @brief - * The execHeatDisinfectMode function executes the heat disinfect mode state machine. + * The execHeatDisinfectMode function executes the heat disinfect Mode + * state machine. * @details - * Inputs : none - * Outputs : Heat disinfect mode state machine executed - * @return current state + * Inputs: none + * Outputs: none + * @return current state. *************************************************************************/ U32 execHeatDisinfectMode( void ) { - checkInletPressureFault(); + //checkInletPressureFault(); // execute current heat disinfect state - switch ( heatState ) + 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 - heatState = DG_HEAT_DISINFECT_STATE_START; + heatDisinfectState = DG_HEAT_DISINFECT_STATE_COMPLETE; break; } - return heatState; + publishHeatDisinfectData(); + + return (U32)heatDisinfectState; } /*********************************************************************//** * @brief * The getCurrentHeatDisinfectState function returns the current state of the * heat disinfect mode. * @details - * Inputs : heatState - * Outputs : none + * Inputs: heatState + * Outputs: none * @return the current state of heat disinfect mode. *************************************************************************/ DG_HEAT_DISINFECT_STATE_T getCurrentHeatDisinfectState( void ) { - return heatState; + 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; +} + /**@}*/