Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -rb8f298547eb578000b3ff3cf55732fda7a689ce0 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision b8f298547eb578000b3ff3cf55732fda7a689ce0) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -1091,11 +1091,11 @@ #ifndef _RELEASE_ if ( ( HW_CONFIG_BETA == getHardwareConfigStatus() ) && ( getCurrentOperationMode() != DG_MODE_INIT ) ) -#endif { primaryAndCondSensorsRefResistance = PRIMARY_HEATER_EXT_TEMP_SENSORS_V3_REF_RESISTANCE; externalTempSesnorsRefResitance = TRIMMER_HEATER_EXT_TEMP_SENSORS_V3_REF_RESISTANCE; } +#endif tempSensors[ TEMPSENSORS_INLET_PRIMARY_HEATER ].refResistance = primaryAndCondSensorsRefResistance; tempSensors[ TEMPSENSORS_OUTLET_PRIMARY_HEATER ].refResistance = primaryAndCondSensorsRefResistance; Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -rb8f298547eb578000b3ff3cf55732fda7a689ce0 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision b8f298547eb578000b3ff3cf55732fda7a689ce0) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -55,7 +55,7 @@ #define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. #define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. -#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. // Flush drain path state defines #define FLUSH_DRAIN_WAIT_TIME_MS ( 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. @@ -176,6 +176,7 @@ static F32 R2FullVolume; ///< R2 volume determined by fill to full function. static F32 disinfectantMixRatio ; ///< Current disinfectant mixing ratio. static DISINFECT_NV_OPS_T disinfectNVOps; ///< Disinfect non-volatile memory operations. +static BOOL haveDrainParamsBeenInit[ NUM_OF_DG_RESERVOIRS ]; ///< Boolean flag to indicate whether the drain parameters have been reset or not. // ********** private function prototypes ********** @@ -191,9 +192,9 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPartialDrainR1FillR2ToR1State( void ); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR2ToR1State( void ); static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectPartialDrainR2FillR1ToR2State( void ); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeBasicPathState(void); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeWaterPathState(void); -static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCompleteState(void); +static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeBasicPathState( void ); +static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeWaterPathState( void ); +static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCompleteState( void ); static void failChemicalDisinfect( void ); static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout ); @@ -215,9 +216,8 @@ * stateTrialCounter, areTempSensorsInRange, rsrvr1Status, rsrvr2Status, * overallChemDisinfectTimer, * cancellationMode, rsrvrFillStableTimeCounter, prevChemDisinfectState - * isPartialDisinfectInProgress, numberOfPostDisinfectRinses, - * primeAcidSteadyStateCounter, chemDisinfectUIState, haveDrainParamsBeenInit, - * disinfectNVOps + * isPartialDisinfectInProgress, primeAcidSteadyStateCounter, + * chemDisinfectUIState, haveDrainParamsBeenInit, disinfectNVOps * @return none *************************************************************************/ void initChemicalDisinfectMode( void ) @@ -229,7 +229,7 @@ stateTrialCounter = 0; rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - overallChemDisinfectTimer = 0; + overallChemDisinfectTimer = getMSTimerCount(); cancellationMode = CANCELLATION_MODE_NONE; rsrvrFillToFullStableTimeCounter = 0; primeAcidSteadyStateCounter = 0; @@ -254,6 +254,8 @@ R1FullVolume = 0.0F; R2FullVolume = 0.0F; disinfectantMixRatio = 0.0F; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; initPersistentAlarm( ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE, DISINFECT_TEMP_OUT_OF_RANGE_TIMEOUT_MS, DISINFECT_TEMP_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DG_CHEM_DISINFECT_TARGET_COND_OUT_OF_RANGE, DISINFECT_COND_OUT_OF_RANGE_TIMEOUT_MS, DISINFECT_COND_OUT_OF_RANGE_TIMEOUT_MS ); @@ -276,6 +278,8 @@ setCPLDCleanLEDColor( CPLD_CLEAN_LED_YELLOW ); + activateAlarmNoData( ALARM_ID_DG_CHEM_DISINFECT_INSERT_ACID ); + return chemDisinfectState; } @@ -432,28 +436,26 @@ *************************************************************************/ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectStartState( void ) { - DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; + DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_START; // Set the chemical disinfect state that is published on the UI chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_FLUSH_BEFORE_DISINFECT; - // Start overall chemical disinfect timer - overallChemDisinfectTimer = getMSTimerCount(); + if ( FALSE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_INSERT_ACID ) ) + { + // Set all the actuators to reset and de-energized state + deenergizeActuators( NO_PARK_CONC_PUMPS ); + setValveState( VPI, VALVE_STATE_CLOSED ); + setValveState( VRD1, VALVE_STATE_OPEN ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - // Set all the actuators to reset and de-energized state - deenergizeActuators( NO_PARK_CONC_PUMPS ); + // Assume reservoir 1 is full and drain it + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; + stateTimer = getMSTimerCount(); + } - setValveState( VPI, VALVE_STATE_CLOSED ); - // Set the actuators to drain R1 - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - - // Assume reservoir 1 is full and drain it - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; - stateTimer = getMSTimerCount(); - return state; } @@ -478,7 +480,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - 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 ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { // Done with draining R1 @@ -520,7 +522,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { - 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 ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -543,9 +545,9 @@ setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); turnOnUVReactor( INLET_UV_REACTOR ); - stateTrialCounter = 0; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_FLUSH_DRAIN; + stateTrialCounter = 0; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_FLUSH_DRAIN; } } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) @@ -613,19 +615,24 @@ // Check if the flush circulation time has elapsed and the temperature sensors are not in range yet if ( TRUE == didTimeout( stateTimer, flushCircWaitTime ) ) { - F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 TD2Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); + F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + F32 TD2Temp = 0.0F; + +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_USING_TPO_FOR_PRIMARY_HEATER_CONTROL ) ) + { + TD2Temp = getTemperatureValue( TEMPSENSORS_CONDUCTIVITY_SENSOR_2 ); + } +#endif + F32 avgTemp = ( TPoTemp + TD2Temp ) / NUM_OF_TEMP_SENSORS_TO_AVG; F32 cd2Conductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); F32 cpoConductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CPO_SENSOR ); + BOOL isTPoOut = FALSE; + BOOL isTD2Out = FALSE; + BOOL isCD2Out = FALSE; + BOOL isCPoOut = FALSE; - // Check if any of the temperature sensors deviate for more than the defined value from the average of all - // of the temperature sensors - BOOL isTPoOut = FALSE; - BOOL isTD2Out = FALSE; - BOOL isCD2Out = ( cd2Conductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); - BOOL isCPoOut = ( cpoConductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); - #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_TEMPERATURE_SENSORS_ALARM ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -634,6 +641,14 @@ isTD2Out = ( fabs( TD2Temp - avgTemp ) > MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C ? TRUE : FALSE ); } +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + isCD2Out = ( cd2Conductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); + isCPoOut = ( cpoConductivity > MAX_FLUSH_CIRC_CONDUCTIVITY_US_PER_CM ? TRUE : FALSE ); + } + // Check if any of the temperature sensors are out of tolerance if( ( TRUE == isTPoOut ) || ( TRUE == isTD2Out ) || ( TRUE == isCD2Out ) || ( TRUE == isCPoOut) ) { @@ -1160,7 +1175,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 ) { @@ -1180,7 +1195,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 ) { @@ -1227,7 +1242,13 @@ *************************************************************************/ static void failChemicalDisinfect( void ) { - SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevChemDisinfectState ) + // In the cleaning modes the alarms are triggered but the mode is not transitioned to fault automatically + // so transition to fault mode is done here + if ( alarmDetectedPendingTrigger != ALARM_ID_NO_ALARM ) + { + SET_ALARM_WITH_1_U32_DATA( alarmDetectedPendingTrigger, prevChemDisinfectState ) + } + requestNewOperationMode( DG_MODE_FAUL ); } /*********************************************************************//** @@ -1298,20 +1319,27 @@ static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_ABOVE_TARGET; + BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); - 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(); + 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 and transition to basic cancellation prevChemDisinfectState = chemDisinfectState; alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; + haveDrainParamsBeenInit[ r ] = FALSE; status = DG_RESERVOIR_NOT_REACHED_TARGET; } @@ -1332,8 +1360,8 @@ static DG_RESERVOIR_STATUS_T getRsrvrFillToFullStatus( DG_RESERVOIR_ID_T r, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_BELOW_TARGET; - F32 currentVolume = 0.0; - F32 filteredVolume = 0.0; + F32 currentVolume = 0.0F; + F32 filteredVolume = 0.0F; if ( DG_RESERVOIR_1 == r ) { @@ -1398,11 +1426,10 @@ static void handleDisinfectantMixing( F32 measuredROFlowRate_mL_min, F32 disinfectantMixingRatio ) { // Set concentrate pumps speed based off RO pump flow rate. The ratio is water/disinfectant - F32 disinfectantCP2PumpFlowRate = measuredROFlowRate_mL_min / disinfectantMixingRatio; + F32 disinfectantCP2PumpFlowRate = measuredROFlowRate_mL_min / disinfectantMixingRatio; // Cap to the maximum allowed concentrate pumps rate disinfectantCP2PumpFlowRate = MIN( disinfectantCP2PumpFlowRate, CONCENTRATE_PUMP_MAX_SPEED ); - disinfectantCP2PumpFlowRate = MAX( disinfectantCP2PumpFlowRate, 0.0F ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, disinfectantCP2PumpFlowRate ); @@ -1442,7 +1469,7 @@ if ( DG_RESERVOIR_1 == r ) { actVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); - if ( R1FullVolume > 0.0 ) + if ( R1FullVolume > 0.0F ) { // If a reservoir full volume is known, use a set volume below full. This compensates for variations in // the reservoir and load cell that may affect the volume read when the reservoir is full. tgtVolume = R1FullVolume - RESERVOIR_VOLUME_BELOW_FULL_ML; @@ -1451,7 +1478,7 @@ else if ( DG_RESERVOIR_2 == r ) { actVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - if ( R2FullVolume > 0.0 ) + if ( R2FullVolume > 0.0F ) { // If a reservoir full volume is known, use a set volume below full. This compensates for variations in // the reservoir and load cell that may affect the volume read when the reservoir is full. tgtVolume = R2FullVolume - RESERVOIR_VOLUME_BELOW_FULL_ML; @@ -1462,8 +1489,8 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_DG_RESERVOIR_SELECTED, r ) } - newRPM = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP_VOLUME, tgtVolume, actVolume ); - setDrainPumpTargetRPM( newRPM ); + newRPM = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP_VOLUME, tgtVolume, actVolume ); + setDrainPumpTargetRPM( newRPM ); drpControlTimerCounter = getMSTimerCount(); } } @@ -1567,8 +1594,6 @@ *************************************************************************/ static void monitorModeChemicalDisinfect( void ) { - BOOL areInletWaterAlarmsActive = FALSE; - // Reservoir leak detection. if ( ( DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2 == chemDisinfectState ) || ( DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1 == chemDisinfectState ) ) { @@ -1602,30 +1627,12 @@ // If the dialysate cap is open during any state, alarm if ( 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 ); prevChemDisinfectState = chemDisinfectState; chemDisinfectState = DG_CHEM_DISINFECT_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 ) - { - prevChemDisinfectState = chemDisinfectState; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } - // Check the temperature and conductivity of the diluted disinfectant if ( ( chemDisinfectState >= DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH ) && ( chemDisinfectState <= DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R2_FILL_R1_TO_R2 ) ) { @@ -1652,6 +1659,12 @@ chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } } + + if ( ( TRUE == isAnyAlarmActive() ) && ( chemDisinfectState != DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH ) ) + { + prevChemDisinfectState = chemDisinfectState; + chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + } } /*********************************************************************//** 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; Index: firmware/App/Modes/ModeFlush.c =================================================================== diff -u -r6499ea25921fcf67826fa0c35bb03caf411ba542 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) +++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -1108,8 +1108,6 @@ *************************************************************************/ static void monitorModeFlush( void ) { - BOOL areInletWaterAlarmsActive = FALSE; - #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -1125,14 +1123,7 @@ } } - 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 ) ) + if ( ( TRUE == isAnyAlarmActive() ) && ( flushState != DG_FLUSH_STATE_CANCEL_WATER_PATH ) ) { prevFlushState = flushState; flushState = DG_FLUSH_STATE_CANCEL_WATER_PATH; Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -rb8f298547eb578000b3ff3cf55732fda7a689ce0 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision b8f298547eb578000b3ff3cf55732fda7a689ce0) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -53,7 +53,7 @@ // Drain R1 & R2 states defines #define DRAIN_PUMP_TARGET_RPM 2400 ///< Drain pump target RPM during drain. -#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 @@ -455,7 +455,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - 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 ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -480,7 +480,7 @@ else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; } return state; @@ -503,7 +503,7 @@ if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { - 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 ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -513,13 +513,13 @@ signalDrainPumpHardStop(); // Done with draining R2, close it + turnOnUVReactor( INLET_UV_REACTOR ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); stateTrialCounter = 0; - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_FLUSH_DRAIN; - - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_FLUSH_DRAIN; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { @@ -550,7 +550,6 @@ // Check if flush time has elapsed if ( TRUE == didTimeout( stateTimer, FLUSH_DRAIN_WAIT_TIME_MS ) ) { - turnOnUVReactor( INLET_UV_REACTOR ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); stateTimer = getMSTimerCount(); @@ -742,7 +741,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_INITIAL_DRAIN_TIME_OUT_MS ); + rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIMEOUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -789,10 +788,11 @@ signalROPumpHardStop(); stopHeater( DG_PRIMARY_HEATER ); turnOffUVReactor( INLET_UV_REACTOR ); + turnOffUVReactor( OUTLET_UV_REACTOR ); // Set the valves to drain R2 and no fill setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD2, VALVE_STATE_OPEN ); setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); @@ -834,7 +834,7 @@ // If reservoir 2 is empty, set the drain valve to drain R1 if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) { - 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 ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { @@ -872,7 +872,7 @@ // If reservoir 1 is empty, set the state to fill water state if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { - 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 ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -1314,10 +1314,8 @@ // Set the heat disinfect UI state heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_CANCEL_DISINFECT; + cancellationMode = CANCELLATION_MODE_BASIC; - // Set the cancellation mode - cancellationMode = CANCELLATION_MODE_BASIC; - failHeatDisinfect(); return state; @@ -1339,10 +1337,10 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCancelModeWaterPathState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + U32 drainTimeoutMS = ( CANCELLATION_MODE_COLD == cancellationMode ? RSRVRS_INITIAL_DRAIN_TIMEOUT_MS : RSRVRS_MIX_DRAIN_TIMEOUT_MS ); // Set the heat disinfect UI state heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_CANCEL_DISINFECT; - U32 drainTimeoutMS = ( CANCELLATION_MODE_COLD == cancellationMode ? RSRVRS_INITIAL_DRAIN_TIME_OUT_MS : RSRVRS_MIX_DRAIN_TIMEOUT_MS ); if ( CANCELLATION_MODE_NONE == cancellationMode ) { @@ -1367,7 +1365,6 @@ targetRPM = DRAIN_PUMP_RPM_IN_MIX_DRAIN; cancellationMode = CANCELLATION_MODE_HOT; - drainTimeoutMS = RSRVRS_MIX_DRAIN_TIMEOUT_MS; } rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; @@ -1376,7 +1373,6 @@ // The drain is set to start from reservoir 2 since all the actuators have been de-energized // Set the drain valve to reservoir 2 setValveState( VRD2, VALVE_STATE_OPEN ); - // Start the drain pump setDrainPumpTargetRPM( targetRPM ); // Start the timer for drain timeout @@ -1552,6 +1548,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ) { 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 ] ) @@ -1560,11 +1557,9 @@ haveDrainParamsBeenInit[ r ] = TRUE; } - BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); - if ( TRUE == isDrainComplete ) { - if ( ( DG_HEAT_DISINFECT_STATE_FLUSH_R2_AND_DRAIN_R1 == heatDisinfectState) && ( DG_RESERVOIR_1 == r ) ) + if ( ( DG_HEAT_DISINFECT_STATE_FLUSH_R2_AND_DRAIN_R1 == heatDisinfectState ) && ( DG_RESERVOIR_1 == r ) ) { if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( 0 == getDrainPumpTargetRPM() ) ) { @@ -1787,8 +1782,6 @@ *************************************************************************/ static void monitorModeHeatDisinfect( void ) { - BOOL areInletWaterAlarmsActive = FALSE; - #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -1804,15 +1797,7 @@ } } - 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() ) && ( heatDisinfectState != DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH ) ) { prevHeatDisinfectState = heatDisinfectState; heatDisinfectState = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -rb8f298547eb578000b3ff3cf55732fda7a689ce0 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision b8f298547eb578000b3ff3cf55732fda7a689ce0) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -46,7 +46,7 @@ // *** This declaration will cause a compiler error if ALARM_RANK_TABLE does not have same # of alarms as the Alarm_List enumeration. U08 alarmRankTableSizeAssertion[ ( ( sizeof( ALARM_RANK_TABLE ) / sizeof( ALARM_RANK_T ) ) == NUM_OF_ALARM_IDS ? 1 : -1 ) ]; -U32 alarmLEDTimer; +U32 alarmLEDTimer; ///< Alarm LED timer const ALARM_DATA_T BLANK_ALARM_DATA = { ALARM_DATA_TYPE_NONE, 0 }; ///< A blank alarm data record for alarms that do not include alarm data when triggered. @@ -57,6 +57,7 @@ static BOOL alarmIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of current state of each alarm static BOOL alarmConditionIsActive[ NUM_OF_ALARM_IDS ]; ///< Array of flag indicates if an alarm condition is active static U32 alarmInfoPublicationTimerCounter; ///< Used to schedule alarm information publication to CAN bus. +static ALARM_ID_T activeAlarm; ///< Active DG alarm to be used to cancel the cleaning modes. /// Interval (in task intervals) at which to publish alarm information to CAN bus. static OVERRIDE_U32_T alarmInfoPublishInterval = { ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, ALARM_INFO_PUB_INTERVAL, 0 }; @@ -71,20 +72,22 @@ * @brief * The initAlarmMgmt function initializes the AlarmMgmt module. * @details Inputs: none - * @details Outputs: AlarmMgmt module initialized. + * @details Outputs: alarmInfoPublicationTimerCounter, alarmLEDTimer, + * activeAlarm, alarmIsActive, alarmConditionIsActive * @return none *************************************************************************/ void initAlarmMgmt( void ) { ALARM_ID_T alrm; alarmInfoPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - alarmLEDTimer = 0; + alarmLEDTimer = 0; + activeAlarm = ALARM_ID_NO_ALARM; // initialize alarm states and start time stamps for ( alrm = ALARM_ID_NO_ALARM; alrm < NUM_OF_ALARM_IDS; alrm++ ) { - alarmIsActive[ alrm ] = FALSE; + alarmIsActive[ alrm ] = FALSE; alarmConditionIsActive[ alrm ] = FALSE; } } @@ -122,13 +125,19 @@ if ( FALSE == alarmIsActive[ alarm ] ) { // activate alarm - alarmIsActive[ alarm ] = TRUE; + alarmIsActive[ alarm ] = TRUE; alarmConditionIsActive[ alarm ] = TRUE; - // If alarm is a DG fault, request transition to fault mode - if ( ( TRUE == ALARM_TABLE[ alarm ].alarmIsDGFault ) && ( TRUE == isTransitionToFaultRequired() ) ) + if ( TRUE == ALARM_TABLE[ alarm ].alarmIsDGFault ) { - requestNewOperationMode( DG_MODE_FAUL ); + // There is a DG fault alarm. Update the variable so the modes such as cleaning modes know there is a fault happening. + activeAlarm = alarm; + + if ( TRUE == isTransitionToFaultRequired() ) + { + // If alarm is a DG fault and the alarm manager can transition to fault immediately, go to fault mode + requestNewOperationMode( DG_MODE_FAUL ); + } } // If alarm has clear condition immediately property, clear condition now if ( TRUE == ALARM_TABLE[ alarm ].alarmConditionClearImmed ) @@ -267,6 +276,21 @@ BOOL isAlarmActive( ALARM_ID_T alarm ) { return alarmIsActive[ alarm ]; +} + +/*********************************************************************//** + * @brief + * The isAnyAlarmActive function determines whether any alarm is currently + * active. + * @details Inputs: alarmStatus + * @details Outputs: none + * @return TRUE if any alarm is active, FALSE if not + *************************************************************************/ +BOOL isAnyAlarmActive( void ) +{ + BOOL result = ( activeAlarm != ALARM_ID_NO_ALARM ? TRUE : FALSE ); + + return result; } /*********************************************************************//** Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r6499ea25921fcf67826fa0c35bb03caf411ba542 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -99,7 +99,7 @@ void clearAlarm( ALARM_ID_T alarm ); void clearAlarmCondition( ALARM_ID_T alarm ); BOOL isAlarmActive( ALARM_ID_T alarm ); - +BOOL isAnyAlarmActive( void ); void handleResendActiveAlarmsRequest( void ); BOOL testSetAlarmStateOverride( U32 alarmID, BOOL value ); Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r6499ea25921fcf67826fa0c35bb03caf411ba542 -rfcaca0915c314d04b9fa96c1960d32b63ab877db --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision fcaca0915c314d04b9fa96c1960d32b63ab877db) @@ -925,7 +925,7 @@ // Set the start time to 0 for the next drain and update the current load cell reading to the previous value reservoirWeightUnchangeStartTime[ reservoirId ] = 0; reservoirPreviousStatus[ reservoirId ].previousReservoirWeightG = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); - reservoirPreviousStatus[ reservoirId ].previousDrainFlowML = 0.0; + reservoirPreviousStatus[ reservoirId ].previousDrainFlowML = 0.0F; }