Index: firmware/App/Modes/ModeChemicalDisinfectFlush.c =================================================================== diff -u -r0accd811fd2db649fe15ca85e1ad6614efa8ba51 -r54abf84364e737dd350153d5fab7dd652f917ef4 --- firmware/App/Modes/ModeChemicalDisinfectFlush.c (.../ModeChemicalDisinfectFlush.c) (revision 0accd811fd2db649fe15ca85e1ad6614efa8ba51) +++ firmware/App/Modes/ModeChemicalDisinfectFlush.c (.../ModeChemicalDisinfectFlush.c) (revision 54abf84364e737dd350153d5fab7dd652f917ef4) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2022-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2022-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file ModeChemicalDisinfectFlush.c * * @author (last) Dara Navaei -* @date (last) 28-Jun-2023 +* @date (last) 09-Sep-2024 * * @author (original) Dara Navaei * @date (original) 15-Nov-2022 @@ -73,7 +73,6 @@ #define CHEM_DISINFECT_FLUSH_TIME_MS ( 12 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect flush time in ms. // Fill reservoirs to full defines -#define RESERVOIR_FULL_VOLUME_CHANGE_LIMIT_ML 5.0F ///< The maximum difference between the short-term and long-term filtered reservoir volumes in ml that determines the reservoir is full. #define RESERVOIR_MINIMUM_FULL_VOLUME_ML 1850.0F ///< When filling the reservoir, the volume reading must be at least this value before checking for the volume to level off. #define RSRVRS_FILL_TO_FULL_STABLE_TASK_INT ( ( 2 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in task intervals. @@ -113,7 +112,6 @@ static DG_RESERVOIR_STATUS_T rsrvr1Status; ///< Reservoir 1 status. static DG_RESERVOIR_STATUS_T rsrvr2Status; ///< Reservoir 2 status. static U32 waitTimer; ///< Wait timer for reservoir flushing. -static U32 drainTimer; ///< Timer for reservoir draining during flush states static U32 dataPublishCounter; ///< Chemical disinfect flush data publish counter. static CANCELLATION_MODE_T cancellationMode; ///< Cancellation mode. static U32 rsrvrFillToFullStableTimerCounter; ///< Task interval counter for determining if reservoir is full @@ -174,7 +172,6 @@ alarmDetectedPendingTrigger = ALARM_ID_NO_ALARM; chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_NOT_RUNNING; waitTimer = 0; - drainTimer = 0; dataPublishCounter = 0; disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; hasAlarmBeenTriggered = FALSE; @@ -556,7 +553,7 @@ * UF filter for a period of time. After the flush it transitions to the * next state. * @details Inputs: stateTimer, - * @details Outputs: stateTimer, drainTimer, numberOfPostDisinfectRinses, + * @details Outputs: stateTimer, numberOfPostDisinfectRinses, * rsrvrFillToFullStableTimerCounter * @return next state of the chemical disinfect flush state machine *************************************************************************/ @@ -575,7 +572,6 @@ setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - drainTimer = getMSTimerCount(); numberOfPostDisinfectRinses = 0; rsrvrFillToFullStableTimerCounter = 0; stateTimer = getMSTimerCount(); @@ -594,32 +590,15 @@ * if the fill times out, it transitions to water cancellation state. * If the drain and rinse are completed within the defined time, it * transitions to the next state. - * @details Inputs: rsrvr1Status, rsrvr2Status, drainTimer, waitTimer - * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, drainTimer, + * @details Inputs: rsrvr1Status, rsrvr2Status, waitTimer + * @details Outputs: stateTimer, rsrvr1Status, rsrvr2Status, * waitTimer, prevChemDisinfectFlushState, alarmDetectedPendingTrigger * @return next state of the chemical disinfect flush state machine *************************************************************************/ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushFlushR2ToR1DrainR1State( void ) { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R2_TO_R1_DRAIN_R1; - // Check whether draining R1 has timed out - if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) - { - // Do not use the standard drain status function because we are filling and draining at the same time - if ( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) < RSRVRS_DRAIN_TARGET_VOLUME_ML ) - { - rsrvr1Status = DG_RESERVOIR_REACHED_TARGET; - } - else if ( TRUE == didTimeout( drainTimer, RSRVRS_FLUSH_DRAIN_TIMEOUT_MS ) ) - { - // reservoir 1 drain timeout - prevChemDisinfectFlushState = state; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; - } - } - // Check whether R2 fill has timed out if ( DG_RESERVOIR_BELOW_TARGET == rsrvr2Status ) { @@ -646,7 +625,6 @@ setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - drainTimer = getMSTimerCount(); stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R1_TO_R2_DRAIN_R2; } @@ -673,23 +651,6 @@ { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R1_TO_R2_DRAIN_R2; - // Check whether draining R2 has timed out - if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) - { - // Do not use the standard drain status function because we are filling and draining at the same time - if ( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) < RSRVRS_DRAIN_TARGET_VOLUME_ML ) - { - rsrvr2Status = DG_RESERVOIR_REACHED_TARGET; - } - else if ( TRUE == didTimeout( drainTimer, RSRVRS_FLUSH_DRAIN_TIMEOUT_MS ) ) - { - // reservoir 2 drain timeout - prevChemDisinfectFlushState = state; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; - } - } - // Check whether R1 fill has timed out if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { @@ -719,12 +680,12 @@ setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - drainTimer = getMSTimerCount(); stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R2_TO_R1_DRAIN_R1; } else { + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); // Number of rinse cycles complete stateTimer = getMSTimerCount(); state = DG_CHEM_DISINFECT_FLUSH_STATE_SAMPLE_FLUSH_R1_TO_R2_DRAIN_R2; @@ -751,7 +712,6 @@ if ( ( TRUE == didTimeout( stateTimer, SAMPLE_FLUSH_WAIT_TIME_MS ) ) && ( FALSE == hasAlarmBeenTriggered ) ) { hasAlarmBeenTriggered = TRUE; - setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); activateAlarmNoData( ALARM_ID_DG_CHEM_DISINFECT_FLUSH_FLUSH_SAMPLE ); } @@ -820,7 +780,7 @@ * chemical disinfect flush cancel mode water path state. * @details Inputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer * @details Outputs: rsrvr1Status, rsrvr2Status, cancellationMode, stateTimer, - * ChemDisinfectFlushUIState + * ChemDisinfectFlushUIState, haveDrainParamsBeenInit * @return next state of the chemical disinfect flush state machine *************************************************************************/ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCancelModeWaterPathState( void ) @@ -834,12 +794,15 @@ // Stop all the actuators first then decide who should run next deenergizeActuators( NO_PARK_CONC_PUMPS ); - cancellationMode = CANCELLATION_MODE_WATER; - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; + haveDrainParamsBeenInit[ DG_RESERVOIR_1 ] = FALSE; + haveDrainParamsBeenInit[ DG_RESERVOIR_2 ] = FALSE; + cancellationMode = CANCELLATION_MODE_WATER; + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; // The drain is set to start from reservoir 2 setValveState( VRD2, VALVE_STATE_OPEN ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); // Start the timer for drain timeout @@ -917,13 +880,16 @@ *************************************************************************/ static void failChemicalDisinfectFlush( void ) { + // If a fault alarm is active go to mode fault otherwise for cleaning mode alarms, transition to standby + DG_OP_MODE_T nextOpMode = ( FALSE == isDGFaultAlarmActive() ? DG_MODE_STAN : DG_MODE_FAUL ); + // 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, prevChemDisinfectFlushState ) } - requestNewOperationMode( DG_MODE_STAN ); + requestNewOperationMode( nextOpMode ); } /*********************************************************************//** @@ -1073,16 +1039,21 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif { + OPN_CLS_STATE_T concCap = getSwitchStatus( CONCENTRATE_CAP ); + OPN_CLS_STATE_T dialysateCap = getSwitchStatus( DIALYSATE_CAP ); + // 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 ) ) ) + if ( ( STATE_OPEN == concCap ) || ( STATE_OPEN == dialysateCap ) ) { - if ( chemDisinfectFlushState != DG_CHEM_DISINFECT_FLUSH_STATE_START ) + if ( ( chemDisinfectFlushState != DG_CHEM_DISINFECT_FLUSH_STATE_START ) && + ( chemDisinfectFlushState != DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH ) && + ( chemDisinfectFlushState != DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_BASIC_PATH ) ) { prevChemDisinfectFlushState = chemDisinfectFlushState; chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_CAP_NOT_IN_PROPER_POSITION; - if ( STATE_OPEN == getSwitchStatus( CONCENTRATE_CAP ) ) + if ( STATE_OPEN == concCap ) { alarmDetectedPendingTrigger = ALARM_ID_DG_CONCENTRATE_CAP_NOT_IN_PROPER_POSITION; }