Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r4e6093159809ef2ddc39d88401390caebe7fa293 -r2f4f66fcceb986cc592693b08f1b57767cb1c515 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 4e6093159809ef2ddc39d88401390caebe7fa293) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 2f4f66fcceb986cc592693b08f1b57767cb1c515) @@ -8,7 +8,7 @@ * @file BloodFlow.c * * @author (last) Sean Nash -* @date (last) 02-Jan-2023 +* @date (last) 18-Jan-2023 * * @author (original) Sean Nash * @date (original) 07-Nov-2019 @@ -19,7 +19,8 @@ #include "can.h" #include "etpwm.h" - + +#include "Battery.h" #include "BloodFlow.h" #include "FPGA.h" #include "InternalADC.h" @@ -1248,7 +1249,7 @@ BOOL const isRunningMCCurrentBad = ( ( BLOOD_PUMP_OFF_STATE != bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ) ? TRUE : FALSE ); if ( ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, isOffMCCurrentBad || isRunningMCCurrentBad ) ) && - ( FALSE == isAlarmActive( ALARM_ID_HD_AC_POWER_LOST ) ) ) + ( FALSE == isACPowerLost() ) ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_MOTOR_CURRNT_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -rafe402337b84d8843c6ab544643fc403cb382c43 -r2f4f66fcceb986cc592693b08f1b57767cb1c515 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision afe402337b84d8843c6ab544643fc403cb382c43) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 2f4f66fcceb986cc592693b08f1b57767cb1c515) @@ -8,7 +8,7 @@ * @file SyringePump.c * * @author (last) Sean Nash -* @date (last) 01-Dec-2022 +* @date (last) 05-Feb-2023 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 @@ -472,6 +472,18 @@ /*********************************************************************//** * @brief + * The resetPreLoadStatus function resets the syringe pump pre-load status. + * @details Inputs: none + * @details Outputs: syringePumpPreLoadCompleted + * @return none + *************************************************************************/ +void resetPreLoadStatus( void ) +{ + syringePumpPreLoadCompleted = FALSE; +} + +/*********************************************************************//** + * @brief * The stopSyringePump function requests syringe pump be stopped. * @details Inputs: none * @details Outputs: syringePumpSetRate, syringePumpState, heparinDeliveryState @@ -1392,7 +1404,6 @@ syringePumpPlungerFound = FALSE; syringeVolumeAdequate = FALSE; syringePumpPrimeCompleted = FALSE; - syringePumpPreLoadCompleted = FALSE; syringePumpVolumeRequired = 0.0F; // Clear insufficient volume alarm condition in case we're retracting to allow user to resolve alarm clearAlarmCondition( ALARM_ID_HD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ); @@ -1512,10 +1523,9 @@ syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = pos; - syringePumpPreLoadCompleted = FALSE; - // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm - if ( syringeVol >= txVolume ) + // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm (check only applies in pre-tx mode) + if ( ( syringeVol >= txVolume ) || ( getCurrentOperationMode() != MODE_PRET ) ) { syringePumpPlungerFound = TRUE; syringeVolumeAdequate = TRUE; @@ -1574,7 +1584,6 @@ syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = syringePumpPosition.data; - syringePumpPreLoadCompleted = FALSE; } // Has syringe been removed? Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -rf760ffc4b10556e5186e9ceb90294262063440ca -r2f4f66fcceb986cc592693b08f1b57767cb1c515 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision f760ffc4b10556e5186e9ceb90294262063440ca) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 2f4f66fcceb986cc592693b08f1b57767cb1c515) @@ -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_FILL_RESERVOIR_VOLUME_ML 125 ///< 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 1300 ///< 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,14 @@ 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 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,TRUE,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 +137,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 +186,7 @@ * @details Inputs: none * @details Outputs: none * @return initial state -*************************************************************************/ + *************************************************************************/ U32 transitionToPreTreatmentMode( void ) { F32 trimmerHeaterTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); @@ -208,7 +230,7 @@ * @details Inputs: none * @details Outputs: none * @return current state (sub-mode) -*************************************************************************/ + *************************************************************************/ U32 execPreTreatmentMode( void ) { BOOL stop = isStopButtonPressed(); @@ -482,22 +504,46 @@ /*********************************************************************//** * @brief - * The signalActionToResumeFill function sets the remaining reservior fill - * flags to resume filling while in PreTreatment Mode. + * The signalAllowDGFlushFills function sets the reservoir flush flags + * to allow reservoir flush fills to proceed when ready. * @details Inputs: none * @details Outputs: reservoirFlags * @return none *************************************************************************/ -void signalActionToResumeFill( void ) +void signalAllowDGFlushFills( 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_2 ].startFlushFill = TRUE; } /*********************************************************************//** * @brief + * The signalAllowDGFillRes1 function sets the reservoir 1 fill flag + * to allow reservoir 1 fill to proceed when ready. + * @details Inputs: none + * @details Outputs: reservoirFlags + * @return none + *************************************************************************/ +void signalAllowDGFillRes1( void ) +{ + reservoirStatus[ DG_RESERVOIR_1 ].startNormalFill = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalAllowDGFillRes2 function sets the reservoir 2 fill flag + * to allow reservoir 2 fill to proceed when ready. + * @details Inputs: none + * @details Outputs: reservoirFlags + * @return none + *************************************************************************/ +void signalAllowDGFillRes2( void ) +{ + reservoirStatus[ DG_RESERVOIR_2 ].startNormalFill = TRUE; +} + +/*********************************************************************//** + * @brief * The getReservoirFillStatus function returns the fill complete status for * given reservoir. * @details Inputs: reservoirFilledStatus @@ -506,7 +552,7 @@ *************************************************************************/ BOOL getReservoirFillStatus( DG_RESERVOIR_ID_T reservoirID ) { - return reservoirFilledStatus[ reservoirID ]; + return reservoirStatus[ reservoirID ].fillComplete; } /*********************************************************************//** @@ -693,10 +739,10 @@ transitionToNoCartSelfTests(); } #ifndef _RELEASE_ - if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) + if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) // Allow reservoir flushes now if air pump not disabled #endif { - signalActionToResumeFill(); + signalAllowDGFlushFills(); } } @@ -976,7 +1022,6 @@ rsrvrCmd.useLastTrimmerHeaterDC = FALSE; fillReservoirOneStartRequested = FALSE; state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_STATE; - cmdSetDGActiveReservoir( &rsrvrCmd ); } @@ -1008,8 +1053,8 @@ { 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 ); + state = PRE_TREATMENT_RESERVOIR_MGMT_DRAIN_CMD_RESP_STATE; + cmdStartDGDrain( DRAIN_RESERVOIR_TO_VOLUME_ML, TRUE, FALSE, TRUE ); } } @@ -1054,47 +1099,44 @@ * 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 *************************************************************************/ static PRE_TREATMENT_RESERVOIR_MGMT_STATE_T handlePreTreatmentReservoirMgmtFillCmdState( void ) { PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_START_FILL_STATE; + DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); 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 ) ) { + U32 volume = 0; + // Drain both reservoirs and return to active res 2 before initial fills - if ( initialReservoirDrain[ inactiveReservoir ] != TRUE ) + if ( reservoirStatus[ inactiveReservoir ].initialDrain != TRUE ) { - initialReservoirDrain[ inactiveReservoir ] = TRUE; + reservoirStatus[ inactiveReservoir ].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 ) ) - { - cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); - state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; - } + // Determine target fill volume for next fill + volume = getPreTreatmentFillVolume( inactiveReservoir ); - // 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; - } + // Determine whether we can start next fill yet + if ( ( FALSE == reservoirStatus[ inactiveReservoir ].flushComplete ) && + ( TRUE == reservoirStatus[ inactiveReservoir ].startFlushFill ) ) + { + cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); + state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; } + else if ( ( TRUE == reservoirStatus[ inactiveReservoir ].flushComplete ) && + ( TRUE == reservoirStatus[ inactiveReservoir ].startNormalFill ) ) + { + cmdStartDGFill( volume, DEFAULT_TARGET_FILL_FLOW_RATE_LPM ); + state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_CMD_RESP_STATE; + } } return state; @@ -1150,56 +1192,41 @@ PRE_TREATMENT_RESERVOIR_MGMT_STATE_T state = PRE_TREATMENT_RESERVOIR_MGMT_FILL_COMPLETE_STATE; DG_OP_MODE_T dgOpMode = getDGOpMode(); U32 dgSubMode = getDGSubMode(); + DG_RESERVOIR_ID_T inactiveReservoir = getDGInactiveReservoir(); + DG_RESERVOIR_ID_T activeReservoir = getDGActiveReservoir(); 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 ] ) + reservoirStatus[ inactiveReservoir ].fillComplete = TRUE; + + if ( ( TRUE == reservoirStatus[ DG_RESERVOIR_1 ].fillComplete ) && + ( TRUE == reservoirStatus[ DG_RESERVOIR_2 ].fillComplete ) ) { - state = PRE_TREATMENT_RESERVOIR_MGMT_REQUEST_RESERVOIR_SWITCH_STATE; - reservoirFilledStatus[ DG_RESERVOIR_1 ] = TRUE; + state = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; } - else - { - if ( FALSE == reservoirFilledStatus[ DG_RESERVOIR_2 ] ) - { - reservoirFilledStatus[ DG_RESERVOIR_2 ] = TRUE; - state = PRE_TREATMENT_RESERVOIR_MGMT_COMPLETE_STATE; - } - } } else { - state = PRE_TREATMENT_RESERVOIR_MGMT_WAIT_FOR_RESERVOIR_SWITCH_STATE; + DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - if ( FALSE == reservoirFlushedStatus[ DG_RESERVOIR_1 ] ) + // Start tracking flush cycles, flushComplete => don't drain again, this completes the final fill. + if ( FALSE == reservoirStatus[ inactiveReservoir ].flushComplete ) { -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) + reservoirStatus[ inactiveReservoir ].flushCount--; + if ( 0 == reservoirStatus[ inactiveReservoir ].flushCount ) { - reservoirFilledStatus[ DG_RESERVOIR_1 ] = TRUE; + reservoirStatus[ inactiveReservoir ].flushComplete = 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 = (U32)activeReservoir; + rsrvrCmd.useLastTrimmerHeaterDC = FALSE; + cmdSetDGActiveReservoir( &rsrvrCmd ); } } @@ -1210,7 +1237,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 +1266,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 +1299,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 @@ -1281,52 +1308,50 @@ { U32 volume = 0; - // Fill volumes after flushing - if ( TRUE == reservoirFlushedStatus[ inactiveRes ] ) - { - 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 - } - // 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 - } - } - // 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 - } + // Fill volumes after flushing + if ( TRUE == reservoirStatus[ inactiveRes ].flushComplete ) + { + #ifndef _RELEASE_ + if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) || + ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_WET_SELF_TEST ) ) ) + { + if ( DG_RESERVOIR_1 == inactiveRes ) + { + volume = PRE_TREATMENT_FULL_RESERVOIR_VOLUME_ML; + } + // Reservoir 2 + else + { + volume = PRE_TREATMENT_MIN_FILL_RESERVOIR_VOLUME_ML; + } + } + else + #endif + { + if ( DG_RESERVOIR_1 == inactiveRes ) + { + volume = PRE_TREATMENT_FILL_RESERVOIR_ONE_VOLUME_ML; + } + // Reservoir 2 + else + { + volume = PRE_TREATMENT_FILL_RESERVOIR_TWO_VOLUME_ML; + } + } + } + // Flush fill volumes + else + { + volume = PRE_TREATMENT_FLUSH_RESERVOIR_VOLUME_ML; + } - return volume; + return volume; } - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ - /*********************************************************************//** * @brief * The testSetPreTreatmentModePublishIntervalOverride function sets the override of the Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -rceeba51c01b896855eb03ab81281a2b0f48c75d2 -r2f4f66fcceb986cc592693b08f1b57767cb1c515 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision ceeba51c01b896855eb03ab81281a2b0f48c75d2) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 2f4f66fcceb986cc592693b08f1b57767cb1c515) @@ -980,6 +980,8 @@ sendTreatmentLogEventData( TREATMENT_DURATION_CHANGE_EVENT, ( presTreatmentTimeSecs / SEC_PER_MIN ), treatmentTime ); presMaxUFVolumeML = uFVolume; presTreatmentTimeSecs = treatmentTime * SEC_PER_MIN; + setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); + setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, ( presTreatmentTimeSecs / SEC_PER_MIN ) ); setDialysisParams( getTreatmentParameterU32( TREATMENT_PARAM_BLOOD_FLOW ), getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presMaxUFVolumeML, presUFRate ); } else @@ -1135,8 +1137,10 @@ * @brief * The verifyUFSettingsConfirmation function verifies the user confirmed * ultrafiltration settings change(s) and, if valid, accepts the new settings. - * @details Inputs: current operating mode, treatment states and parameters - * @details Outputs: response message sent + * @details Inputs: current operating mode, treatment states and parameters, + * pendingUFVolumeChange, pendingUFRateChange + * @details Outputs: response message sent, presMaxUFVolumeML, + * presTreatmentTimeSecs, presUFRate * @param uFVolume New ultrafiltration volume confirmed by the user * @param adjustment The adjustment selected by the user * @return TRUE if new UF settings accepted, FALSE if not. @@ -1156,11 +1160,13 @@ sendTreatmentLogEventData( UF_VOLUME_CHANGE_EVENT, presMaxUFVolumeML, pendingUFVolumeChange ); result = TRUE; presMaxUFVolumeML = pendingUFVolumeChange; + setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, ( presMaxUFVolumeML / (F32)ML_PER_LITER ) ); // Which setting does user want to adjust to accommodate the UF volume change? (treatment time or UF rate) if ( UF_ADJ_TREATMENT_TIME == adjustment ) { presTreatmentTimeSecs = pendingTreatmentTimeChange * SEC_PER_MIN; + setTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION, ( presTreatmentTimeSecs / SEC_PER_MIN ) ); } else // Must be adjusting UF rate then { Index: firmware/App/Modes/Prime.c =================================================================== diff -u -rf760ffc4b10556e5186e9ceb90294262063440ca -r2f4f66fcceb986cc592693b08f1b57767cb1c515 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision f760ffc4b10556e5186e9ceb90294262063440ca) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 2f4f66fcceb986cc592693b08f1b57767cb1c515) @@ -46,6 +46,7 @@ #define BLOOD_PUMP_FAST_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump fast flow rate during prime recirculate blood circuit state. #define BLOOD_PUMP_FLOW_RATE_SALINE_DIALYZER_ML_MIN 300 ///< Blood pump flow rate during prime the saline dialyzer dialysate state. #define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. +#define DIALYSATE_PUMP_FAST_PRIME_FLOW_RATE_ML_MIN 600 ///< Dialysate pump flow rate during priming fluid path. #define DPO_PUMP_PRIME_FLOW_RATE_ML_MIN 225 ///< Dialysate outlet pump flow rate needed to match PWM with dialysate inlet pump @ 300 mL/min in open loop mode. #define DIALYSATE_DIALYZER_TUBE_VOLUME_ML 115 ///< This total tube volume is used to calculate the Dpi & Dpo time out in the dialysate dialyzer state. @@ -57,7 +58,7 @@ #define PURGE_AIR_TIME_OUT_COUNT ( 240 * MS_PER_SECOND ) ///< Time period count for purge air time out. #define PRIME_SALINE_DIALYZER_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for prime saline dialyzer time out. #define LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ( 1 * MS_PER_SECOND ) ///< Time load cell reading steady state detection sampling time in seconds. -#define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 15 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. +#define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 8 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. #define STEADY_VOLUME_COUNT_SEC ( 10000 / LOAD_CELL_STEADY_VOLUME_SAMPLING_TIME ) ///< Counter must be greater than 10 seconds before steady volume is true. #define STEADY_VOLUME_TIME_DEADLINE_MS ( 55 * MS_PER_SECOND ) ///< Time in msec for the steady volume deadline time out. @@ -695,7 +696,7 @@ if ( TRUE == getReservoirFillStatus( DG_RESERVOIR_1 ) ) { - if ( TRUE == hasDGCompletedReservoirSwitch() ) + if ( ( TRUE == hasDGCompletedReservoirSwitch() ) && ( DG_RESERVOIR_1 == getDGActiveReservoir() ) ) { U32 dialyzerDialysateVolume = getDialyzerDialysateVolume(); @@ -875,17 +876,10 @@ if ( TRUE == getReservoirFillStatus( DG_RESERVOIR_2 ) ) { - DG_SWITCH_RSRVRS_CMD_T rsrvrCmd; - - rsrvrCmd.reservoirID = (U32)DG_RESERVOIR_1; - rsrvrCmd.useLastTrimmerHeaterDC = FALSE; - - cmdSetDGActiveReservoir( &rsrvrCmd ); - - if ( TRUE == hasDGCompletedReservoirSwitch() ) + if ( ( TRUE == hasDGCompletedReservoirSwitch() ) && ( DG_RESERVOIR_2 == getDGActiveReservoir() ) ) { signalBloodPumpHardStop(); - setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( DIALYSATE_PUMP_FAST_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -rceeba51c01b896855eb03ab81281a2b0f48c75d2 -r2f4f66fcceb986cc592693b08f1b57767cb1c515 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision ceeba51c01b896855eb03ab81281a2b0f48c75d2) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 2f4f66fcceb986cc592693b08f1b57767cb1c515) @@ -75,8 +75,10 @@ #define WET_SELF_TEST_SECOND_DISPLACEMENT_TARGET_VOLUME_ML 600.0F ///< Target of second displacement volume in ml. #define WET_SELF_TEST_INTEGRATED_VOLUME_PCT_TOLERANCE 0.10F ///< Tolerance on integrated volume as a percentage (10%). #define WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE 20.0F ///< Tolerance on integrated volume in grams. +#define WET_SELF_TEST_INTEGRATED_VOLUME_WIDER_TOLERANCE 100.0F ///< Wider tolerance on integrated volume in grams, during debug. #define WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G 20.0F ///< Tolerance in the load cell readings of the displacement in grams. -#define WET_SELF_TEST_DISPLACEMENT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Time to displace dialysate in wet self-test in ms. +#define WET_SELF_TEST_FIRST_DISPLACEMENT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Time to displace dialysate in wet self-test in ms (first). +#define WET_SELF_TEST_SECOND_DISPLACEMENT_TIME_MS ( 30 * MS_PER_SECOND ) ///< Time to displace dialysate in wet self-test in ms (second). #define RESERVOIR_SETTLE_TIME_MS ( 5 * MS_PER_SECOND ) ///< Time allotted for reservoir to settle in ms. #define MAX_NO_CARTRIDGE_SELF_TEST_TIME 30 ///< Maximum no cartridge self-test time (in seconds). @@ -592,7 +594,8 @@ WET_SELF_TESTS_STATE_T priorSubState = currentWetSelfTestsState; #ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WET_SELF_TEST ) == SW_CONFIG_ENABLE_VALUE ) + if ( ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRIMING ) ) || + ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_WET_SELF_TEST ) ) ) { currentWetSelfTestsState = WET_SELF_TESTS_COMPLETE_STATE; } @@ -924,6 +927,13 @@ else #endif { +#ifndef _RELEASE_ + if ( SW_CONFIG_DISABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) // Allow res 1&2 fills now if air pump not disabled +#endif + { + signalAllowDGFillRes1(); + signalAllowDGFillRes2(); + } state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; } } @@ -1043,7 +1053,7 @@ else { #ifndef _RELEASE_ - if ( SW_CONFIG_DISABLE_VALUE != getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) { // Wait for reservoirs to drain before starting this test @@ -1445,7 +1455,14 @@ { state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 3 seconds has elapsed - signalActionToResumeFill(); +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) // if no air pump, now we can allow fills to start + { + signalAllowDGFlushFills(); + signalAllowDGFillRes1(); + signalAllowDGFillRes2(); + } +#endif } else { @@ -1467,7 +1484,14 @@ } else { - signalActionToResumeFill(); +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_AIR_PUMP ) ) // if no air pump, now we can allow fills to start + { + signalAllowDGFlushFills(); + signalAllowDGFillRes1(); + signalAllowDGFillRes2(); + } +#endif state = DRY_SELF_TESTS_COMPLETE_STATE; } @@ -1763,13 +1787,11 @@ // Once we've settled (5 sec), integrate flow to volume over duration of fluid transfer if ( 0 == settleStartTime ) { - // This is not a volume for now and it is a flow rate. - fmdIntegratedVolume += getMeasuredDialInFlowRate(); + fmdIntegratedVolume += ( getMeasuredDialInFlowRate() / (F32)( ( SEC_PER_MIN * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ); - if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ) + if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_FIRST_DISPLACEMENT_TIME_MS ) ) { signalDialInPumpHardStop(); - fmdIntegratedVolume = ( ( fmdIntegratedVolume * TASK_GENERAL_INTERVAL ) / ( WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ); settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_FIRST_DISPLACEMENT_VERIFY_STATE; } @@ -1815,7 +1837,7 @@ #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WET_SELF_TEST_WIDER_VOLUME_TOL ) ) { - integrateVolumeToleranceG = 50.0F; + integrateVolumeToleranceG = WET_SELF_TEST_INTEGRATED_VOLUME_WIDER_TOLERANCE; } #endif @@ -1916,12 +1938,11 @@ if ( 0 == settleStartTime ) { - fmdIntegratedVolume += getMeasuredDialInFlowRate(); + fmdIntegratedVolume += ( getMeasuredDialInFlowRate() / (F32)( ( SEC_PER_MIN * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ); - if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ) + if ( TRUE == didTimeout( displacementStartTime, WET_SELF_TEST_SECOND_DISPLACEMENT_TIME_MS ) ) { signalDialInPumpHardStop(); - fmdIntegratedVolume = ( ( fmdIntegratedVolume * TASK_GENERAL_INTERVAL ) / ( WET_SELF_TEST_DISPLACEMENT_TIME_MS ) ); settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_SECOND_DISPLACEMENT_VERIFY_STATE; } @@ -1957,7 +1978,7 @@ #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_WET_SELF_TEST_WIDER_VOLUME_TOL ) ) { - integrateVolumeToleranceG = 50.0F; + integrateVolumeToleranceG = WET_SELF_TEST_INTEGRATED_VOLUME_WIDER_TOLERANCE; } #endif