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; + } } /*********************************************************************//**