Index: firmware/App/Modes/ModeChemicalDisinfectFlush.c =================================================================== diff -u -rb8f298547eb578000b3ff3cf55732fda7a689ce0 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Modes/ModeChemicalDisinfectFlush.c (.../ModeChemicalDisinfectFlush.c) (revision b8f298547eb578000b3ff3cf55732fda7a689ce0) +++ firmware/App/Modes/ModeChemicalDisinfectFlush.c (.../ModeChemicalDisinfectFlush.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -52,7 +52,7 @@ // Drain R1 & R2 states defines #define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. #define RSRVRS_INITIAL_FINAL_DRAIN_TIME_OUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. -#define RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. +#define RSRVRS_INITIAL_DRAIN_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines @@ -85,6 +85,7 @@ // Sample flush R1 to R2 drain R2 defines #define SAMPLE_FLUSH_WAIT_TIME_MS ( 2.5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time to wait for sampling flush R1 to R2 drain R2 in milliseconds. +#define SAMPLE_FLUSH_WAIT_STATE_TIMEOUT_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time to wait for sampling flush R1 to R2 drain R2 state waiting for the user to confirm in milliseconds. /// Cancellation paths typedef enum Cancellation_modes @@ -119,6 +120,8 @@ static ALARM_ID_T alarmDetectedPendingTrigger; ///< Chemical disinfect flush alarm to raise. static U32 numberOfPostDisinfectRinses; ///< Number of times to rinse the fluid path after chemical disinfect flush. static DISINFECT_NV_OPS_T disinfectNVOps; ///< Disinfect non-volatile memory operations. +static BOOL hasAlarmBeenTriggered; ///< Boolean flag to indicate that an alarm has been raised. +static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Boolean flag to indicate whether the drain parameters have been reset or not. // ********** private function prototypes ********** @@ -149,11 +152,9 @@ * @details Inputs: none * @details Outputs: chemDisinfectFlushState, stateTimer, isThisLastDrain, * stateTrialCounter, rsrvr1Status, rsrvr2Status, haveInletWaterChecksPassed, - * overallChemDisinfectFlushTimer, + * overallChemDisinfectFlushTimer, hasAlarmBeenTriggered, haveDrainParamsBeenInit * cancellationMode, rsrvrFillToFullStableTimeCounter, prevChemDisinfectFlushState - * numberOfPostDisinfectRinses, - * chemDisinfectFlushUIState, - * disinfectFlushNVOps + * numberOfPostDisinfectRinses, chemDisinfectFlushUIState, disinfectFlushNVOps * @return none *************************************************************************/ void initChemicalDisinfectFlushMode( void ) @@ -164,7 +165,7 @@ isThisLastDrain = FALSE; rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - overallChemDisinfectFlushTimer = 0; + overallChemDisinfectFlushTimer = getMSTimerCount(); cancellationMode = CANCELLATION_MODE_NONE; rsrvrFillToFullStableTimerCounter = 0; numberOfPostDisinfectRinses = 0; @@ -174,6 +175,9 @@ drainTimer = 0; dataPublishCounter = 0; disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; + hasAlarmBeenTriggered = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; } /*********************************************************************//** @@ -192,6 +196,8 @@ setCPLDCleanLEDColor( CPLD_CLEAN_LED_YELLOW ); + activateAlarmNoData( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_REMOVE_ACID ); + return chemDisinfectFlushState; } @@ -330,21 +336,22 @@ *************************************************************************/ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushStartState( void ) { - DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R1; + DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_START; - chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_FLUSH_AFTER_DISINFECT; - overallChemDisinfectFlushTimer = getMSTimerCount(); + chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_FLUSH_AFTER_DISINFECT; - // Close VPi to prevent wasting water - setValveState( VPI, VALVE_STATE_CLOSED ); + if ( FALSE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_REMOVE_ACID ) ) + { + // Close VPi to prevent wasting water + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R1; + } - // Set the actuators to drain R1 - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_OPEN ); - setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - stateTimer = getMSTimerCount(); - return state; } @@ -564,7 +571,7 @@ { rsrvr1Status = DG_RESERVOIR_REACHED_TARGET; } - else if ( TRUE == didTimeout( drainTimer, RSRVRS_FLUSH_DRAIN_TIMEOUT_MS ) ) + else if ( TRUE == didTimeout( drainTimer, RSRVRS_FLUSH_DRAIN_TIMEOUT_MS ) ) { // reservoir 1 drain timeout prevChemDisinfectFlushState = state; @@ -579,7 +586,7 @@ rsrvr2Status = getRsrvrFillToFullStatus( DG_RESERVOIR_2, RSRVRS_FILL_UP_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { - waitTimer = getMSTimerCount(); + waitTimer = getMSTimerCount(); } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { @@ -590,7 +597,7 @@ } // Overflow R2 to R1 for an additional period - if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( TRUE == didTimeout( waitTimer, FLUSH_ADDITIONAL_TIME_MS ) ) ) + if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( TRUE == didTimeout( waitTimer, FLUSH_ADDITIONAL_TIME_MS ) ) ) { // Set the valves to flush R1 to R2 and drain R2 setValveState( VRD2, VALVE_STATE_OPEN ); @@ -651,7 +658,7 @@ if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { - waitTimer = getMSTimerCount(); + waitTimer = getMSTimerCount(); } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { @@ -662,7 +669,7 @@ } // Overflow R2 to R1 for an additional period - if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) && ( TRUE == didTimeout( waitTimer, FLUSH_ADDITIONAL_TIME_MS ) ) ) + if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) && ( TRUE == didTimeout( waitTimer, FLUSH_ADDITIONAL_TIME_MS ) ) ) { if ( ++numberOfPostDisinfectRinses < NUM_OF_RINSE_CYCLES ) { @@ -680,18 +687,7 @@ } else { - // number of rinse cycles complete - // Set the valves to drain R1 - setValveState( VPI, VALVE_STATE_OPEN ); - setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_CLOSED ); - setValveState( VRD2, VALVE_STATE_OPEN ); - setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + // Number of rinse cycles complete stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_FLUSH_STATE_SAMPLE_FLUSH_R1_TO_R2_DRAIN_R2; } @@ -705,22 +701,52 @@ * The handleChemicalDisinfectFlushSampleFlushR1ToR2DrainR2State function * handles the chemical disinfect flush sample flush R1 to R2 and drain R2 * state. - * @details Inputs: stateTimer, TODO fill up - * @details Outputs: TODO fill up + * @details Inputs: stateTimer, hasAlarmBeenTriggered + * @details Outputs: stateTimer, hasAlarmBeenTriggered, rsrvr1Status, + * isThisLastDrain * @return next state of the chemical disinfect flush state machine *************************************************************************/ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushSampleFlushR1ToR2DrainR2State( void ) { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_SAMPLE_FLUSH_R1_TO_R2_DRAIN_R2; - state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R1; // TODO remove once this state is implemented - // TODO add a 30 min timeout if the user did not hit complete and update the SRS + if ( ( TRUE == didTimeout( stateTimer, SAMPLE_FLUSH_WAIT_TIME_MS ) ) && ( FALSE == hasAlarmBeenTriggered ) ) + { + hasAlarmBeenTriggered = TRUE; + activateAlarmNoData( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ); + } - if ( TRUE == didTimeout( stateTimer, SAMPLE_FLUSH_WAIT_TIME_MS ) ) + if ( ( TRUE == hasAlarmBeenTriggered ) && ( FALSE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ) ) ) { - // TODO complete this if statement + signalROPumpHardStop(); + turnOffUVReactor( INLET_UV_REACTOR ); + turnOffUVReactor( OUTLET_UV_REACTOR ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VRD2, VALVE_STATE_CLOSED ); + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); + + isThisLastDrain = TRUE; + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + hasAlarmBeenTriggered = TRUE; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R1; } + if ( TRUE == didTimeout( stateTimer, SAMPLE_FLUSH_WAIT_STATE_TIMEOUT_MS ) ) + { + activateAlarmNoData( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_SAMPLE_TIMEOUT ); + state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; + } + return state; } @@ -781,7 +807,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { // If the cancellation water path cannot be done, got to basic cancellation path - rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ); + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -801,7 +827,7 @@ if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) ) { // If the cancellation water path cannot be done, got to basic cancellation path - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -871,18 +897,26 @@ DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_ABOVE_TARGET; BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); + // If the drain parameters of the reservoir is not initialized, initialize them + if ( FALSE == haveDrainParamsBeenInit[ r ] ) + { + initDrainParameters( r ); + haveDrainParamsBeenInit[ r ] = TRUE; + } + if ( TRUE == isDrainComplete ) { - // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); - status = DG_RESERVOIR_REACHED_TARGET; + stateTimer = getMSTimerCount(); + haveDrainParamsBeenInit[ r ] = FALSE; + status = DG_RESERVOIR_REACHED_TARGET; } else if ( TRUE == didTimeout( stateTimer, timeout ) ) { - // Failed to drain on time. Update the previous chemical disinfect state - prevChemDisinfectFlushState = chemDisinfectFlushState; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + // Failed to drain on time. Update the previous chemical disinfect flush state and transition to basic cancellation + prevChemDisinfectFlushState = chemDisinfectFlushState; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; + haveDrainParamsBeenInit[ r ] = FALSE; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -991,34 +1025,20 @@ *************************************************************************/ static void monitorModeChemicalDisinfectFlush( void ) { - BOOL areInletWaterAlarmsActive = FALSE; - #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif { // If either the dialysate cap or the concentrate cap is open during any state, alarm if ( ( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ) || ( STATE_OPEN == getSwitchStatus( DIALYSATE_CAP ) ) ) { - // Set the variables to fail and go to cancel water path. Set the pending alarm to no alarm so the cancel water path - // will not be raising the alarm at end of the cancel water path. The recoverable alarm is raised here in this function - U32 ConcCap = (U32)getSwitchStatus( CONCENTRATE_CAP ); - U32 DialysateCap = (U32)getSwitchStatus( DIALYSATE_CAP ); prevChemDisinfectFlushState = chemDisinfectFlushState; chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; } } - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH ); - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_LOW ); - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_HIGH ); - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_LOW ); - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH ); - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW ); - areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE ); - - if ( ( TRUE == areInletWaterAlarmsActive ) ) + if ( ( TRUE == isAnyAlarmActive() ) && ( chemDisinfectFlushState != DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH ) ) { prevChemDisinfectFlushState = chemDisinfectFlushState; chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH;