Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -re83374c507e06265cfeb3ad6c96f6175f4cebfd7 -r364631fbb6ffd3ab52271e1cc5b71ee9e2cc777f --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision e83374c507e06265cfeb3ad6c96f6175f4cebfd7) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 364631fbb6ffd3ab52271e1cc5b71ee9e2cc777f) @@ -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_WATER_SAMPLE_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 ); @@ -208,7 +231,7 @@ * @details Inputs: none * @details Outputs: none * @return current state (sub-mode) -*************************************************************************/ + *************************************************************************/ U32 execPreTreatmentMode( void ) { BOOL stop = isStopButtonPressed(); @@ -490,10 +513,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; } /*********************************************************************//** @@ -506,7 +529,7 @@ *************************************************************************/ BOOL getReservoirFillStatus( DG_RESERVOIR_ID_T reservoirID ) { - return reservoirFilledStatus[ reservoirID ]; + return reservoirStatus[ reservoirID ].fillComplete; } /*********************************************************************//** @@ -622,8 +645,7 @@ signalBloodPumpHardStop(); signalDialOutPumpHardStop(); - //setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialInPumpTargetFlowRate( 250, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); // TODO remove this line once the new flow control is implemented + setDialInPumpTargetFlowRate( DIP_PATIENT_CONNECTION_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); cmdStartDGTrimmerHeater(); } @@ -692,12 +714,7 @@ fillReservoirOneStartRequested = TRUE; transitionToNoCartSelfTests(); } -#ifndef _RELEASE_ - if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) -#endif - { - signalActionToResumeFill(); - } + signalActionToResumeFill(); } return state; @@ -911,6 +928,9 @@ *************************************************************************/ static void execPreTreatmentReservoirMgmt( void ) { + // update the active reservoir. + activeReservoir = getDGActiveReservoir(); + // treatment reservoir mgmt. state machine switch ( currentReservoirMgmtState ) { @@ -976,7 +996,6 @@ rsrvrCmd.useLastTrimmerHeaterDC = FALSE; fillReservoirOneStartRequested = FALSE; state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; - cmdSetDGActiveReservoir( &rsrvrCmd ); } @@ -1008,8 +1027,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; + } } } @@ -1054,7 +1080,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 *************************************************************************/ @@ -1064,36 +1090,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; } } @@ -1153,53 +1183,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 ); } } @@ -1210,7 +1207,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 *************************************************************************/ @@ -1239,7 +1236,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 *************************************************************************/ @@ -1272,7 +1269,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 @@ -1282,40 +1279,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;