Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -ra053cecf0673654e2bc03e9a34ff15845c8cff93 -ra3a6cd2db3c03262d9da832753eeb77158845f28 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision a053cecf0673654e2bc03e9a34ff15845c8cff93) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision a3a6cd2db3c03262d9da832753eeb77158845f28) @@ -1,19 +1,19 @@ /************************************************************************** -* -* Copyright (c) 2019-2023 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) 03-Jan-2023 -* -* @author (original) Dara Navaei -* @date (original) 05-Nov-2019 -* -***************************************************************************/ + * + * Copyright (c) 2019-2023 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) 03-Jan-2023 + * + * @author (original) Dara Navaei + * @date (original) 05-Nov-2019 + * + ***************************************************************************/ #include "AlarmMgmt.h" #include "Buttons.h" @@ -46,10 +46,24 @@ /// TODO: Restore to 100 when DPi flow control is fixed. #define DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN 250 ///< Patient connection sub-mode dialysate inlet pump flow rate in mL/min. +#define PRE_TREATMENT_MIN_RESERVOIR_VOLUME_ML 400 ///< Fill reservoir to this volume minimum to prep volume during development. #define PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML 500 ///< Fill reservoir to this volume (in mL) to flush filter and lines. -#define PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML 900 ///< Fill reservoir one to this volume (in mL) during pre-treatment mode. -#define PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML 1100 ///< Fill reservoir two to this volume (in mL) during pre-treatment mode. +#define PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML 1200 ///< Fill reservoir one to this volume (in mL) during pre-treatment mode. +#define PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML 600 ///< Fill reservoir two to this volume (in mL) during pre-treatment mode. +#define PRE_TREATMENT_FULL_RESERVOIR_VOLUME_ML 1500 ///< Fill reservoir to this volume minimum to prep volume during development. +#define PRE_TREATMENT_FLUSH_COUNT 2 ///< Number of flush cycles for each reservoir. + +typedef struct +{ + BOOL initialDrain; ///< Flags indicate whether a reservoir has been requested to initially drain. + BOOL startFlushFill; ///< Flags "GO" for a flush reservoir fill, to synchronize with self-test requirements + BOOL startNormalFill; ///< Flags "GO" for a normal reservoir fill, to synchronize with self-test requirements + BOOL flushComplete; ///< Flag indicates a reservoir has been flushed. + BOOL fillComplete; ///< Flag indicates a reservoir has been filled. + U32 flushCount; ///< Flag indicates the number of reservoir flush cycles required. +} PRE_TREATMENT_RESERVOIR_VAR_T; + /// States of the pre-treatment reservoir management state machine. typedef enum PreTreatmentReservoirMgmt_States { @@ -82,12 +96,15 @@ static OVERRIDE_U32_T preTreatmentModePublishInterval = { PRE_TREATMENT_DATA_PUB_INTERVAL, PRE_TREATMENT_DATA_PUB_INTERVAL, PRE_TREATMENT_DATA_PUB_INTERVAL, 0 }; static U32 submodeCompleteTransitionTimeCounter; ///< Sub-mode completed transition wait time counter. -static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current pre-treatment reservoir management state. -static BOOL reservoirFilledStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Flag indicates a reservoir has been filled. -static BOOL reservoirFlushedStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Flag indicates a reservoir has been flushed. -static PRE_TREATMENT_RESERVOIR_FLAGS_T reservoirFlags[ NUM_OF_DG_RESERVOIRS ]; ///< Set of Flags that signal if the DG should wait to fill. -static BOOL initialReservoirDrain[ NUM_OF_DG_RESERVOIRS ]; ///< Flags indicate whether a reservoir has been requested to initially drain. +static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T currentReservoirMgmtState; ///< Current pre-treatment reservoir management state. +static DG_RESERVOIR_ID_T activeReservoir = DG_RESERVOIR_2; +static PRE_TREATMENT_RESERVOIR_VAR_T reservoirStatus[ NUM_OF_DG_RESERVOIRS ]; ///< Detailed state of each reservoir. +#ifndef _RELEASE_ +const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPrimingDisabled = {FALSE,FALSE,FALSE,FALSE,FALSE,(0)}; +#endif +const PRE_TREATMENT_RESERVOIR_VAR_T reservoirPretreatmentInit = {FALSE,FALSE,FALSE,FALSE,FALSE,PRE_TREATMENT_FLUSH_COUNT}; + // ********** private function prototypes ********** static void publishPreTreatmentState( void ); @@ -121,29 +138,35 @@ * @details Inputs: none * @details Outputs: Pre-Treatment Mode module initialized. * @return none -*************************************************************************/ + *************************************************************************/ void initPreTreatmentMode( void ) { + int reservoirIndex = 0; + currentPreTreatmentState = HD_PRE_TREATMENT_START_STATE; currentReservoirMgmtState = PRE_TREATMENT_RESERVOIR_MGMT_START_STATE; setUFVolStatus = FALSE; patientConnectionConfirm = FALSE; fillReservoirOneStartRequested = FALSE; submodeCompleteTransitionTimeCounter = 0; - reservoirFilledStatus[ DG_RESERVOIR_1 ] = FALSE; - reservoirFilledStatus[ DG_RESERVOIR_2 ] = FALSE; - reservoirFlushedStatus[ DG_RESERVOIR_1 ] = FALSE; - reservoirFlushedStatus[ DG_RESERVOIR_2 ] = FALSE; +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) + { + for ( reservoirIndex = 0; reservoirIndex < NUM_OF_DG_RESERVOIRS; reservoirIndex++ ) + { + reservoirStatus[reservoirIndex] = reservoirPrimingDisabled; + } + } + else +#endif + { + for ( reservoirIndex = 0; reservoirIndex < NUM_OF_DG_RESERVOIRS; reservoirIndex++ ) + { + reservoirStatus[reservoirIndex] = reservoirPretreatmentInit; + } + } - reservoirFlags[ DG_RESERVOIR_1 ].startFlushFill = FALSE; - reservoirFlags[ DG_RESERVOIR_1 ].startNormalFill = FALSE; - reservoirFlags[ DG_RESERVOIR_2 ].startFlushFill = FALSE; - reservoirFlags[ DG_RESERVOIR_2 ].startNormalFill = FALSE; - - initialReservoirDrain[ DG_RESERVOIR_1 ] = FALSE; - initialReservoirDrain[ DG_RESERVOIR_2 ] = FALSE; - initSampleWater(); initConsumableSelfTest(); initPrime(); @@ -164,7 +187,7 @@ * @details Inputs: none * @details Outputs: none * @return initial state -*************************************************************************/ + *************************************************************************/ U32 transitionToPreTreatmentMode( void ) { F32 trimmerHeaterTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); @@ -205,7 +228,7 @@ * @details Inputs: none * @details Outputs: none * @return current state (sub-mode) -*************************************************************************/ + *************************************************************************/ U32 execPreTreatmentMode( void ) { BOOL stop = isStopButtonPressed(); @@ -497,10 +520,10 @@ *************************************************************************/ void signalActionToResumeFill( void ) { - reservoirFlags[ DG_RESERVOIR_1 ].startFlushFill = TRUE; - reservoirFlags[ DG_RESERVOIR_1 ].startNormalFill = TRUE; - reservoirFlags[ DG_RESERVOIR_2 ].startFlushFill = TRUE; - reservoirFlags[ DG_RESERVOIR_2 ].startNormalFill = TRUE; + reservoirStatus[ DG_RESERVOIR_1 ].startFlushFill = TRUE; + reservoirStatus[ DG_RESERVOIR_1 ].startNormalFill = TRUE; + reservoirStatus[ DG_RESERVOIR_2 ].startFlushFill = TRUE; + reservoirStatus[ DG_RESERVOIR_2 ].startNormalFill = TRUE; } /*********************************************************************//** @@ -513,7 +536,7 @@ *************************************************************************/ BOOL getReservoirFillStatus( DG_RESERVOIR_ID_T reservoirID ) { - return reservoirFilledStatus[ reservoirID ]; + return reservoirStatus[ reservoirID ].fillComplete; } /*********************************************************************//** @@ -700,12 +723,7 @@ fillReservoirOneStartRequested = TRUE; transitionToNoCartSelfTests(); } -#ifndef _RELEASE_ - if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) -#endif - { - signalActionToResumeFill(); - } + signalActionToResumeFill(); } return state; @@ -906,6 +924,9 @@ *************************************************************************/ static void execPreTreatmentReservoirMgmt( void ) { + // update the active reservoir. + activeReservoir = getDGActiveReservoir(); + // treatment reservoir mgmt. state machine switch ( currentReservoirMgmtState ) { @@ -971,7 +992,6 @@ rsrvrCmd.useLastTrimmerHeaterDC = FALSE; fillReservoirOneStartRequested = FALSE; state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; - cmdSetDGActiveReservoir( &rsrvrCmd ); } @@ -1003,8 +1023,15 @@ { if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { - state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; - cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE, FALSE, TRUE ); + if ( FALSE == reservoirStatus[ activeReservoir ].flushComplete ) + { + state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; + cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE, FALSE, TRUE ); + } + else + { + state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + } } } @@ -1049,7 +1076,7 @@ * The handlePreTreatmentReservoirMgmtFillCmdState function sends fill * command to DG when DG is in re-circulate mode. * @details Inputs: DG operation mode, DG operation sub-mode, - * reservoirFlushedStatus, reservoirFlags + * reservoirStatus.flushedStatus, reservoirStatus * @details Outputs: sent fill command to DG * @return current state of pre-treatment reservoir management *************************************************************************/ @@ -1059,36 +1086,40 @@ DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); U32 volume = 0; - DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { // Drain both reservoirs and return to active res 2 before initial fills - if ( initialReservoirDrain[ inactiveReservoir ] != TRUE ) + if ( reservoirStatus[ activeReservoir ].initialDrain != TRUE ) { - initialReservoirDrain[ inactiveReservoir ] = TRUE; + reservoirStatus[ activeReservoir ].initialDrain = TRUE; state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; } - // Once both reservoirs drained and returned to active res 2, wait for pre-tx workflow to get to point where fills allowed before filling - else if ( TRUE == reservoirFlags[ DG_RESERVOIR_1 ].startFlushFill ) - { - volume = getPreTreatmentFillVolume( inactiveReservoir ); - // not flushed and need to fill - if ( ( TRUE != reservoirFlushedStatus[ inactiveReservoir ] ) && - ( TRUE == reservoirFlags[ inactiveReservoir ].startFlushFill ) ) + // Once both reservoirs drained and returned to active res 2, wait for pre-tx workflow + // to get to point where fills are allowed, before starting fill + // not flushed and need to fill -OR- + // flushed and need to fill after entering dry self test state + else if ( ( TRUE == reservoirStatus[ activeReservoir ].startFlushFill ) || + ( ( TRUE == reservoirStatus[ activeReservoir ].startNormalFill ) && + ( currentPreTreatmentState >= HD_PRE_TREATMENT_SELF_TEST_DRY_STATE ) ) ) + { + // Start tracking flush cycles, flushComplete => don't drain again. + if ( FALSE == reservoirStatus[ activeReservoir ].flushComplete ) { - cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); - state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; + if (0 < reservoirStatus[ activeReservoir ].flushCount) + { + reservoirStatus[ activeReservoir ].flushCount -= 1; + } + if ( 0 == reservoirStatus[ activeReservoir ].flushCount ) + { + reservoirStatus[ activeReservoir ].flushComplete = TRUE; + } } - // flushed and need to fill - if ( ( TRUE == reservoirFlushedStatus[ inactiveReservoir ] ) && - ( TRUE == reservoirFlags[ inactiveReservoir ].startNormalFill ) ) - { - cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); - state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; - } + volume = getPreTreatmentFillVolume( activeReservoir ); + cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); + state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; } } @@ -1148,55 +1179,20 @@ if ( ( DG_MODE_GENE == dgOpMode ) && ( DG_GEN_IDLE_MODE_STATE_FLUSH_WATER == dgSubMode ) ) { - if ( ( TRUE == reservoirFlushedStatus[ DG_RESERVOIR_1 ] ) && ( TRUE == reservoirFlushedStatus[ DG_RESERVOIR_2 ] ) ) + state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; + + if ( ( TRUE == reservoirStatus[ DG_RESERVOIR_1 ].flushComplete ) && + ( TRUE == reservoirStatus[ DG_RESERVOIR_2 ].flushComplete ) ) { - if ( FALSE == reservoirFilledStatus[ DG_RESERVOIR_1 ] ) - { - state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; - reservoirFilledStatus[ DG_RESERVOIR_1 ] = TRUE; - } - else - { - if ( FALSE == reservoirFilledStatus[ DG_RESERVOIR_2 ] ) - { - reservoirFilledStatus[ DG_RESERVOIR_2 ] = TRUE; - state = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; - } - } + reservoirStatus[ activeReservoir ].fillComplete = TRUE; } else { - state = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; + DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - if ( FALSE == reservoirFlushedStatus[ DG_RESERVOIR_1 ] ) - { -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) - { - reservoirFilledStatus[ DG_RESERVOIR_1 ] = TRUE; - } - else -#endif - { - DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; - rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - reservoirFlushedStatus[ DG_RESERVOIR_1 ] = TRUE; - - cmdSetDGActiveReservoir( &rsrvrCmd ); - } - } - else - { - DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_2; - rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - reservoirFlushedStatus[ DG_RESERVOIR_2 ] = TRUE; - - cmdSetDGActiveReservoir( &rsrvrCmd ); - } + rsrvrCmd.reservoirID = activeReservoir; + rsrvrCmd.useLastTrimmerHeaterDC = FALSE; + cmdSetDGActiveReservoir( &rsrvrCmd ); } } @@ -1207,7 +1203,7 @@ * @brief * The handlePreTreatmentReservoirMgmtRequestReservoirSwitchState function waits * until prime operation switches the active reservoir before filling up next reservoir. - * @details Inputs: DG intactive reservoir + * @details Inputs: DG inactive reservoir * @details Outputs: start filling next reservoir * @return current state of pre-treatment reservoir management *************************************************************************/ @@ -1236,7 +1232,7 @@ * @brief * The handlePreTreatmentReservoirMgmtWaitReservoirSwitchState function waits * until prime operation switches the active reservoir before filling up next reservoir. - * @details Inputs: DG intactive reservoir + * @details Inputs: DG inactive reservoir * @details Outputs: start filling next reservoir * @return current state of pre-treatment reservoir management *************************************************************************/ @@ -1269,7 +1265,7 @@ * @brief * The getPreTreatmentFillVolume function determines which volume to fill * the inactive reservoir. - * @details Inputs: reservoirFlushedStatus + * @details Inputs: reservoirStatus.flushedStatus * @details Outputs: none * @param DG inactive Reservoir * @return volume to fill @@ -1279,40 +1275,22 @@ U32 volume = 0; // Fill volumes after flushing - if ( TRUE == reservoirFlushedStatus[ inactiveRes ] ) + if ( TRUE == reservoirStatus[ inactiveRes ].flushComplete ) { if ( DG_RESERVOIR_1 == inactiveRes ) { - volume = FILL_RESERVOIR_TO_VOLUME_ML; -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) != SW_CONFIG_ENABLE_VALUE ) - { - volume = PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML; - } -#endif + volume = PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML; } // Reservoir 2 else { - volume = FILL_RESERVOIR_TO_VOLUME_ML; -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) != SW_CONFIG_ENABLE_VALUE ) - { - volume = PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML; - } -#endif + volume = PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML; } } // Flush fill volumes else { volume = PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML; -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) - { - volume = FILL_RESERVOIR_TO_VOLUME_ML; - } -#endif } return volume;