Index: firmware/.launches/DG.launch =================================================================== diff -u -r28b5f2e7f757647145a82a39aca0a5f3652c68a1 -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/.launches/DG.launch (.../DG.launch) (revision 28b5f2e7f757647145a82a39aca0a5f3652c68a1) +++ firmware/.launches/DG.launch (.../DG.launch) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -1,10 +1,22 @@ + + + + + + + + + + + + Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r7017f6bd576659eabecd1723214df888b80e47ac -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 7017f6bd576659eabecd1723214df888b80e47ac) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -111,6 +111,10 @@ static BOOL hasClosedLoopBeenRequested = FALSE; ///< Closed loop pump control flag. static U32 currentDrainPumpRPM = 0; ///< Current drain pump RPM from feedback. +static DRAIN_PUMP_STATE_T pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; ///< Delayed (pending) drain pump command. +static F32 pendingDrainPumpCmdTarget = 0.0; ///< Delayed (pending) drain pump command target (rpm or PSI depending on command). +static U32 pendingDrainPumpCmdCountDown = 0; ///< Delayed (pending) drain pump command count down timer (in task intervals). + /* TODO These variables are used for POST. POST will be implemented later static DRAIN_PUMP_SELF_TEST_STATE_T drainPumpSelfTestState = DRAIN_PUMP_SELF_TEST_STATE_START; ///< Current drain pump self test state. static U32 drainPumpSelfTestTimerCount = 0; ///< Timer counter for drain pump self test. @@ -187,8 +191,38 @@ /*********************************************************************//** * @brief - * The setDrainPumpTargetOutletPressure function sets the target drain pump - * outlet pressure. + * The setDrainPumpTargetRPMDelayed function sets a new target RPM for the + * drain pump with delayed start. + * @details Inputs: drainPumpDAC, targetDrainPumpSpeed, drainPumpControlMode, + * drainPumpControlModeSet + * @details Outputs: pendingDrainPumpCmd, pendingDrainPumpCmdTarget, pendingDrainPumpCmdCountDown + * @param rpm new drain pump target RPM + * @param delayMs delay duration (in ms) before drain pump started + * @return TRUE if new target RPM is set, FALSE if not + *************************************************************************/ +BOOL setDrainPumpTargetRPMDelayed( U32 rpm, U32 delayMs ) +{ + BOOL result = FALSE; + + if ( ( 0 == rpm ) || ( ( rpm >= MIN_DRAIN_PUMP_RPM ) && ( rpm <= MAX_DRAIN_PUMP_RPM ) ) ) + { + pendingDrainPumpCmd = DRAIN_PUMP_OPEN_LOOP_STATE; + pendingDrainPumpCmdTarget = (F32)rpm; + pendingDrainPumpCmdCountDown = delayMs / TASK_GENERAL_INTERVAL; + result = TRUE; + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_INVALID_RPM_SELECTED, rpm ) + } + + return result; +} + +/*********************************************************************//** + * @brief + * The setDrainPumpTargetOutletPressure function sets the drain pump to start + * with given target PDr pressure. * @details Inputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet * @details Outputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, @@ -221,6 +255,38 @@ /*********************************************************************//** * @brief + * The setDrainPumpTargetOutletPressureDelayed function sets the drain pump + * to start with given target PDr pressure after given delay. + * @details Inputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, + * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet + * @details Outputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, + * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet + * @param pressure new target drain pump outlet pressure + * @param delayMS delay duration (in ms) before drain pump started + * @return TRUE if new target speed is set, FALSE if not + *************************************************************************/ +BOOL setDrainPumpTargetOutletPressureDelayed( F32 pressure, U32 delayMs ) +{ + BOOL result = FALSE; + + // Check the delta pressure is in range + if ( ( pressure >= MIN_ALLOWED_TARGET_OUTLET_PRESSURE ) && ( pressure <= MAX_ALLOWED_TARGET_OUTLET_PRESSURE ) ) + { + pendingDrainPumpCmd = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; + pendingDrainPumpCmdTarget = pressure; + pendingDrainPumpCmdCountDown = delayMs / TASK_GENERAL_INTERVAL; + result = TRUE; + } + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_INVALID_DELTA_PRESSURE_SELECTED, pressure ) + } + + return result; +} + +/*********************************************************************//** + * @brief * The signalDrainPumpHardStop function stops the Drain pump immediately. * @details Inputs: targetDrainPumpSpeed, drainPumpState, drainPumpControlMode, * hasClosedLoopBeenRequested, drainControlTimerCounter @@ -310,6 +376,33 @@ *************************************************************************/ void execDrainPumpController( void ) { + // Handle pending drain pump command + if ( pendingDrainPumpCmdCountDown > 0 ) + { + pendingDrainPumpCmdCountDown--; + if ( 0 == pendingDrainPumpCmdCountDown ) + { + if ( DRAIN_PUMP_CONTROL_TO_TARGET_STATE == pendingDrainPumpCmd ) + { + targetDrainPumpOutletPressure = pendingDrainPumpCmdTarget; + hasClosedLoopBeenRequested = TRUE; + drainPumpDAC = DRAIN_PUMP_MIN_DAC; + drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + drainPumpControlModeSet = drainPumpControlMode; + } + else if ( DRAIN_PUMP_OPEN_LOOP_STATE == pendingDrainPumpCmd ) + { + drainPumpDAC = (U32)(pendingDrainPumpCmdTarget * DRP_SPEED_RPM_TO_ADC_FACTOR + FLOAT_TO_INT_ROUNDUP_OFFSET); + targetDrainPumpRPM = (U32)pendingDrainPumpCmdTarget; + drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; + drainPumpControlModeSet = drainPumpControlMode; + } + pendingDrainPumpCmdTarget = 0.0; + pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; + } + } + + // Execute drain pump state machine switch ( drainPumpState ) { case DRAIN_PUMP_OFF_STATE: @@ -377,6 +470,18 @@ /*********************************************************************//** * @brief + * The isDrainPumpOn function determines whether the drain pump is on. + * @details Inputs: drainPumpDACSet + * @details Outputs: none + * @return TRUE if drain pump is on, FALSE if not. + *************************************************************************/ +BOOL isDrainPumpOn( void ) +{ + return ( drainPumpDACSet > 0 ? TRUE : FALSE ); +} + +/*********************************************************************//** + * @brief * The handleDrainPumpOffState function handles the drain pump off state of * the drain pump controller state machine. * @details Inputs: drainPumpControlModeSet, drainPumpDACSet, drainPumpDAC @@ -390,7 +495,7 @@ // If the target drain pump speed was not 0 and the control mode // is open loop, set the drain pump to open loop - if ( getTargetDrainPumpRPM() > 0 && drainPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) + if ( ( getTargetDrainPumpRPM() > 0 ) && ( drainPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) ) { // Set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); @@ -403,7 +508,7 @@ } // If the drain pump is set to closed loop, call the proper state // It is checked for the value of delta pressure because it can be anything including 0 - else if ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP && hasClosedLoopBeenRequested ) + else if ( ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP ) && ( hasClosedLoopBeenRequested ) ) { // set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); Index: firmware/App/Controllers/ROPump.c =================================================================== diff -u -r1a7b3fdc8c9b47ae713a7ec37670a96df7d73818 -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 1a7b3fdc8c9b47ae713a7ec37670a96df7d73818) +++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -114,6 +114,10 @@ static PUMP_CONTROL_MODE_T roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Requested RO pump control mode. static PUMP_CONTROL_MODE_T roPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; ///< Currently set RO pump control mode. TODO do we need this? +static F32 pendingROPumpCmdMaxPressure = 0.0; ///< Delayed (pending) RO pump max pressure (in PSI) setting. +static F32 pendingROPumpCmdTargetFlow = 0.0; ///< Delayed (pending) RO pump target flow rate (in mL/min) setting. +static U32 pendingROPumpCmdCountDown = 0; ///< Delayed (pending) RO pump command count down timer (in task intervals). + static F32 targetROPumpFlowRate = 0.0; ///< Target RO flow rate (in L/min). static F32 targetROPumpMaxPressure = 0.0; ///< Target RO max allowed pressure (in PSI). @@ -249,6 +253,49 @@ /*********************************************************************//** * @brief + * The setROPumpTargetFlowRateDelayed function sets a new target flow rate for the + * RO pump to be set after given delay. + * @details Inputs: none + * @details Outputs: pendingROPumpCmdMaxPressure, pendingROPumpCmdTargetFlow, + * pendingROPumpCmdCountDown + * @param roFlowRate which is target RO flow rate + * @param maxPressure which is the maximum allowed pressure that the RO pump + * can reach + * @param delayMs delay duration (in ms) before RO pump started + * @return TRUE if new target flow rate is set successfully, FALSE if not + *************************************************************************/ +BOOL setROPumpTargetFlowRateDelayed( F32 roFlowRate, U32 maxPressure, U32 delayMs ) +{ + BOOL result = FALSE; + + // First of all, the flow rate must be in range + if ( ( roFlowRate <= MAX_RO_FLOWRATE_LPM ) && ( roFlowRate >= MIN_RO_FLOWRATE_LPM ) ) + { + // Then the max pressure that we are allowed to reach must be in range + if ( ( maxPressure >= MIN_ALLOWED_PRESSURE_PSI ) && ( maxPressure <= MAX_ALLOWED_PRESSURE_PSI ) ) + { + pendingROPumpCmdMaxPressure = (F32)maxPressure; + pendingROPumpCmdTargetFlow = roFlowRate; + pendingROPumpCmdCountDown = delayMs / TASK_GENERAL_INTERVAL; + result = TRUE; + } + // Requested max pressure is out of range + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET, maxPressure ) + } + } + // Requested flow rate is out of range + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_RO_PUMP_INVALID_PRESSURE_SELECTED, roFlowRate ) + } + + return result; +} + +/*********************************************************************//** + * @brief * The signalROPumpHardStop function stops the RO pump immediately and * resets all the variables associated with the RO pump run. * @details Inputs: targetROPumpFlowRate, roPumpState, roPumpPWMDutyCyclePct, @@ -362,6 +409,26 @@ *************************************************************************/ void execROPumpController( void ) { + // Handle pending delayed RO pump command + if ( pendingROPumpCmdCountDown > 0 ) + { + pendingROPumpCmdCountDown--; + if ( 0 == pendingROPumpCmdCountDown ) + { + targetROPumpMaxPressure = pendingROPumpCmdMaxPressure; + targetROPumpFlowRate = pendingROPumpCmdTargetFlow; + pendingROPumpCmdMaxPressure = 0.0; + pendingROPumpCmdTargetFlow = 0.0; + roPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + roPumpState = RO_PUMP_RAMP_UP_TO_TARGET_FLOW_STATE; + // Get the initial guess of the duty cycle + roPumpPWMDutyCyclePct = ROP_FLOW_TO_PWM_DC( targetROPumpFlowRate ); + roControlTimerCounter = 0; + isROPumpOn = TRUE; + } + } + + // Execute RO pump control state machine switch ( roPumpState ) { case RO_PUMP_OFF_STATE: @@ -393,13 +460,13 @@ /*********************************************************************//** * @brief - * The isReverseOsmosisPumpOn function returns the on/off status of RO pump. + * The isROPumpRunning function returns the on/off status of RO pump. * @details Inputs: isROPumpOn * @details Outputs: none * @return isROPumpOn the boolean flag that is TRUE if the pump is on and * FALSE if it is off *************************************************************************/ -BOOL isReverseOsmosisPumpOn( void ) +BOOL isROPumpRunning( void ) { return isROPumpOn; } Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r379f78f1fad668d741b3ccf1e78c69f3fccc45b5 -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 379f78f1fad668d741b3ccf1e78c69f3fccc45b5) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -39,7 +39,9 @@ static U32 valvesStatesPublicationTimerCounter = 0; ///< Timer counter used to schedule valve state publication to CAN bus. static U16 commandedValvesStates = ALL_VALVES_DEENERGIZED; ///< Initialize commanded valves states bit field. -static U32 valveStateMismatchCounter = 0; ///< Initialize valve state mismatch counter. +static U32 valveStateMismatchCounter = 0; ///< Initialize valve state mismatch counter. +static U32 pendingValveStateChanges[ NUM_OF_VALVES ]; ///< Delayed (pending) valve state changes. +static U32 pendingValveStateChangeCountDowns[ NUM_OF_VALVES ]; ///< Delayed (pending) valve state change count down timers (in task intervals). static OVERRIDE_U32_T valveStates[ NUM_OF_VALVES ]; ///< Currently commanded valves states. static OVERRIDE_U32_T valvesStatesPublishInterval = { VALVES_STATE_PUB_INTERVAL, VALVES_STATE_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. @@ -69,7 +71,10 @@ valveStates[ i ].data = DEENERGIZED; valveStates[ i ].ovInitData = DEENERGIZED; valveStates[ i ].ovData = DEENERGIZED; - valveStates[ i ].override = OVERRIDE_RESET; + valveStates[ i ].override = OVERRIDE_RESET; + + pendingValveStateChanges[ i ] = DEENERGIZED; + pendingValveStateChangeCountDowns[ i ] = 0; } commandedValvesStates = fromU32ArrayToU16(); setFPGAValveStates( commandedValvesStates ); // initially set all valves to de-energized state via FPGA @@ -85,10 +90,11 @@ * @return none *************************************************************************/ void execValves( void ) -{ +{ + U32 i; U16 readValvesStates = getFPGAValveStates(); // get valves states from FPGA - // verify read back FPGA valve states match last commanded valve states + // Verify read back FPGA valve states match last commanded valve states if ( readValvesStates != commandedValvesStates ) { valveStateMismatchCounter++; // increment valve state mismatch counter by 1 @@ -100,13 +106,27 @@ else { valveStateMismatchCounter = 0; + } + + // Handle pending delayed valve state changes + for ( i = 0; i < NUM_OF_VALVES; i++ ) + { + if ( pendingValveStateChangeCountDowns[ i ] > 0 ) + { + pendingValveStateChangeCountDowns[ i ]--; + if ( 0 == pendingValveStateChangeCountDowns[ i ] ) + { + valveStates[ i ].data = pendingValveStateChanges[ i ]; + pendingValveStateChanges[ i ] = DEENERGIZED; + } + } } - // set valves states (via FPGA) to currently commanded states + // Set valves states (via FPGA) to currently commanded states commandedValvesStates = fromU32ArrayToU16(); setFPGAValveStates( commandedValvesStates ); - // publish valve states on interval + // Publish valve states on interval publishValvesStates(); } @@ -367,7 +387,7 @@ * @brief * The setValveState function sets the valve state for given valve. * @details Inputs: none - * @details Outputs: none + * @details Outputs: valveStates[], pendingValveStateChanges[], pendingValveStateChangeCountDowns[] * @param valveID ID of valve to set state for * @param valveStateName name of valve state to set given valve to * @return TRUE if new valve state is set for given valve ID, FALSE if not. @@ -382,14 +402,55 @@ { valveStates[ valveID ].data = convertValveStateNameToValveState( valveStateName ); result = TRUE; + // If a delayed state change is pending for this valve, cancel it + pendingValveStateChanges[ valveID ] = DEENERGIZED; + pendingValveStateChangeCountDowns[ valveID ] = 0; } } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) } return result; +} + +/*********************************************************************//** + * @brief + * The setValveStateDelayed function sets the valve state for given valve + * after a given delay. + * @details Inputs: pendingValveStateChangeCountDowns[] + * @details Outputs: pendingValveStateChangeCountDowns[], pendingValveStateChangeCountDowns[] + * @param valveID ID of valve to set state for + * @param valveStateName name of valve state to set given valve to + * @param delayMs delay duration (in ms) before actuation + * @return TRUE if new valve state is set for given valve ID, FALSE if not. + *************************************************************************/ +BOOL setValveStateDelayed( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName, U32 delayMs ) +{ + BOOL result = FALSE; // initialize result flag to FALSE + + if ( valveID < NUM_OF_VALVES ) + { + if ( checkValveStateName( valveID, valveStateName ) ) + { + // If a delayed state change is already pending for this valve, execute it now before setting a new delayed state change + if ( pendingValveStateChangeCountDowns[ valveID ] > 0 ) + { + valveStates[ valveID ].data = pendingValveStateChanges[ valveID ]; + } + // Set delayed valve state change + pendingValveStateChanges[ valveID ] = convertValveStateNameToValveState( valveStateName ); + pendingValveStateChangeCountDowns[ valveID ] = delayMs / TASK_PRIORITY_INTERVAL; + result = TRUE; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) + } + + return result; } /*********************************************************************//** Index: firmware/App/Controllers/Valves.h =================================================================== diff -u -r379f78f1fad668d741b3ccf1e78c69f3fccc45b5 -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Controllers/Valves.h (.../Valves.h) (revision 379f78f1fad668d741b3ccf1e78c69f3fccc45b5) +++ firmware/App/Controllers/Valves.h (.../Valves.h) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -79,6 +79,7 @@ void execValves( void ); BOOL setValveState( VALVES_T valve, VALVE_STATE_NAMES_T valveState ); +BOOL setValveStateDelayed( VALVES_T valve, VALVE_STATE_NAMES_T valveState, U32 delayMs ); U32 getValveState( U32 valveID ); BOOL testSetValvesStatesPublishIntervalOverride( U32 value ); Index: firmware/App/DGCommon.h =================================================================== diff -u -rebbb1f85550a1f9b8f946655f7b2b63f76fbf67d -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/DGCommon.h (.../DGCommon.h) (revision ebbb1f85550a1f9b8f946655f7b2b63f76fbf67d) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -25,7 +25,7 @@ #define DG_VERSION_MAJOR 0 #define DG_VERSION_MINOR 5 #define DG_VERSION_MICRO 0 -#define DG_VERSION_BUILD 15 +#define DG_VERSION_BUILD 4 // ********** build switches ********** @@ -48,12 +48,17 @@ #define DISABLE_DIALYSATE_CHECK 1 #define IGNORE_DRAIN_PUMP_MONITOR 1 #define IGNORE_HEATERS_MONITOR 1 -// #define IGNORE_RO_PUMP_MONITOR 1 - #define IGNORE_HEAT_DISINFECT_RSRVR_TIMEOUT 1 + #define IGNORE_RO_PUMP_MONITOR 1 + #define IGNORE_DISINFECT_RSRVR_TIMEOUT 1 #define DISABLE_RO_RATIO_CHECK 1 #define DISABLE_COND_SENSOR_CHECK 1 #define DISABLE_MIXING 1 #define DISABLE_WATER_QUALITY_CHECK 1 + #define DISABLE_RTC_CONFIG 1 +// #define V_2_SYSTEM 1 +// #define SKIP_RECIRC 1 + #define DISABLE_UV_REACTOR_MONITOR 1 + #include #include #endif Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -rebd43ef11d75ff69de2eda6aec1142858bc1237e -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision ebd43ef11d75ff69de2eda6aec1142858bc1237e) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -39,6 +39,9 @@ #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define TARGET_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. +#define DELAY_RES_DRAIN_VALVE_MS 1000 ///< Delay reservoir drain valve open by 1 second. +#define DELAY_DRAIN_PUMP_MS 2000 ///< Delay drain pump on by 2 seconds. + // ********** private data ********** static DG_DRAIN_STATE_T drainState = DG_DRAIN_STATE_START; ///< Currently active drain state. @@ -76,18 +79,16 @@ if ( DG_RESERVOIR_1 == inactiveReservoir ) { - setValveState( VRD1, VALVE_STATE_OPEN ); + setValveStateDelayed( VRD1, VALVE_STATE_OPEN, DELAY_RES_DRAIN_VALVE_MS ); } else if ( DG_RESERVOIR_2 == inactiveReservoir ) { - setValveState( VRD2, VALVE_STATE_OPEN ); + setValveStateDelayed( VRD2, VALVE_STATE_OPEN, DELAY_RES_DRAIN_VALVE_MS ); } #endif - // set initial actuator states setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - - setDrainPumpTargetRPM( TARGET_DRAIN_PUMP_RPM ); + setDrainPumpTargetRPMDelayed( TARGET_DRAIN_PUMP_RPM, DELAY_DRAIN_PUMP_MS ); setROPumpTargetFlowRate( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); } @@ -110,7 +111,10 @@ switch ( drainState ) { case DG_DRAIN_STATE_START: - drainState = DG_DRAIN_STATE_DRAIN; + if ( TRUE == isDrainPumpOn() ) + { + drainState = DG_DRAIN_STATE_DRAIN; + } break; case DG_DRAIN_STATE_DRAIN: Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r379f78f1fad668d741b3ccf1e78c69f3fccc45b5 -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 379f78f1fad668d741b3ccf1e78c69f3fccc45b5) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -1295,6 +1295,9 @@ if ( ( TRUE == didTimeout( stateTimer, DRAIN_PUMP_START_TIME_IN_MIX_DRAIN_MS ) ) && ( isDrainPumpInMixDrainOn == FALSE ) ) { isDrainPumpInMixDrainOn = TRUE; +#ifndef V_2_SYSTEM + setValveState( VRD1, VALVE_STATE_OPEN ); +#endif #ifndef V_2_SYSTEM setValveState( VRD1, VALVE_STATE_OPEN ); @@ -1483,7 +1486,7 @@ // Done with draining R1 signalDrainPumpHardStop(); #ifndef V_2_SYSTEM - setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD1, VALVE_STATE_CLOSED ); #endif } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r847478dd75aac2edfe27df454ac5a644b6f30040 -r7ae6d3a29de6f544da89b10ce8041861a310f2a5 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 847478dd75aac2edfe27df454ac5a644b6f30040) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 7ae6d3a29de6f544da89b10ce8041861a310f2a5) @@ -19,6 +19,7 @@ #include "CPLD.h" #include "DrainPump.h" #include "Heaters.h" +#include "ModeFault.h" #include "ModeStandby.h" #include "OperationModes.h" #include "Reservoirs.h" @@ -94,6 +95,8 @@ // re-initialize standby mode each time we transition to standby mode initStandbyMode(); + //deenergizeActuators(); + // set initial actuator states setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); @@ -187,7 +190,7 @@ filterFlushStartTime = getMSTimerCount(); setValveState( VPI, VALVE_STATE_OPEN ); #ifndef V_2_SYSTEM - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); #else setValveState( VPD, VALVE_STATE_OPEN ); // TODO: VPD drain state is closed for V3 #endif @@ -216,6 +219,7 @@ if ( TRUE == didTimeout( filterFlushStartTime, FILTER_FLUSH_TIME_MS ) ) { + setValveState( VPI, VALVE_STATE_CLOSED ); state = DG_STANDBY_MODE_STATE_FLUSH_FILTER_IDLE; } @@ -281,6 +285,7 @@ // After HD requests to stop or 10 seconds has elapsed, close and return to idle state if ( ( TRUE == stopSampleWaterRequest ) || ( TRUE == didTimeout( waterSampleStartTime, MAX_WATER_SAMPLE_TIME_MS ) ) ) { + stopSampleWaterRequest = FALSE; setValveState( VSP, VALVE_STATE_CLOSED ); #ifndef V_2_SYSTEM setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); @@ -376,6 +381,29 @@ /*********************************************************************//** * @brief + * The startDGFlush function starts DG flush mode. + * @details Inputs: standbyState + * @details Outputs: none + * @return: TRUE if the switch was successful, otherwise FALSE + *************************************************************************/ +BOOL startDGFlush( void ) +{ + BOOL result = FALSE; + + // If DG is in standby mode or in the solo mode and the standby mode is in Idle state, request DG flush + if ( ( DG_MODE_STAN == getCurrentOperationMode() && DG_STANDBY_MODE_STATE_IDLE == standbyState ) || + DG_MODE_SOLO == getCurrentOperationMode() ) + { + requestNewOperationMode( DG_MODE_FLUS ); + + result = TRUE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The startDGHeatDisinfect function starts heat disinfect mode. * @details Inputs: standbyState * @details Outputs: none @@ -390,7 +418,28 @@ ( DG_MODE_SOLO == getCurrentOperationMode() ) ) { requestNewOperationMode( DG_MODE_HEAT ); + status = TRUE; + } + return status; +} + +/*********************************************************************//** + * @brief + * The startDGChemicalDisinfect function starts chemical disinfect mode. + * @details Inputs: standbyState + * @details Outputs: none + * @return: TRUE if the switch was successful + *************************************************************************/ +BOOL startDGChemicalDisinfect( void ) +{ + BOOL status = FALSE; + + // If DG is in standby mode and the standby mode is in Idle, request chemical disinfect + // Chemical disinfect cannot be run in solo mode because the user has to confirm that the acid is inserted or removed + //if ( ( DG_MODE_STAN == getCurrentOperationMode() ) && ( DG_STANDBY_MODE_STATE_IDLE == standbyState ) ) TODO un-comment this line. This is commented to be able to run chemical without HD for development + { + requestNewOperationMode( DG_MODE_CHEM ); status = TRUE; }