Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -re86b330049966e34035f03496e40f22e6bd4e5a9 -rb71077660606609cc3b06911ad4aaa2ffaebd9f2 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision e86b330049966e34035f03496e40f22e6bd4e5a9) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision b71077660606609cc3b06911ad4aaa2ffaebd9f2) @@ -52,6 +52,9 @@ #define MAX_ACTIVE_LOAD_CELL_CHANGE_G 50.0F ///< Maximum delta between new and previous measured UF volume. +// 3.07 + 12.28 has been received from the mechanical team and 5 mL of margine has been added for safety +#define DPI_TO_BLD_VOLUME_ML ( 3.07F + 12.28F + 5.0F ) ///< Dialysate inlet pump to blood detect sensor volume in milliliters. + /// Defined states for the Load Cell cycles. typedef enum Reservoir_Steady_Cycle { @@ -62,6 +65,17 @@ // ********** private data ********** +/// Blood leak treatment zeroing data structure +typedef struct +{ + F32 DPiToBLDFlushedVolML; ///< Dialysate inlet pump to blood leak flushed volume in milliliters. + BOOL hasBloodLeakZeroingBeenCompleted; ///< Flag to indicate blood leak zeroing has been completed successfully. + BOOL hasBloodLeakZeroingBeenRequested; ///< Flag to indicate blood leak zeroing has been requested. + BOOL isZeroingRequestedFromTreatmentStop; ///< Flag to indicate blood leak zeroing has been requested from treatment stop. + BLOOD_LEAK_ZEROING_STATE_T bloodLeakZeroingState; ///< Blood leak zeroing state. + DIALYSIS_STATE_T* dialysisState; ///< Pointer to current dialysis state. +} BLOOD_LEAK_ZEROING_T ; + static DIALYSIS_STATE_T currentDialysisState; ///< Current state of the dialysis sub-mode state machine. static UF_STATE_T currentUFState; ///< Current state of the ultrafiltration state machine. static SALINE_BOLUS_STATE_T currentSalineBolusState; ///< Current state of the saline bolus state machine. @@ -91,6 +105,7 @@ static F32 totalSalineVolumeDelivered_mL; ///< Volume (mL) in total of saline delivered so far (cumulative for all boluses including current one). static F32 bolusSalineVolumeDelivered_mL; ///< Volume (mL) of current bolus delivered so far (calculated from measured blood flow rate). static U32 bolusSalineLastVolumeTimeStamp; ///< Time stamp for last saline volume update. +static BLOOD_LEAK_ZEROING_T bloodLeakZeroingStatus; ///< Blood leak zeroing status. // ********** private function prototypes ********** @@ -106,11 +121,19 @@ static SALINE_BOLUS_STATE_T handleSalineBolusInProgressState( DIALYSIS_STATE_T *dialysisState ); static SALINE_BOLUS_STATE_T handleSalineBolusMaxDeliveredState( DIALYSIS_STATE_T *dialysisState ); +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingIdleState( void ); +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingSet2BypassState( void ); +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingFlushState( void ); +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingZeroState( void ); +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingVerifyZeroingState( void ); +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingCompleteState( void ); + static void checkUFControl( void ); static void updateUFVolumes( void ); static void publishSalineBolusData( void ); static void checkLoadCellsStablePrimaryBackupDriftOutOfRange( DG_RESERVOIR_ID_T reservoirID, RESERVOIR_STEADY_CYCLE_T cycle ); +static BOOL hasDPiToBLDVolumeBeenFlushed( void ); /*********************************************************************//** * @brief @@ -166,6 +189,7 @@ } resetSalineBolus(); + resetBloodLeakZeroing(); } /*********************************************************************//** @@ -663,8 +687,8 @@ if ( ( TRUE == isBloodLeakZeroingNeeded() ) && ( DIALYSIS_UF_STATE == currentDialysisState ) ) { - requestBloodLeakZeroing(); - currentDialysisState = DIALYSIS_BLOOD_LEAK_ZEROING_STATE; + requestBloodLeakZeroing( FALSE ); + signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); } // Dialysis state machine @@ -809,11 +833,6 @@ execBloodLeakZeroing(); - if ( TRUE == isBloodLeakZeroingComplete() ) - { - result = DIALYSIS_UF_STATE; - } - return result; } @@ -1042,7 +1061,6 @@ setCurrentSubState( (U32)DIALYSIS_UF_STATE ); setCurrent4thLevelState( (U32)currentUFState ); sendOperationStatusEvent(); - } signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); // Resume dialysis @@ -1075,6 +1093,171 @@ /*********************************************************************//** * @brief + * The handleBloodLeakZeroingIdleState function handles the blood leak zeroing + * idle state. In this state the actuators and parameters are set to run + * the blood leak zeroing state machine. + * @details Inputs: bloodLeakZeroingStatus + * @details Outputs: bloodLeakZeroingStatus + * @return next state of the blood leak zeroing state + *************************************************************************/ +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingIdleState( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T state = BLD_ZEROING_IDLE; + + if ( TRUE == bloodLeakZeroingStatus.hasBloodLeakZeroingBeenRequested ) + { + bloodLeakZeroingStatus.hasBloodLeakZeroingBeenRequested = FALSE; + + // Cmd all pumps to stop + // TODO do we need to stop the dialysate pump? + //setDialInPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + stopSyringePump(); + + state = BLD_ZEROING_SET_TO_BYPASS; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakZeroingSet2BypassState function handles the blood leak zeroing + * set to bypass state. In this state, the actuators are set to in dialysate + * bypass. + * @details Inputs: none + * @details Outputs: bloodLeakZeroingStatus + * @return next state of the blood leak zeroing state + *************************************************************************/ +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingSet2BypassState( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T state = BLD_ZEROING_SET_TO_BYPASS; + + if ( FALSE == isDialOutPumpRunning() ) + { + bloodLeakZeroingStatus.DPiToBLDFlushedVolML = 0.0F; + + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + + state = BLD_ZEROING_FLUSH; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakZeroingFlushState function handles the blood leak zeroing + * flush state. In this state, the line in between the dialysate inlet pump + * to blood leak detector is flushed with new dialysate. + * @details Inputs: none + * @details Outputs: none + * @return next state of the blood leak zeroing state + *************************************************************************/ +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingFlushState( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T state = BLD_ZEROING_FLUSH; + + if ( TRUE == hasDPiToBLDVolumeBeenFlushed() ) + { + state = BLD_ZEROING_ZERO; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakZeroingZeroState function handles the blood leak zeroing + * zero state. In this state, the zero blood leak command is issued. + * @details Inputs: none + * @details Outputs: none + * @return next state of the blood leak zeroing state + *************************************************************************/ +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingZeroState( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T state = BLD_ZEROING_ZERO; + + if ( TRUE == zeroBloodLeak() ) + { + state = BLD_ZEROING_VERIFY_ZEROING; + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakZeroingVerifyZeroingState function handles the blood + * leak verifying whether zeroing was successful or not. Based on the pass + * or fail status of the blood leak zeroing the state transition occurs. + * @details Inputs: none + * @details Outputs: none + * @return next state of the blood leak zeroing state + *************************************************************************/ +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingVerifyZeroingState( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T state = BLD_ZEROING_VERIFY_ZEROING; + SELF_TEST_STATUS_T zeroSelfTestStatus = getBloodLeakSelfTestStatus(); + + if ( SELF_TEST_STATUS_PASSED == zeroSelfTestStatus ) + { + state = BLD_ZEROING_COMPLETE; + } + else if ( SELF_TEST_STATUS_FAILED == zeroSelfTestStatus ) + { + if ( TRUE == hasBloodLeakZeroSequenceFailed() ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_ZERO_SEQUENCE_FAILED ); + } + else + { + state = BLD_ZEROING_ZERO; + } + } + + return state; +} + +/*********************************************************************//** + * @brief + * The handleBloodLeakZeroingCompleteState function handles the blood + * leak complete state. The state requests a transition back to dialysis + * if the request to zero the blood leak was issued from the dialysis sub-mode. + * @details Inputs: bloodLeakZeroingStatus, autoResumeUF + * @details Outputs: bloodLeakZeroingStatus, autoResumeUF, currentUFState + * @return next state of the blood leak zeroing state + *************************************************************************/ +static BLOOD_LEAK_ZEROING_STATE_T handleBloodLeakZeroingCompleteState( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T state = BLD_ZEROING_COMPLETE; + + if ( FALSE == bloodLeakZeroingStatus.isZeroingRequestedFromTreatmentStop ) + { + *bloodLeakZeroingStatus.dialysisState = DIALYSIS_UF_STATE; + + // Resume UF if appropriate + if ( TRUE == autoResumeUF ) + { + autoResumeUF = FALSE; + currentUFState = UF_RUNNING_STATE; + //Set substate for event + setCurrentSubState( (U32)DIALYSIS_UF_STATE ); + setCurrent4thLevelState( (U32)currentUFState ); + sendOperationStatusEvent(); + } + + signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); + // Resume dialysis + transitionToDialysis(); + } + + return state; +} + +/*********************************************************************//** + * @brief * The publishSalineBolusData function handles the max saline delivered * state of the saline bolus state machine. This is a terminal state. * @details Inputs: none @@ -1267,6 +1450,88 @@ /*********************************************************************//** * @brief + * The execBloodLeakZeroing function handles the blood leak zeroing sequence + * @details Inputs: bloodLeakZeroing + * @details Outputs: bloodLeakZeroing + * @return none + *************************************************************************/ +void execBloodLeakZeroing( void ) +{ + BLOOD_LEAK_ZEROING_STATE_T prevState = bloodLeakZeroingStatus.bloodLeakZeroingState; + + switch( bloodLeakZeroingStatus.bloodLeakZeroingState ) + { + case BLD_ZEROING_IDLE: + bloodLeakZeroingStatus.bloodLeakZeroingState = handleBloodLeakZeroingIdleState(); + break; + + case BLD_ZEROING_SET_TO_BYPASS: + bloodLeakZeroingStatus.bloodLeakZeroingState = handleBloodLeakZeroingSet2BypassState(); + break; + + case BLD_ZEROING_FLUSH: + bloodLeakZeroingStatus.bloodLeakZeroingState = handleBloodLeakZeroingFlushState(); + break; + + case BLD_ZEROING_ZERO: + bloodLeakZeroingStatus.bloodLeakZeroingState = handleBloodLeakZeroingZeroState(); + break; + + case BLD_ZEROING_VERIFY_ZEROING: + bloodLeakZeroingStatus.bloodLeakZeroingState = handleBloodLeakZeroingVerifyZeroingState(); + break; + + case BLD_ZEROING_COMPLETE: + bloodLeakZeroingStatus.bloodLeakZeroingState = handleBloodLeakZeroingCompleteState(); + break; + + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_INVALID_BLOOD_LEAK_ZEROING_STATE, + bloodLeakZeroingStatus.bloodLeakZeroingState ) + break; + } + + if ( prevState != bloodLeakZeroingStatus.bloodLeakZeroingState ) + { + setCurrent4thLevelState( (U32)bloodLeakZeroingStatus.bloodLeakZeroingState ); + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, prevState, bloodLeakZeroingStatus.bloodLeakZeroingState ) + } +} + +/*********************************************************************//** + * @brief + * The requestBloodLeakZeroing function sets the flag the requests the + * blood leak zeroing. + * @details Inputs: none + * @details Outputs: bloodLeakZeroing + * @return none + *************************************************************************/ +void requestBloodLeakZeroing( BOOL isRequestFromTreatmentStop ) +{ + bloodLeakZeroingStatus.hasBloodLeakZeroingBeenRequested = TRUE; + bloodLeakZeroingStatus.isZeroingRequestedFromTreatmentStop = isRequestFromTreatmentStop; + bloodLeakZeroingStatus.dialysisState = ¤tDialysisState; +} + +/*********************************************************************//** + * @brief + * The resetBloodLeakZeroingParameters function resets the blood leak zeroing + * parameters. + * @details Inputs: none + * @details Outputs: bloodLeakZeroing + * @return none + *************************************************************************/ +void resetBloodLeakZeroing( void ) +{ + bloodLeakZeroingStatus.DPiToBLDFlushedVolML = 0.0F; + bloodLeakZeroingStatus.bloodLeakZeroingState = BLD_ZEROING_IDLE; + bloodLeakZeroingStatus.hasBloodLeakZeroingBeenCompleted = FALSE; + bloodLeakZeroingStatus.hasBloodLeakZeroingBeenRequested = FALSE; + bloodLeakZeroingStatus.isZeroingRequestedFromTreatmentStop = FALSE; +} + +/*********************************************************************//** + * @brief * The checkLoadCellsStablePrimaryBackupDriftOutOfRange function checks the * load cells' primary and backup drift when the reservoir level has been stable * for greater than large filter time. @@ -1325,4 +1590,24 @@ } } +/*********************************************************************//** + * @brief + * The hasDPiToBLDVolumeBeenFlushed function checks whether the line in + * between dialysate inlet pump to the blood leak detector has been flushed + * with fresh fluid or not. + * @details Inputs: bloodLeakZeroing + * @details Outputs: bloodLeakZeroing + * @return TRUE if the line has been flushed otherwise, FALSE + *************************************************************************/ +static BOOL hasDPiToBLDVolumeBeenFlushed( void ) +{ + BOOL status = FALSE; + F32 measuredDPiMLPM = getMeasuredDialInFlowRate(); + + bloodLeakZeroingStatus.DPiToBLDFlushedVolML += ( measuredDPiMLPM * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ); + status = ( ( bloodLeakZeroingStatus.DPiToBLDFlushedVolML - DPI_TO_BLD_VOLUME_ML ) < NEARLY_ZERO ? TRUE : FALSE ); + + return status; +} + /**@}*/