Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -rcf72c9fc8fd10c06bec1981cb26c1e653b7e8d92 -r14d1cffaeeebd5729f5c05c21b9eb1ac414b4750 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision cf72c9fc8fd10c06bec1981cb26c1e653b7e8d92) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 14d1cffaeeebd5729f5c05c21b9eb1ac414b4750) @@ -234,7 +234,7 @@ static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ); static BOOL isDialysateLineInBypass( void ); static void processBloodLeakIntensityData( void ); -static void signalEmbModeCmdRespConsumed( U08 cmd ); +static void resetEmbModeCmdRespConsumedFlag( U08 cmd ); /*********************************************************************//** * @brief @@ -1689,6 +1689,10 @@ bloodLeakEmbModeInfoCmdEnqLastTimeStamp = getMSTimerCount(); bloodLeakEmbModeInfoCmdCounter = INC_WRAP( bloodLeakEmbModeInfoCmdCounter, 0, BLOOD_LEAK_EMB_MODE_NUM_OF_INFO_CMDS - 1 ); break; + + default: + // Do nothing as the other commands are ignored + break; } } } @@ -1761,19 +1765,19 @@ bloodLeakZeroingStatus.intensityMovingAverage = (F32)bloodLeakZeroingStatus.intensityRunningSum / (F32)BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES; bloodLeakZeroingStatus.rawIntensityNextIndex = INC_WRAP( index, 0, BLD_ZERO_MVG_AVG_NUM_OF_SAMPLES - 1 ); - signalEmbModeCmdRespConsumed( I_EMB_MODE_CMD ); + resetEmbModeCmdRespConsumedFlag( I_EMB_MODE_CMD ); } } /*********************************************************************//** * @brief - * The signalEmbModeCmdRespConsumed function sets the cmd response ready flag + * The resetEmbModeCmdRespConsumedFlag function sets the cmd response ready flag * to false its flag that fresh data is ready. * @details Inputs: none * @details Outputs: bloodLeakEmbModeCmd * @param cmd the command to signal its data has been consumed * @return none *************************************************************************/ -static void signalEmbModeCmdRespConsumed( U08 cmd ) +static void resetEmbModeCmdRespConsumedFlag( U08 cmd ) { bloodLeakEmbModeCmd[ cmd ].isCmdRespRdy = FALSE; } Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r736cc5b56cc9c784ab1d8fc8687a73d190c35759 -r14d1cffaeeebd5729f5c05c21b9eb1ac414b4750 --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 736cc5b56cc9c784ab1d8fc8687a73d190c35759) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 14d1cffaeeebd5729f5c05c21b9eb1ac414b4750) @@ -19,6 +19,7 @@ #include "AirTrap.h" #include "BloodFlow.h" +#include "BloodLeak.h" #include "Buttons.h" #include "Dialysis.h" #include "DialInFlow.h" @@ -95,6 +96,7 @@ static DIALYSIS_STATE_T handleDialysisUltrafiltrationState( void ); static DIALYSIS_STATE_T handleDialysisSalineBolusState( void ); +static DIALYSIS_STATE_T handleDialysisBloodLeakZeroingState( void ); static UF_STATE_T handleUFPausedState( DIALYSIS_STATE_T *dialysisState ); static UF_STATE_T handleUFRunningState( DIALYSIS_STATE_T *dialysisState ); @@ -659,6 +661,12 @@ // Check ultrafiltration control during dialysis (even when ultrafiltration is paused). checkUFControl(); + if ( ( TRUE == isBloodLeakZeroingNeeded() ) && ( DIALYSIS_UF_STATE == currentDialysisState ) ) + { + requestBloodLeakZeroing(); + currentDialysisState = DIALYSIS_BLOOD_LEAK_ZEROING_STATE; + } + // Dialysis state machine switch ( currentDialysisState ) { @@ -670,6 +678,9 @@ currentDialysisState = handleDialysisSalineBolusState(); break; + case DIALYSIS_BLOOD_LEAK_ZEROING_STATE: + currentDialysisState = handleDialysisBloodLeakZeroingState(); + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_DIALYSIS_INVALID_STATE, currentDialysisState ) break; @@ -785,6 +796,28 @@ /*********************************************************************//** * @brief + * The handleDialysisBloodLeakZeroingState function handles the blood leak + * zeroing sub state of the state machine. + * @details Inputs: none + * @details Outputs: none + * @return next Dialysis state. + *************************************************************************/ +static DIALYSIS_STATE_T handleDialysisBloodLeakZeroingState( void ) +{ + DIALYSIS_STATE_T result = DIALYSIS_BLOOD_LEAK_ZEROING_STATE; + + execBloodLeakZeroing(); + + if ( TRUE == isBloodLeakZeroingComplete() ) + { + result = DIALYSIS_UF_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief * The handleUFPausedState function handles the Paused state of the * ultrafiltration state machine. * @details Inputs: salineBolusStartRequested Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r21c533a2c6f4cfc840a0297536c7f10a5a9fc274 -r14d1cffaeeebd5729f5c05c21b9eb1ac414b4750 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 21c533a2c6f4cfc840a0297536c7f10a5a9fc274) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 14d1cffaeeebd5729f5c05c21b9eb1ac414b4750) @@ -75,7 +75,8 @@ /// Macro to calculate the remaining treatment time in seconds. #define CALC_TREAT_TIME_REMAINING_IN_SECS() ( (S32)presTreatmentTimeSecs - (S32)( treatmentTimeMS / MS_PER_SECOND ) ) -#define DPI_TO_BLD_VOLUME_ML ( 3.07F + 12.28F ) ///< Dialysate inlet pump to blood detect sensor volume in milliliters. +// 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. /// Blood leak zeroing states typedef enum BloodLeakZeroingState @@ -94,7 +95,6 @@ F32 DPiToBLDFlushedVolML; ///< Dialysate inlet pump to blood leak flushed volume in milliliters. BOOL hasBloodLeakZeroingBeenCompleted; ///< Flag to indicate blood leak zeroing has been completed successfully. BLOOD_LEAK_ZEROING_STATE_T bloodLeakZeroingState; ///< Blood leak zeroing state. - TREATMENT_STATE_T prevTreatmentState; ///< Previous treatment state prior to transitioning to zeroing state. } BLOOD_LEAK_ZEROING_T ; // ********** private data ********** @@ -155,7 +155,7 @@ static U32 treatmentStartTimeStamp; ///< Treatment start timestampt for logging purpose. static U32 treatmentEndTimeStamp; ///< Treatment end timestampt for logging purpose. -static BLOOD_LEAK_ZEROING_T bloodLeakZeroing; ///< Blood leak zeroing. +static BLOOD_LEAK_ZEROING_T bloodLeakZeroing; ///< Blood leak zeroing status. // ********** private function prototypes ********** @@ -167,7 +167,6 @@ static TREATMENT_STATE_T handleTreatmentDialysisState( void ); static TREATMENT_STATE_T handleTreatmentStopState( void ); static TREATMENT_STATE_T handleTreatmentRinsebackState( void ); -static TREATMENT_STATE_T handleTreatmentZeroBloodLeakState( void ); static TREATMENT_STATE_T handleTreatmentRecircState( void ); static TREATMENT_STATE_T handleTreatmentEndState( void ); static void resetSignalFlags( void ); @@ -670,13 +669,6 @@ resumeBlockedByAlarm = TRUE; } - if ( TRUE == isBloodLeakZeroingNeeded() ) - { - requestBloodLeakZeroing(); - currentTreatmentState = TREATMENT_ZERO_BLOOD_LEAK_STATE; // TODO is this the right thing to change the tx state? anything else? - // TODO when we go to zeroing, shouldn't we pause the treatment time? - } - // Check dialysate temperature during treatment mode (except end state where treatment is over, dialyzer is bypassed and temp is no longer an issue) if ( currentTreatmentState != TREATMENT_END_STATE ) { @@ -706,10 +698,6 @@ currentTreatmentState = handleTreatmentRinsebackState(); break; - case TREATMENT_ZERO_BLOOD_LEAK_STATE: - currentTreatmentState = handleTreatmentZeroBloodLeakState(); - break; - case TREATMENT_RECIRC_STATE: currentTreatmentState = handleTreatmentRecircState(); break; @@ -827,8 +815,8 @@ U32 msSinceLast = calcTimeBetween( lastTreatmentTimeStamp, newTime ); DIALYSIS_STATE_T dialysisState = getDialysisState(); - // Update treatment time (unless delivering a saline bolus) - if ( dialysisState != DIALYSIS_SALINE_BOLUS_STATE ) + // Update treatment time (unless delivering a saline bolus or is in blood leak zeroing state) + if ( ( dialysisState != DIALYSIS_SALINE_BOLUS_STATE ) || ( dialysisState != DIALYSIS_BLOOD_LEAK_ZEROING_STATE ) ) { treatmentTimeMS += msSinceLast; } @@ -982,48 +970,6 @@ /*********************************************************************//** * @brief - * The handleTreatmentZeroBloodLeakState function executes the zero blood leak - * state of the state machine. - * @details Inputs: TODO fill up - * @details Outputs: TODO fill up - * @return next treatment mode state - *************************************************************************/ -static TREATMENT_STATE_T handleTreatmentZeroBloodLeakState( void ) -{ - TREATMENT_STATE_T result = TREATMENT_ZERO_BLOOD_LEAK_STATE; - - // If user requests treatment end, end treatment - if ( TRUE == endTreatmentAlarmResponseRequest ) - { - sendLastTreatmentPeriodicData = TRUE; - requestNewOperationMode( MODE_POST ); - } - else - { - // If user requests resumption of treatment, resume - if ( TRUE == resumeTreatmentAlarmResponseRequest ) - { - resumeTreatmentAlarmResponseRequest = FALSE; - //signalRinsebackAlarmResumeUserAction(); // TODO do we need one of this for zeroing? - } - execBloodLeakZeroing(); - } - - // TODO other transitions are needed too? - if ( TRUE == bloodLeakZeroing.hasBloodLeakZeroingBeenCompleted ) - { - result = bloodLeakZeroing.prevTreatmentState; - } - else if ( TRUE == endTreatmentRequest ) - { - requestNewOperationMode( MODE_POST ); - } - - return result; -} - -/*********************************************************************//** - * @brief * The handleTreatmentRecircState function executes the re-circulate state of the * Treatment Mode state machine. * @details Inputs: endTreatmentAlarmResponseRequest, rinsebackToStoppedRequest, @@ -1592,8 +1538,9 @@ *************************************************************************/ void execBloodLeakZeroing( void ) { - BOOL status = FALSE; - SELF_TEST_STATUS_T zeroStatus = getBloodLeakSelfTestStatus(); + BOOL status = FALSE; + SELF_TEST_STATUS_T zeroStatus = getBloodLeakSelfTestStatus(); + BLOOD_LEAK_ZEROING_STATE_T prevState = bloodLeakZeroing.bloodLeakZeroingState; // TODO investigate whether we need to stop the before going to bypass @@ -1602,6 +1549,7 @@ case BLD_ZEROING_SET_TO_BYPASS: // Set Dialysate valves to bypass filter for recirculation signalDialOutPumpHardStop(); + stopSyringePump(); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); bloodLeakZeroing.bloodLeakZeroingState = BLD_ZEROING_FLUSH; @@ -1644,6 +1592,12 @@ bloodLeakZeroing.bloodLeakZeroingState ) break; } + + if ( prevState != bloodLeakZeroing.bloodLeakZeroingState ) + { + setCurrent4thLevelState( (U32)bloodLeakZeroing.bloodLeakZeroingState ); + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SUB_STATE_CHANGE, prevState, bloodLeakZeroing.bloodLeakZeroingState ); + } } /*********************************************************************//** @@ -1659,11 +1613,23 @@ bloodLeakZeroing.DPiToBLDFlushedVolML = 0.0F; bloodLeakZeroing.bloodLeakZeroingState = BLD_ZEROING_SET_TO_BYPASS; bloodLeakZeroing.hasBloodLeakZeroingBeenCompleted = FALSE; - bloodLeakZeroing.prevTreatmentState = currentTreatmentState; } /*********************************************************************//** * @brief + * The isBloodLeakZeroingComplete function returns the status of the blood + * leak zeroing complete + * @details Inputs: none + * @details Outputs: bloodLeakZeroing + * @return TRUE if blood leak zeroing was complete otherwise, FALSE + *************************************************************************/ +BOOL isBloodLeakZeroingComplete( void ) +{ + return bloodLeakZeroing.hasBloodLeakZeroingBeenCompleted; +} + +/*********************************************************************//** + * @brief * The broadcastTreatmentSettingsRanges function computes and broadcasts * updated treatment parameter ranges that the user may change during treatment. * It is assumed that prescription settings have already been set prior to calling @@ -1819,18 +1785,22 @@ endTreatmentAlarmResponseRequest = FALSE; } +/*********************************************************************//** + * @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 targetDPiMLPM = (F32)abs( getTargetDialInFlowRate() ); - F32 measuredDPiMLPM = getMeasuredDialInFlowRate(); - BOOL hasTargetFlowBeenReached = ( fabs( targetDPiMLPM - measuredDPiMLPM ) < NEARLY_ZERO ); + BOOL status = FALSE; + F32 measuredDPiMLPM = getMeasuredDialInFlowRate(); - if ( TRUE == hasTargetFlowBeenReached ) - { - bloodLeakZeroing.DPiToBLDFlushedVolML += ( measuredDPiMLPM * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ); - status = ( ( bloodLeakZeroing.DPiToBLDFlushedVolML - DPI_TO_BLD_VOLUME_ML ) < NEARLY_ZERO ? TRUE : FALSE ); - } + bloodLeakZeroing.DPiToBLDFlushedVolML += ( measuredDPiMLPM * TASK_GENERAL_INTERVAL ) / ( SEC_PER_MIN * MS_PER_SECOND ); + status = ( ( bloodLeakZeroing.DPiToBLDFlushedVolML - DPI_TO_BLD_VOLUME_ML ) < NEARLY_ZERO ? TRUE : FALSE ); return status; } Index: firmware/App/Modes/ModeTreatment.h =================================================================== diff -u -r9ded16038a0d6dd844da697aaf03505ec3ed335a -r14d1cffaeeebd5729f5c05c21b9eb1ac414b4750 --- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 9ded16038a0d6dd844da697aaf03505ec3ed335a) +++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 14d1cffaeeebd5729f5c05c21b9eb1ac414b4750) @@ -132,6 +132,7 @@ void execBloodLeakZeroing( void ); void requestBloodLeakZeroing( void ); +BOOL isBloodLeakZeroingComplete( void ); BOOL verifyTreatmentDurationSettingChange( U32 treatmentTime ); BOOL verifyUFSettingsChange( F32 uFVolume );