Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r437ac340cfe0bd90bc016372113bae3d594b7526 -rcd5be724d5a3ba7457e761191d82f278654d7f5c --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 437ac340cfe0bd90bc016372113bae3d594b7526) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision cd5be724d5a3ba7457e761191d82f278654d7f5c) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-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 ModePreTreat.c * -* @author (last) Dara Navaei -* @date (last) 02-Jun-2023 +* @author (last) Sean Nash +* @date (last) 30-Sep-2023 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -110,7 +110,7 @@ #ifndef _RELEASE_ const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPrimingDisabled = {FALSE,FALSE,FALSE,TRUE,FALSE,(0)}; #endif -const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPretreatmentInit = {FALSE,FALSE,FALSE,FALSE,FALSE,PRE_TREATMENT_FLUSH_COUNT}; +const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPretreatmentInit = {FALSE,FALSE,FALSE,FALSE,FALSE,PRE_TREATMENT_FLUSH_COUNT}; ///< Pretreatment reservoir fill plan record. // ********** private function prototypes ********** @@ -141,6 +141,7 @@ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCompleteState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtRequestReservoirSwitchState( void ); static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtWaitReservoirSwitchState( void ); +static void handlePreTreatmentReservoirMgmtCompleteState( void ); static U32 getPreTreatmentFillVolume( DG_RESERVOIR_ID_T inactiveRes ); static void setPreTreatmentHeatingParams( F32 targetTempC, U32 targetVolML, F32 targetFillFlowLPM, U32 dialysateFlowMLPM ); @@ -524,6 +525,7 @@ case ALARM_ACTION_END_TREATMENT: if ( currentPreTreatmentState > HD_PRE_TREATMENT_WATER_SAMPLE_STATE ) { + signalNoDisinfectRequired(); // no blood introduced in pre-tx, so no need to disinfect after post-tx. requestNewOperationMode( MODE_POST ); } else @@ -825,6 +827,7 @@ { submodeCompleteTransitionTimeCounter = 0; state = HD_PRE_TREATMENT_CART_INSTALL_STATE; + doorOpened = FALSE; setCurrentSubState( NO_SUB_STATE ); transitionToCartridgeInstallation(); } @@ -836,7 +839,7 @@ /*********************************************************************//** * @brief * The handleInstallState function handles disposable installation. - * @details Inputs: none + * @details Inputs: confirmInstallRequested * @details Outputs: transition to prime sub-mode when blood pump finished * homing * @return current state (sub-mode) @@ -852,6 +855,8 @@ } #endif + handleDoorCloseAfterCartridgeInsertion(); // want to pinch off saline once door closed after cartridge install + if ( TRUE == confirmInstallRequested ) { confirmInstallRequested = FALSE; @@ -1201,6 +1206,8 @@ break; case PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE: + // retry the DG park concentrate pump request command if previous request was failed. + handlePreTreatmentReservoirMgmtCompleteState(); break; default: @@ -1523,6 +1530,9 @@ // Set the heating parameters setPreTreatmentHeatingParams( targetTempC, FILL_RESERVOIR_TO_VOLUME_ML, DEFAULT_TARGET_FILL_FLOW_RATE_LPM, dialysateFlowMLPM ); + // after reservoir fill at end of the pre-treatment, do park the concentrate pumps to maintain conductivity + // when treatment begins + cmdDGParkConcentratePumps(); state = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; } else @@ -1537,6 +1547,30 @@ /*********************************************************************//** * @brief + * The handlePreTreatmentReservoirMgmtCompleteState function checks + * Park DG concentrate pump command request sent was successfully handled or not. + * on failure, retry the DG Concentrate pumps park command request. + * @details Inputs: DG park concentrate pump request command response + * @details Outputs: retry park command on failure + * @return none + *************************************************************************/ +static void handlePreTreatmentReservoirMgmtCompleteState( void ) +{ + DG_CMD_RESPONSE_T dgCmdResp; + + // Check DG response to park concentrate pumps command + if ( TRUE == getDGCommandResponse( DG_CMD_PARK_CONCENTRATE_PUMPS, &dgCmdResp ) ) + { + if ( DG_CMD_REQUEST_REJECT_REASON_NONE != dgCmdResp.rejectCode ) + { + // retry park concentrate pumps command request to DG + cmdDGParkConcentratePumps(); + } + } +} + +/*********************************************************************//** + * @brief * The getPreTreatmentFillVolume function determines which volume to fill * the inactive reservoir. * @details Inputs: reservoirStatus[] @@ -1636,67 +1670,71 @@ DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); + // If DG has not started yet, start DG + if ( DG_MODE_STAN == dgOpMode ) + { + cmdStartDG(); + } + switch( currentReservoirMgmtState ) { case PRE_TREATMENT_RESERVOIR_MGMT_START_STATE: - rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - if ( ( reservoir1Level >= PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML ) && ( reservoir1Level < PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) ) + if ( DG_MODE_GENE == dgOpMode ) { - // Assume a reservoir switch is not needed and transition to the complete state because we are done - currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; + rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - if ( DG_RESERVOIR_2 == getDGActiveReservoir() ) + if ( ( reservoir1Level >= PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML ) && ( reservoir1Level < PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) ) { - // Reservoir 1 has the right volume, set it to active reservoir and wait for it to be done - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; - currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; - cmdSetDGActiveReservoir( &rsrvrCmd ); + // Assume a reservoir switch is not needed and transition to the complete state because we are done + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; + + if ( DG_RESERVOIR_2 == getDGActiveReservoir() ) + { + // Reservoir 1 has the right volume, set it to active reservoir and wait for it to be done + rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; + cmdSetDGActiveReservoir( &rsrvrCmd ); + } } - } - else if ( reservoir1Level >= PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) - { - // Reservoir 1 needs a partial drain so set it to be inactive so DG can drain it - if ( DG_RESERVOIR_1 == getDGActiveReservoir() ) + else if ( reservoir1Level >= PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) { - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; - cmdSetDGActiveReservoir( &rsrvrCmd ); - } + // Reservoir 1 needs a partial drain so set it to be inactive so DG can drain it + if ( DG_RESERVOIR_1 == getDGActiveReservoir() ) + { + rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; + cmdSetDGActiveReservoir( &rsrvrCmd ); + } - currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; - } - else if ( ( reservoir2Level >= PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML ) && ( reservoir2Level < PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) ) - { - // Reservoir 2 is in the right level, just make sure it is the active reservoir - // Assume a reservoir switch is not needed and transition to the complete state because we are done - currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; - - if ( DG_RESERVOIR_1 == getDGActiveReservoir() ) - { - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; - currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; - cmdSetDGActiveReservoir( &rsrvrCmd ); + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; } - } - else if ( reservoir2Level >= PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) - { - if ( DG_RESERVOIR_2 == getDGActiveReservoir() ) + else if ( ( reservoir2Level >= PRE_TREATMENT_TEST_CONFIG_MIN_RSRVR_VOL_ML ) && ( reservoir2Level < PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) ) { - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; - cmdSetDGActiveReservoir( &rsrvrCmd ); + // Reservoir 2 is in the right level, just make sure it is the active reservoir + // Assume a reservoir switch is not needed and transition to the complete state because we are done + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; + + if ( DG_RESERVOIR_1 == getDGActiveReservoir() ) + { + rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; + cmdSetDGActiveReservoir( &rsrvrCmd ); + } } + else if ( reservoir2Level >= PRE_TREATMENT_TEST_CONFIG_MAX_RSRVR_VOL_ML ) + { + if ( DG_RESERVOIR_2 == getDGActiveReservoir() ) + { + rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; + cmdSetDGActiveReservoir( &rsrvrCmd ); + } - currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; + currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; + } } break; case PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE: - // If DG has not started yet, start DG - if ( DG_MODE_STAN == dgOpMode ) - { - cmdStartDG(); - } - // Ensure any pending reservoir switches are completed before sending drain command if ( TRUE == hasDGCompletedReservoirSwitch() ) {