Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -r19934ca6e36e2dcabd6a6083a9a1f15b1ed32189 -receb190a5d66fdbee779478ac8bb50a846ed9241 --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 19934ca6e36e2dcabd6a6083a9a1f15b1ed32189) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision eceb190a5d66fdbee779478ac8bb50a846ed9241) @@ -7,15 +7,16 @@ * * @file ModeFlush.c * -* @author (last) Bill Bracken -* @date (last) 24-Oct-2022 +* @author (last) Steve Jarpe +* @date (last) 06-Dec-2022 * * @author (original) Leonardo Baloa * @date (original) 20-Dec-2019 * ***************************************************************************/ #include "ConcentratePumps.h" +#include "ConductivitySensors.h" #include "CPLD.h" #include "DrainPump.h" #include "FlowSensors.h" @@ -24,10 +25,12 @@ #include "MessageSupport.h" #include "ModeFault.h" #include "ModeFlush.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" +#include "RTC.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" @@ -64,13 +67,13 @@ #define BICARB_PUMP_SPEED_ML_PER_MIN 30.6F ///< Bicarb pump speed in mL/min. // Flush and drain R1 and R2 state defines -#define RSRVRS_FULL_VOL_ML 1800.0F ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900 +#define RSRVRS_FULL_VOL_ML 1900.0F ///< Reservoirs 1 & 2 full volume in mL. #define RSRVRS_PARTIAL_FILL_VOL_ML 500.0F ///< Reservoirs 1 & 2 partial volume in mL. #define RSRVRS_FULL_STABLE_TIME_COUNT ( ( 4 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in counts. #define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. #define RSRVRS_PARTIAL_FILL_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms. #define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. -#define FINAL_DRAIN_RO_PUMP_FLOW_LPM 0.6F ///< Final drain RO pump flow rate in L/min. This is used to flush the drain line during drain. +#define FINAL_DRAIN_RO_PUMP_FLOW_LPM 0.8F ///< Final drain RO pump flow rate in L/min. This is used to flush the drain line during drain. // Flush drain line state defines #define FLUSH_DRAIN_LINE_VOLUME_L 0.1F ///< Water volume to flush in liters. @@ -98,6 +101,7 @@ static BOOL hasWaterCancellationBeenSet; ///< Water cancellation set/not set boolean flag. static F32 flushLinesVolumeL; ///< Volume of water pumped by RO pump during flush lines state. static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Boolean flag to indicate whether the drain parameters have been reset or not. +static BOOL hasFlushStatusBeenWrittenToNV; ///< Boolean flag to indicate whether the flush status has been written to NV or not. // ********** private function prototypes ********** @@ -121,6 +125,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ); static void publishFlushData( void ); static void monitorModeFlush( void ); +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ); /*********************************************************************//** * @brief @@ -129,7 +134,8 @@ * @details Outputs: flushState, prevFlushState, rsrvrFillStableTimeCounter, * overallFlushElapsedTime, isThisInitialDrain, dataPublishCounter, * rsrvr1Status, rsrvr2Status, hasWaterCancellationBeenSet, - * flushLinesVolumeL, haveDrainParamsBeenInit, stateTimerStart + * flushLinesVolumeL, haveDrainParamsBeenInit, stateTimerStart, + * hasFlushStatusBeenWrittenToNV * @return none *************************************************************************/ void initFlushMode( void ) @@ -145,10 +151,11 @@ rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; hasWaterCancellationBeenSet = FALSE; - flushLinesVolumeL = 0.0; + flushLinesVolumeL = 0.0F; haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; stateTimerStart = 0; + hasFlushStatusBeenWrittenToNV = FALSE; } /*********************************************************************//** @@ -161,7 +168,7 @@ U32 transitionToFlushMode( void ) { // Reset all the actuators - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); initFlushMode(); @@ -179,6 +186,16 @@ *************************************************************************/ U32 execFlushMode( void ) { + checkInletWaterTemperature(); + + if ( flushState != DG_FLUSH_STATE_FLUSH_DRAIN ) + { + // Do not check on the inlet water temperature and conductivity until the inlet filters have been flushed + // The initial states are drain reservoirs but in those states VPi is closed so these alarms are not checked + checkInletWaterConductivity(); + checkInletWaterPressure(); + } + monitorModeFlush(); // Execute current flush state @@ -281,7 +298,7 @@ if ( DG_MODE_FLUS == getCurrentOperationMode() ) { // Reset all the actuators - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); // Transition to mode standby requestNewOperationMode( DG_MODE_STAN ); @@ -369,7 +386,7 @@ } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -407,6 +424,7 @@ setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + turnOnUVReactor( INLET_UV_REACTOR ); state = DG_FLUSH_STATE_FLUSH_DRAIN; } @@ -426,14 +444,14 @@ turnOnUVReactor( OUTLET_UV_REACTOR ); flushUIState = FLUSH_UI_STATE_FLUSH_RECIRCULATION_PATH; - state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE; + state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE; } stateTimerStart = getMSTimerCount(); } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -461,8 +479,7 @@ turnOnUVReactor( OUTLET_UV_REACTOR ); stateTimerStart = getMSTimerCount(); - - state = DG_FLUSH_STATE_FLUSH_DIALYSATE; + state = DG_FLUSH_STATE_FLUSH_DIALYSATE; } return state; @@ -481,6 +498,8 @@ { DG_FLUSH_STATE_T state = DG_FLUSH_STATE_FLUSH_DIALYSATE; + writeDisinfectDataToNV( USAGE_INFO_FILTER_FLUSH ); + if ( TRUE == didTimeout( stateTimerStart, FLUSH_DIALYSATE_WAIT_TIME_MS ) ) { // Turn the pumps on in reverse @@ -491,7 +510,10 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - stateTimerStart = getMSTimerCount(); + // Set the timer for the next state + // Set the NV data flag to FALSE since it should be ready for another write while the mode is running + stateTimerStart = getMSTimerCount(); + hasFlushStatusBeenWrittenToNV = FALSE; state = DG_FLUSH_STATE_FLUSH_CONCENTRATE_STRAWS; } @@ -515,8 +537,8 @@ if ( TRUE == didTimeout( stateTimerStart, FLUSH_CONCENTRATE_STRAWS_TIME_MS ) ) { // Done with flushing the concentrate pumps line - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); @@ -633,7 +655,7 @@ // Reservoir 1 drain time out else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } // First reservoir 2 must be completely full but if reservoir 1 is filled before reservoir 2 is full, alarm @@ -716,8 +738,10 @@ { DG_FLUSH_STATE_T state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE; + writeDisinfectDataToNV( USAGE_INFO_FILTER_FLUSH ); + F32 waterFlowRate = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); - F32 waterVolume = ( ( waterFlowRate / SEC_PER_MIN ) / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); + F32 waterVolume = ( ( waterFlowRate / SEC_PER_MIN ) / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); // Integrate volume of water moved through line flushLinesVolumeL += waterVolume; @@ -733,14 +757,12 @@ setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLOW_RATE_LPM, RO_PUMP_MAX_PRESSURE_PSI ); stateTimerStart = getMSTimerCount(); - - state = DG_FLUSH_STATE_FLUSH_CIRCULATION; + state = DG_FLUSH_STATE_FLUSH_CIRCULATION; } else if ( TRUE == didTimeout( stateTimerStart, FLUSH_DRAIN_LINE_TIMEOUT_MS ) ) { alarmDetectedPendingTrigger = ALARM_ID_DG_DRAIN_CIRCULATION_LINE_TIMEOUT; - // Could not reach to the defined drain line on time - state = DG_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -766,8 +788,7 @@ setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); stateTimerStart = getMSTimerCount(); - - state = DG_FLUSH_STATE_FLUSH_WITH_FRESH_WATER; + state = DG_FLUSH_STATE_FLUSH_WITH_FRESH_WATER; } return state; @@ -779,7 +800,7 @@ * flush with fresh water state. It runs the circulation state with fresh * water for the defined period of time. * @details Inputs: stateTimerStart - * @details Outputs: none + * @details Outputs: flushUIState * @return next state of the flush state machine *************************************************************************/ static DG_FLUSH_STATE_T handleFlushModeFlushWithFreshWaterState( void ) @@ -788,9 +809,9 @@ if ( TRUE == didTimeout( stateTimerStart, FLUSH_WITH_FRESH_WATER_WAIT_TIME_MS ) ) { - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); flushUIState = FLUSH_UI_STATE_COMPLETE; - state = DG_FLUSH_STATE_COMPLETE; + state = DG_FLUSH_STATE_COMPLETE; } return state; @@ -836,7 +857,7 @@ if ( FALSE == hasWaterCancellationBeenSet ) { // Stop all the actuators first then decide who should run next - deenergizeActuators(); + deenergizeActuators( NO_PARK_CONC_PUMPS ); // Set the actuators setValveState( VPI, VALVE_STATE_CLOSED ); @@ -913,20 +934,25 @@ DG_FLUSH_STATE_T state = DG_FLUSH_STATE_COMPLETE; stopDGFlush(); + writeDisinfectDataToNV( USAGE_INFO_BASIC_FLUSH ); return state; } /*********************************************************************//** * @brief * The failFlushMode function sets the alarm that failed the flush mode. - * @details Inputs: alarm, prevHeatDisinfectState + * @details Inputs: alarmDetectedPendingTrigger, prevFlushState * @details Outputs: none * @return none *************************************************************************/ static void failFlushMode( void ) { - SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevFlushState ) + if ( alarmDetectedPendingTrigger != ALARM_ID_NO_ALARM ) + { + SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevFlushState ) + } + requestNewOperationMode( DG_MODE_FAUL ); } /*********************************************************************//** @@ -1082,6 +1108,8 @@ *************************************************************************/ static void monitorModeFlush( void ) { + BOOL areInletWaterAlarmsActive = FALSE; + #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -1096,6 +1124,35 @@ 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 ); + + if ( ( TRUE == areInletWaterAlarmsActive ) ) + { + prevFlushState = flushState; + flushState = DG_FLUSH_STATE_CANCEL_WATER_PATH; + } } +/*********************************************************************//** + * @brief + * The writeDisinfectDataToNV function writes the disinfection data to the + * non-volatile memory. + * @details Inputs: hasFlushStatusBeenWrittenToNV + * @details Outputs: hasFlushStatusBeenWrittenToNV + * @return: none + *************************************************************************/ +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ) +{ + if ( FALSE == hasFlushStatusBeenWrittenToNV ) + { + hasFlushStatusBeenWrittenToNV = setLastDisinfectDate( info, getRTCTimestamp() ); + } +} + /**@}*/