Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -r379f78f1fad668d741b3ccf1e78c69f3fccc45b5 -r654c5598765bb862c00a0175bdac95604c6c9b24 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 379f78f1fad668d741b3ccf1e78c69f3fccc45b5) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 654c5598765bb862c00a0175bdac95604c6c9b24) @@ -1382,7 +1382,20 @@ return state; } - +/*********************************************************************//** + * @brief + * The handleChemicalDisinfectRinseR2ToR1AndDrainR1State function handles + * the chemical disinfect rinse R2 to R1 and drain R1 state. The state + * rinses reservoir 2 and drains reservoir 1 at the same time. If the drain + * process times out, it transitions to basic cancellation state, and + * if the rinse times out, it transitions to water cancellation state. + * If the drain and rinse are completed within the define time, it + * transitions to the next state. + * @details Inputs: rsrvr1Status, rsrvr2Status + * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, + * prevChemDisinfectState, alarmDetectedPendingTrigger + * @return next state of the chemical disinfect state machine + *************************************************************************/ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectRinseR2ToR1AndDrainR1State( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_RINSE_R2_TO_R1_AND_DRAIN_R1; @@ -1455,8 +1468,6 @@ // Turn on the drain pump to drain R2 setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - // This is the last drain of heat disinfect cycle - isThisLastDrain = TRUE; stateTimer = getMSTimerCount(); // Set the reservoir status rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; @@ -1478,7 +1489,83 @@ } static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectRinseR1ToR2AndDrainR2State( void ) { + DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_RINSE_R1_TO_R2_AND_DRAIN_R2; + if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) + { + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ); + } + else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) + { + // Done with draining R2 + signalDrainPumpHardStop(); +#ifndef V_2_SYSTEM + setValveState( VRD2, VALVE_STATE_CLOSED ); +#endif + } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) + { + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; + } + + // First reservoir 1 must be completely full + if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) + { + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); + + U32 drainPumpRPM = getTargetDrainPumpRPM(); + // Keep monitoring the status of reservoir 2 as the same time + F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already + // reached to target volume, it means reservoir 2's load cell might be reading incorrect values. This situation might continue + // until reservoir 1 is filled up and the tubing might expand or leak. + // Before checking whether reservoir 1 is filled pre-maturely, we have to make sure reservoir 1 is drained completely to make + // sure the extra volume that is read is not because of previous water that is being drained currently and it is above 500 mL + if ( ( volume > RSRVRS_PARTIAL_FILL_VOL_ML ) && ( 0 == drainPumpRPM ) ) + { + prevChemDisinfectState = state; + alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + } + } + // Once reservoir 1 is completely full, monitor reservoir 2 + else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) + { + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); + + if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) + { + // Done with filling, turn off the RO pump + signalROPumpHardStop(); + +#ifndef V_2_SYSTEM + setValveState( VRD2, VALVE_STATE_OPEN ); +#else + setValveState( VRD, VALVE_STATE_R2_C_TO_NO ); +#endif + + // Turn on the drain pump to drain R2 + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + + stateTimer = getMSTimerCount(); + // Set the reservoir status + rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; + state = DG_CHEM_DISINFECT_STATE_RINSE_R1_TO_R2_AND_DRAIN_R2; + } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) + { + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + } + } + else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) + { + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + } + + return state; } static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectRinseCirculationState( void ) {