Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -r0fd51747628ba4b6b522fc1b99e068f6bfa402e6 -red6af22b927bc90733d287af520f188c0a5c7177 --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 0fd51747628ba4b6b522fc1b99e068f6bfa402e6) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision ed6af22b927bc90733d287af520f188c0a5c7177) @@ -49,14 +49,15 @@ #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. // Flush drain path state defines -#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo it was 2 minutes +#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. // Flush dialysate state defines #define FLUSH_DIALYSATE_WAIT_TIME_MS ( 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds. // Flush concentrate straws state defines #define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. todo was 3 minutes #define ACID_PUMP_SPEED_ML_PER_MIN -30.0F ///< Acid pump speed in mL/min. + // The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during flush #define BICARB_PUMP_SPEED_ML_PER_MIN 30.6F ///< Bicarb pump speed in mL/min. @@ -84,12 +85,9 @@ static DG_FLUSH_STATE_T flushState; ///< Current active flush state. static DG_FLUSH_STATE_T prevFlushState; ///< Previous flush state. static DG_FLUSH_UI_STATE_T flushUIState; ///< Current UI flush state. -static U32 rsrvrFillStableTimeCounter[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoirs fill stable time counter. +static U32 rsrvrFillStableTimeCounter; ///< Reservoirs fill stable time counter. static U32 overallFlushElapsedTimeStart; ///< Overall flush mode elapsed time start. static U32 stateTimerStart; ///< State timer start. -static U32 rsrvrTimer[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoir fill timers -static bool hasRsrvrTimerBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoir fill timers initialized -static U32 drainTimer; ///< Drain timer static ALARM_ID_T alarmDetectedPendingTrigger; ///< Alarm ID that is detected and is pending to be triggered. static DG_RESERVOIR_STATUS_T rsrvr1Status; ///< Reservoir 1 status. static DG_RESERVOIR_STATUS_T rsrvr2Status; ///< Reservoir 2 status. @@ -117,8 +115,8 @@ static DG_FLUSH_STATE_T handleFlushModeComplete( void ); static void failFlushMode( void ); -static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout, BOOL resetStateTimer ); -static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout, BOOL resetStateTimer ); +static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout ); +static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ); static void publishFlushData( void ); static void monitorModeFlush( void ); @@ -135,21 +133,20 @@ void initFlushMode( void ) { // Initialize the variables - flushState = DG_FLUSH_STATE_START; - prevFlushState = DG_FLUSH_STATE_START; - flushUIState = FLUSH_UI_STATE_NOT_RUNNING; - rsrvrFillStableTimeCounter[ DG_RESERVOIR_1 ] = 0; - rsrvrFillStableTimeCounter[ DG_RESERVOIR_2 ] = 0; - overallFlushElapsedTimeStart = 0; - isThisInitialDrain = TRUE; - dataPublishCounter = 0; - rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; - rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - hasWaterCancellationBeenSet = FALSE; - flushLinesVolumeL = 0.0; - haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; - haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; - stateTimerStart = 0; + flushState = DG_FLUSH_STATE_START; + prevFlushState = DG_FLUSH_STATE_START; + flushUIState = FLUSH_UI_STATE_NOT_RUNNING; + rsrvrFillStableTimeCounter = 0; + overallFlushElapsedTimeStart = 0; + isThisInitialDrain = TRUE; + dataPublishCounter = 0; + rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; + rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; + hasWaterCancellationBeenSet = FALSE; + flushLinesVolumeL = 0.0; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; + stateTimerStart = 0; } /*********************************************************************//** @@ -311,6 +308,7 @@ // Close VPi to prevent wasting water setValveState( VPI, VALVE_STATE_CLOSED ); + // Set the actuators to drain R1 setValveState( VRD1, VALVE_STATE_OPEN ); @@ -320,7 +318,6 @@ setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); flushUIState = FLUSH_UI_STATE_DRAIN_DEVICE; - drainTimer = stateTimerStart = getMSTimerCount(); rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; state = DG_FLUSH_STATE_DRAIN_R1; @@ -343,7 +340,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS, TRUE ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -362,7 +359,6 @@ // Set VPO setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); - drainTimer = stateTimerStart = getMSTimerCount(); rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; state = DG_FLUSH_STATE_DRAIN_R2; @@ -390,7 +386,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { - rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS, TRUE); + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -521,13 +517,8 @@ setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); - stateTimerStart = - rsrvrTimer[ DG_RESERVOIR_1 ] = - rsrvrTimer[ DG_RESERVOIR_2 ] = getMSTimerCount(); + stateTimerStart = getMSTimerCount(); - hasRsrvrTimerBeenInit[ DG_RESERVOIR_1 ] = TRUE; - hasRsrvrTimerBeenInit[ DG_RESERVOIR_2 ] = FALSE; - rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; flushUIState = FLUSH_UI_STATE_FLUSH_RESERVOIRS; @@ -556,10 +547,10 @@ if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, TRUE); + rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); // Keep monitoring the status of reservoir 2 as the same time - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_PARTIAL_FILL_TIMEOUT_MS , TRUE); + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_PARTIAL_FILL_TIMEOUT_MS ); // Reservoir 2 cannot be filled before reservoir 1 is filled and is overflowing to reservoir 2. If reservoir 2 has already // reached to target volume, it means reservoir 1's load cell might be reading incorrect values. This situation might continue // until reservoir 2 is filled up and the tubing might expand or leak. @@ -572,15 +563,9 @@ } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { - // R1 reached target so start R2 fill timer - if (!hasRsrvrTimerBeenInit[ DG_RESERVOIR_2 ]) - { - rsrvrTimer[ DG_RESERVOIR_2 ] = getMSTimerCount(); - hasRsrvrTimerBeenInit[ DG_RESERVOIR_2 ] = false; - } if ( DG_RESERVOIR_BELOW_TARGET == rsrvr2Status ) { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_PARTIAL_FILL_TIMEOUT_MS, TRUE ); + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_PARTIAL_FILL_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -591,10 +576,7 @@ setValveState( VRD1, VALVE_STATE_OPEN ); setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - stateTimerStart = - drainTimer = - rsrvrTimer[ DG_RESERVOIR_1 ] = - rsrvrTimer[ DG_RESERVOIR_2 ] = getMSTimerCount(); + stateTimerStart = getMSTimerCount(); // Set both reservoirs' status rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; @@ -636,7 +618,7 @@ // If reservoir 1 is empty, turn off the drain pump if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS, FALSE); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -653,7 +635,7 @@ // First reservoir 2 must be completely full but if reservoir 1 is filled before reservoir 2 is full, alarm if ( DG_RESERVOIR_BELOW_TARGET == rsrvr2Status ) { - rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS, FALSE); + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); U32 drainPumpRPM = getDrainPumpTargetRPM(); // Keep monitoring the status of reservoir 1 as the same time @@ -673,7 +655,7 @@ // Once reservoir 2 is full, reservoir 1 must be partially full else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { - rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_PARTIAL_FILL_TIMEOUT_MS, TRUE ); + rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_PARTIAL_FILL_TIMEOUT_MS ); // Once R1 is partially full, transition to the next state if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) @@ -694,7 +676,6 @@ // Set VPO setValveState( VPO, VALVE_STATE_FILL_C_TO_NC); - drainTimer = stateTimerStart = getMSTimerCount(); isThisInitialDrain = FALSE; rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; @@ -879,7 +860,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_DRAIN_TIMEOUT_MS, TRUE ); + rsrvr2Status = getRsrvrDrainStatus( DG_RESERVOIR_2, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -896,7 +877,7 @@ if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) ) { // If the cancellation water path cannot be done, go to basic cancellation path - rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS, TRUE ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_DRAIN_TIMEOUT_MS ); if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -906,12 +887,6 @@ // Raise the alarm failFlushMode(); - - // If the caps alarm was active, clear it at the of the cancel water path - if ( TRUE == isAlarmActive( ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION ) ) - { - clearAlarmCondition( ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION ); - } } } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) @@ -963,7 +938,7 @@ * @param timeout is the fill up time out that is checked against * @return the status of the reservoirs during filling *************************************************************************/ -static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout, BOOL resetStateTimer) +static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_BELOW_TARGET; F32 volume = 0.0; @@ -980,20 +955,25 @@ // Check the volume of the reservoir against the target volume if ( volume >= targetVol ) { - if ( ++rsrvrFillStableTimeCounter[ r ] >= RSRVRS_FULL_STABLE_TIME_COUNT ) + if ( ++rsrvrFillStableTimeCounter >= RSRVRS_FULL_STABLE_TIME_COUNT ) { status = DG_RESERVOIR_REACHED_TARGET; - rsrvrFillStableTimeCounter[ r ] = 0; - // Set the reservoir timer in case it needs to be used for another timeout check - rsrvrTimer [ r ] = getMSTimerCount(); -// if (resetStateTimer) -// { -// stateTimerStart = getMSTimerCount(); -// } + rsrvrFillStableTimeCounter = 0; + // Set the state timer in case it needs to be used for another timeout check + if ( ( DG_FLUSH_STATE_FLUSH_R2_AND_DRAIN_R1 == flushState) && ( DG_RESERVOIR_2 == r) ) + { + if ( rsrvr1Status == DG_RESERVOIR_REACHED_TARGET ) + { + stateTimerStart = getMSTimerCount(); + } + } + else + { + stateTimerStart = getMSTimerCount(); + } } } - else if ( (TRUE == didTimeout( rsrvrTimer [ r ], timeout ) ) && hasRsrvrTimerBeenInit[ r] ) -// else if ( TRUE == didTimeout( stateTimerStart, timeout ) ) + else if ( TRUE == didTimeout( stateTimerStart, timeout ) ) { // Failed to fill on time prevFlushState = flushState; @@ -1019,12 +999,12 @@ * then * @return the status of the reservoirs during draining *************************************************************************/ -static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout, BOOL resetStateTimer ) +static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_ABOVE_TARGET; // If the drain parameters of the reservoir is not initialized, initialize them - if ( FALSE == haveDrainParamsBeenInit ) + if ( FALSE == haveDrainParamsBeenInit [ r ] ) { initDrainParameters( r ); haveDrainParamsBeenInit[ r ] = TRUE; @@ -1034,24 +1014,28 @@ if ( TRUE == isDrainComplete ) { - // Set the state timer in case it needs to be used for another timeout check - drainTimer = getMSTimerCount(); -// if (resetStateTimer) -// { -// stateTimerStart = getMSTimerCount(); -// } + if ( ( DG_FLUSH_STATE_FLUSH_R2_AND_DRAIN_R1 == flushState) && ( DG_RESERVOIR_1 == r) ) + { + if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status) && ( 0 == getDrainPumpTargetRPM() ) ) + { + stateTimerStart = getMSTimerCount(); + } + } + else + { + stateTimerStart = getMSTimerCount(); + } haveDrainParamsBeenInit[ r ] = FALSE; - status = DG_RESERVOIR_REACHED_TARGET; + status = DG_RESERVOIR_REACHED_TARGET; } - else if ( TRUE == didTimeout( drainTimer, timeout ) ) -// else if ( TRUE == didTimeout( stateTimerStart, timeout ) ) + else if ( TRUE == didTimeout( stateTimerStart, timeout ) ) { // Failed to drain on time - prevFlushState = flushState; - haveDrainParamsBeenInit[ r ] = FALSE; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + prevFlushState = flushState; + haveDrainParamsBeenInit [ r ] = FALSE; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -1106,7 +1090,7 @@ prevFlushState = flushState; flushState = DG_FLUSH_STATE_CANCEL_WATER_PATH; alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; - } + } } }