Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r656e6c800f80af3f5fc318051356f87832219689 -r32309398e7ef59471bd624e34ab6b91cdaaf9d24 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 656e6c800f80af3f5fc318051356f87832219689) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 32309398e7ef59471bd624e34ab6b91cdaaf9d24) @@ -96,6 +96,7 @@ // ***************** zeroing status *************** // #define BLD_NOMINAL_INTENSITY 930 ///< Blood leak nominal intensity. +#define BLD_MAX_INTENSITY_DRIFT_AFTER_ZEROING ( BLD_NOMINAL_INTENSITY * 0.01F ) ///< Blood leak max intensity drift after zeroing. #define BLD_MAX_INTENSITY_OUT_OF_RANGE 0.40F ///< Blood leak maximum allowed intensity. #define BLD_MIN_INTENSITY_OUT_OF_RANGE 0.35F ///< Blood leak minimum allowed intensity. #define BLD_ZERO_MIN_INTERVAL_MS ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Blood leak zeroing minimum interval in milliseconds. @@ -231,7 +232,6 @@ static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ); static BOOL isDialysateLineInBypass( void ); static void processBloodLeakIntensityData( void ); -static void checkBloodLeakDrift( void ); static void signalEmbModeCmdRespConsumed( U08 cmd ); /*********************************************************************//** @@ -401,7 +401,7 @@ *************************************************************************/ BOOL zeroBloodLeak( void ) { - BOOL status = TRUE; + BOOL status = FALSE; if ( getAvailableEmbModeQueueCount() >= BLOOD_LEAK_EMB_MODE_ZERO_CMD_RQRD_Q ) { @@ -462,6 +462,21 @@ return status; } +BLOOD_LEAK_INTENSITY_CHECK_T getBloodLeakIntensityStatusAfterZeroing( void ) +{ + BLOOD_LEAK_INTENSITY_CHECK_T status = BLOOD_LEAK_INTENSITY_WAIT_FOR_FRESH_DATA; + + if ( TRUE == bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].isCmdRespRdy ) + { + U32 intensity = bloodLeakEmbModeCmd[ I_EMB_MODE_CMD ].commandResp; + + status = ( abs( BLD_NOMINAL_INTENSITY - intensity ) <= BLD_MAX_INTENSITY_DRIFT_AFTER_ZEROING ? BLOOD_LEAK_INTENSITY_IN_RANGE : + BLOOD_LEAK_INTENSITY_OUT_OF_RANGE ); + } + + return status; +} + /*********************************************************************//** * @brief * The exitBloodLeakNormalState requests that the blood leak sensor to exit @@ -726,8 +741,6 @@ bloodLeakPersistenceCtr = 0; } - checkBloodLeakDrift(); - switch ( getCurrentOperationMode() ) { case MODE_TREA: @@ -868,6 +881,39 @@ /*********************************************************************//** * @brief + * The isBloodLeakZeroingNeeded function checks whether blood leak zeroing + * is needed in terms of drift. + * @details Inputs: bloodLeakZeroingStatus + * @details Outputs: bloodLeakZeroingStatus + * @return TRUE if blood leak zeroing is needed otherwise, FALSE + *************************************************************************/ +BOOL isBloodLeakZeroingNeeded( void ) +{ + BOOL status = FALSE; + BOOL isZeroingNeeded = TRUE; + U32 setPoint = bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].commandResp; + F32 driftMinFromTop = BLD_NOMINAL_INTENSITY - ( setPoint * BLD_MAX_INTENSITY_OUT_OF_RANGE ); + F32 driftMaxFromTop = BLD_NOMINAL_INTENSITY - ( setPoint * BLD_MIN_INTENSITY_OUT_OF_RANGE ); + BOOL isZeroingAllowed = didTimeout( bloodLeakZeroingStatus.lastZeroingStartTimeMS, BLD_ZERO_MIN_INTERVAL_MS ); + + isZeroingNeeded &= ( bloodLeakZeroingStatus.intensityMovingAverage >= driftMinFromTop ? TRUE : FALSE ); + isZeroingNeeded &= ( bloodLeakZeroingStatus.intensityMovingAverage <= driftMaxFromTop ? TRUE : FALSE ); + + if ( FALSE == isZeroingNeeded ) + { + bloodLeakZeroingStatus.driftInRangeStartTimeMS = getMSTimerCount(); + } + + if ( ( TRUE == isZeroingAllowed ) && ( TRUE == didTimeout( bloodLeakZeroingStatus.driftInRangeStartTimeMS, BLD_ZERO_IN_RANGE_DRIFT_TIMEOUT_MS ) ) ) + { + status = TRUE; + } + + return status; +} + +/*********************************************************************//** + * @brief * The handleBloodLeakEmbModeWaitForCommandState function handles the wait for * command state. The state prepares the message to be sent to the blood leak * sensor. @@ -1607,10 +1653,6 @@ { enqueueEmbModeCmd( V_EMB_MODE_CMD ); } - //else if ( 2 == bloodLeakEmbModeInfoCmdCounter ) - //{ - // enqueueEmbModeCmd( D_EMB_MODE_CMD ); - //} // Set the timer for the next time out to enqueue // Reset the counter. The counter starts from 0 @@ -1690,39 +1732,8 @@ signalEmbModeCmdRespConsumed( I_EMB_MODE_CMD ); } } - /*********************************************************************//** * @brief - * The checkBloodLeakDrift function checks for blood leak drift and if the - * conditions are met, it proceeds with requesting the zero sequence again. - * @details Inputs: bloodLeakZeroingStatus - * @details Outputs: bloodLeakZeroingStatus - * @return none - *************************************************************************/ -static void checkBloodLeakDrift( void ) -{ - BOOL isZeroingNeeded = TRUE; - U32 setPoint = bloodLeakEmbModeCmd[ SP_EMB_MODE_CMD ].commandResp; - F32 driftMinFromTop = BLD_NOMINAL_INTENSITY - ( setPoint * BLD_MAX_INTENSITY_OUT_OF_RANGE ); - F32 driftMaxFromTop = BLD_NOMINAL_INTENSITY - ( setPoint * BLD_MIN_INTENSITY_OUT_OF_RANGE ); - BOOL isZeroingAllowed = didTimeout( bloodLeakZeroingStatus.lastZeroingStartTimeMS, BLD_ZERO_MIN_INTERVAL_MS ); - - isZeroingNeeded &= ( bloodLeakZeroingStatus.intensityMovingAverage >= driftMinFromTop ? TRUE : FALSE ); - isZeroingNeeded &= ( bloodLeakZeroingStatus.intensityMovingAverage <= driftMaxFromTop ? TRUE : FALSE ); - - if ( FALSE == isZeroingNeeded ) - { - bloodLeakZeroingStatus.driftInRangeStartTimeMS = getMSTimerCount(); - } - - if ( ( TRUE == isZeroingAllowed ) && ( TRUE == didTimeout( bloodLeakZeroingStatus.driftInRangeStartTimeMS, BLD_ZERO_IN_RANGE_DRIFT_TIMEOUT_MS ) ) ) - { - zeroBloodLeak(); - } -} - -/*********************************************************************//** - * @brief * The signalEmbModeCmdRespConsumed function sets the cmd response ready flag * to false its flag that fresh data is ready. * @details Inputs: none Index: firmware/App/Controllers/BloodLeak.h =================================================================== diff -u -rfcfcd7619185b71aa2163c3e22e4b7bff730041c -r32309398e7ef59471bd624e34ab6b91cdaaf9d24 --- firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision fcfcd7619185b71aa2163c3e22e4b7bff730041c) +++ firmware/App/Controllers/BloodLeak.h (.../BloodLeak.h) (revision 32309398e7ef59471bd624e34ab6b91cdaaf9d24) @@ -39,8 +39,17 @@ BLOOD_LEAK_DETECTED = 0, ///< Blood leak detector senses blood. BLOOD_LEAK_NOT_DETECTED, ///< Blood leak detector does not sense any blood. NUM_OF_BLOOD_LEAK_STATUS ///< Number of blood leak detector status. -} BLOOD_LEAK_STATUS_T; +} BLOOD_LEAK_STATUS_T; +/// TODO comments +typedef enum IntesityDataCheckSatus +{ + BLOOD_LEAK_INTENSITY_WAIT_FOR_FRESH_DATA = 0, + BLOOD_LEAK_INTENSITY_IN_RANGE, + BLOOD_LEAK_INTENSITY_OUT_OF_RANGE, + NUM_OF_BLOOD_LEAK_INTENSITY_DATA +} BLOOD_LEAK_INTENSITY_CHECK_T; + /// Blood leak detector data publish typedef struct { @@ -59,8 +68,10 @@ void execBloodLeak( void ); void execBloodLeakEmbModeCommand( void ); BOOL zeroBloodLeak( void ); -void zeroBloodLeakReset (void ); +void zeroBloodLeakReset( void ); BOOL hasBloodLeakZeroSequenceFailed( void ); +BLOOD_LEAK_INTENSITY_CHECK_T getBloodLeakIntensityStatusAfterZeroing( void ); +BOOL isBloodLeakZeroingNeeded( void ); void exitBloodLeakNormalState( void ); Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r8cf0fafa78ce14b5dbdf95510e957846660ac2b9 -r32309398e7ef59471bd624e34ab6b91cdaaf9d24 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 8cf0fafa78ce14b5dbdf95510e957846660ac2b9) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 32309398e7ef59471bd624e34ab6b91cdaaf9d24) @@ -74,6 +74,24 @@ /// 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. + +typedef enum BloodLeakZeroingState +{ + BLD_ZEROING_FLUSH = 0, + BLD_ZEROING_ZERO, + BLD_ZEROING_VERIFY_SEQ, + BLD_ZEROING_VERIFY_INTENSITY, + BLD_ZEROING_COMPLETE, + NUM_OF_BLD_ZEROING +} BLOOD_LEAK_ZEROING_STATE_T; + +typedef struct +{ + F32 DPiToBLDFlushedVolML; + BLOOD_LEAK_ZEROING_STATE_T bloodLeakZeroingState; +} BLOOD_LEAK_ZEROING_T ; + // ********** private data ********** static TREATMENT_STATE_T currentTreatmentState; ///< Current state (sub-mode) of treatment mode. @@ -132,6 +150,8 @@ static U32 treatmentStartTimeStamp; ///< Treatment start timestampt for logging purpose. static U32 treatmentEndTimeStamp; ///< Treatment end timestampt for logging purpose. +static BLOOD_LEAK_ZEROING_T bloodLeakZeroing; + // ********** private function prototypes ********** static void broadcastTreatmentSettingsRanges( void ); @@ -146,6 +166,7 @@ static TREATMENT_STATE_T handleTreatmentEndState( void ); static void resetSignalFlags( void ); static void resetAlarmSignalFlags( void ); +static BOOL hasDPiToBLDVolumeBeenFlushed( void ); /*********************************************************************//** * @brief @@ -1501,6 +1522,62 @@ } } +void handleBloodLeakZeroing( void ) +{ + BOOL status = FALSE; + + switch( bloodLeakZeroing.bloodLeakZeroingState ) + { + case BLD_ZEROING_FLUSH: + status = hasDPiToBLDVolumeBeenFlushed(); + bloodLeakZeroing.bloodLeakZeroingState = ( TRUE == status ? BLD_ZEROING_ZERO : BLD_ZEROING_FLUSH ); + break; + + case BLD_ZEROING_ZERO: + status = zeroBloodLeak(); + bloodLeakZeroing.bloodLeakZeroingState = ( TRUE == status ? BLD_ZEROING_VERIFY_SEQ : BLD_ZEROING_ZERO ); + break; + + case BLD_ZEROING_VERIFY_SEQ: + { + SELF_TEST_STATUS_T status = getBloodLeakSelfTestStatus(); + + if ( SELF_TEST_STATUS_PASSED == status ) + { + bloodLeakZeroing.bloodLeakZeroingState = BLD_ZEROING_VERIFY_INTENSITY; + } + else if ( SELF_TEST_STATUS_FAILED == status ) + { + if ( TRUE == hasBloodLeakZeroSequenceFailed() ) + { + activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SENSOR_ZERO_SEQUENCE_FAILED ); + } + else + { + bloodLeakZeroing.bloodLeakZeroingState = BLD_ZEROING_ZERO; + } + } + } + break; + + case BLD_ZEROING_VERIFY_INTENSITY: + if ( BLOOD_LEAK_INTENSITY_IN_RANGE == getBloodLeakIntensityStatusAfterZeroing() ) + { + bloodLeakZeroing.bloodLeakZeroingState = BLD_ZEROING_COMPLETE; + } + else + { + // TODO can we try intensity for 3 times too? + // TODO alarm for intensity failure + } + break; + + default: + // TODO software fault + break; + } +} + /*********************************************************************//** * @brief * The broadcastTreatmentSettingsRanges function computes and broadcasts @@ -1658,7 +1735,23 @@ endTreatmentAlarmResponseRequest = FALSE; } +static BOOL hasDPiToBLDVolumeBeenFlushed( void ) +{ + BOOL status = FALSE; + F32 targetDPiMLPM = (F32)abs( getTargetDialInFlowRate() ); + F32 measuredDPiMLPM = getMeasuredDialInFlowRate(); + BOOL hasTargetFlowBeenReached = ( fabs( targetDPiMLPM - measuredDPiMLPM ) < NEARLY_ZERO ); + 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 = 0.0F; + } + + return status; +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/ModeTreatment.h =================================================================== diff -u -r20d0c02f453b6dae1884fb1b5ba542053852ffc1 -r32309398e7ef59471bd624e34ab6b91cdaaf9d24 --- firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 20d0c02f453b6dae1884fb1b5ba542053852ffc1) +++ firmware/App/Modes/ModeTreatment.h (.../ModeTreatment.h) (revision 32309398e7ef59471bd624e34ab6b91cdaaf9d24) @@ -130,6 +130,8 @@ void broadcastTreatmentTimeAndState( void ); // Broadcast the times and states of this treatment +void handleBloodLeakZeroing( void ); + BOOL verifyTreatmentDurationSettingChange( U32 treatmentTime ); BOOL verifyUFSettingsChange( F32 uFVolume ); BOOL verifyUFSettingsConfirmation( F32 uFVolume, U32 adjustment ); Index: firmware/App/Modes/TreatmentStop.c =================================================================== diff -u -r736cc5b56cc9c784ab1d8fc8687a73d190c35759 -r32309398e7ef59471bd624e34ab6b91cdaaf9d24 --- firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 736cc5b56cc9c784ab1d8fc8687a73d190c35759) +++ firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 32309398e7ef59471bd624e34ab6b91cdaaf9d24) @@ -427,6 +427,8 @@ { TREATMENT_STOP_STATE_T result = TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE; + handleBloodLeakZeroing(); + // Keep reseting the blood sitting timer handleTreatmentStopBloodSittingTimer(); result = handleTreatmentStopAlarmsAndSignals( result );