Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r07a39ac5f935a84b2dbb93e3f3d3b3eaa8f37cc4 -r90d598a098a5454769a7eabb8ba2b4595afe47a6 --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 07a39ac5f935a84b2dbb93e3f3d3b3eaa8f37cc4) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 90d598a098a5454769a7eabb8ba2b4595afe47a6) @@ -59,6 +59,7 @@ #define BLOOD_LEAK_SELF_TEST_CMD_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak self test command timeout in milliseconds. #define BLOOD_LEAK_BETWEEN_ZERO_ST_WAIT_MS 250 ///< Blood leak wait time in between zero and self test commands in milliseconds. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. +#define BLOOD_LEAK_DETECT_RECOVERY_MIN_TIME_MS ( 2 * MS_PER_SECOND ) ///< Blood leak blood detect recovery minimum time in milliseconds. // Embedded mode defines #define BLOOD_LEAK_EMB_MODE_CMD_SEQ_LENGTH 6 ///< Blood leak embedded mode command sequence length. @@ -92,9 +93,6 @@ #define BLOOD_LEAK_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Blood leak embedded mode FPGA error timeout in milliseconds. #define BLOOD_LEAK_RXFIFO_COUNT_MASK 0x03FF ///< Mask high order bits of blood leak sensor rx count -#define MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Blood Leak comm failures window -#define MAX_BLOOD_LEAK_COMM_FAILURES 10 ///< Blood Leak maximum comm failures per MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS - /// Defined states for the blood leak detector state machine. typedef enum BloodLeakStates { @@ -160,6 +158,7 @@ static U08 bloodLeakSetPointSequence[ BLOOD_LEAK_SET_POINT_SEQ_MAX_LENGTH ][ 2 ]; ///< Blood leak set point sequence array. static HD_BLOOD_LEAK_SENSOR_CAL_RECORD_T bloodLeakCalRecord; ///< Blood leak calibration record structure. static BOOL bloodLeakExitNormalRequested; ///< Blood leak exit normal state requested. +static U32 bloodLeakRecoveryStartTimeMS; ///< Blood leak recovery start time in milliseconds. // Embedded mode variables static BOOL bloodLeakSignalEmbModeReq; ///< Blood leak signal embedded mode has been requested. @@ -207,6 +206,7 @@ static void enqueueInfoEmbModeCmds( void ); static U16 getBloodLeakRxBytesAvailable( void ); static void resetEmbModeCmdRqstCount( U08 cmd ); +static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ); /*********************************************************************//** * @brief @@ -221,7 +221,7 @@ * bloodLeakEmbModeRespBuffer, bloodLeakEmbModeRespIndex, * bloodLeakExitNormalRequested, bloodLeakEmbModeCmdSeqLength, * bloodLeakEmbModeHasRxRqstBeenSent, bloodLeakEmbModeInfoCmdEnqLastTimeStamp, - * bloodLeakEmbModeInfoCmdCounter + * bloodLeakEmbModeInfoCmdCounter, bloodLeakRecoveryStartTimeMS * @return none *************************************************************************/ void initBloodLeak( void ) @@ -254,6 +254,7 @@ bloodLeakEmbModeCmdEnqueueCount = 0; bloodLeakEmbModeInfoCmdEnqLastTimeStamp = getMSTimerCount(); bloodLeakEmbModeInfoCmdCounter = 0; + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); // Set the blood leak embedded mode command queue to zero memset( bloodLeakEmbModeCmdQ, 0x0, BLOOD_LEAK_EMB_MODE_CMD_Q_MAX_SIZE ); @@ -270,9 +271,6 @@ // Enqueue the commands to set the embedded mode and request the set point of the blood leak sensor enqueueEmbModeCmd( CS_EMB_MODE_CMD ); enqueueEmbModeCmd( D_EMB_MODE_CMD ); - - // initialize FPGA comm failures windowed timer count - initTimeWindowedCount( TIME_WINDOWED_COUNT_BLOOD_LEAK_COMM_ERROR, MAX_BLOOD_LEAK_COMM_FAILURES, MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS ); } /*********************************************************************//** @@ -313,6 +311,10 @@ bloodLeakState = handleBloodLeakNormalState(); break; + case BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE: + bloodLeakState = handleBloodLeakRecoverBloodDetectState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_BLOOD_LEAK_STATE, bloodLeakState ) bloodLeakState = BLOOD_LEAK_INIT_STATE; @@ -663,8 +665,7 @@ { BLOOD_LEAK_STATE_T state = BLOOD_LEAK_NORMAL_STATE; - // If the blood leak status bit is low (0) it means blood has not been detected, otherwise, blood has been detected - bloodLeakStatus.data = ( BLOOD_LEAK_STATUS_BIT_LOW == getFPGABloodLeakStatus() ? BLOOD_LEAK_NOT_DETECTED : BLOOD_LEAK_DETECTED ); + bloodLeakStatus.data = getFPGABloodDetectProcessedStatus(); if ( STATE_OPEN == getSwitchStatus( PUMP_TRACK_SWITCH ) ) { @@ -684,7 +685,8 @@ #endif { activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); - exitBloodLeakNormalState(); // so we don't keep triggering after user clears it (rinseback or end tx). + state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + //exitBloodLeakNormalState(); // so we don't keep triggering after user clears it (rinseback or end tx). // TODO remove } } } @@ -720,9 +722,43 @@ return state; } +/*********************************************************************//** + * @brief + * The handleBloodLeakRecoverBloodDetectState function handles the blood + * leak recover blood detect state. + * @details Inputs: bloodLeakStatus, bloodLeakRecoveryStartTimeMS + * @details Outputs: bloodLeakStatus, bloodLeakRecoveryStartTimeMS, + * bloodLeakPersistenceCtr + * @return next state + *************************************************************************/ static BLOOD_LEAK_STATE_T handleBloodLeakRecoverBloodDetectState( void ) { + BLOOD_LEAK_STATE_T state = BLOOD_LEAK_RECOVER_BLOOD_DETECT_STATE; + bloodLeakStatus.data = getFPGABloodDetectProcessedStatus(); + + if ( BLOOD_LEAK_NOT_DETECTED == getBloodLeakStatus() ) + { + if ( TRUE == didTimeout( bloodLeakRecoveryStartTimeMS, BLOOD_LEAK_DETECT_RECOVERY_MIN_TIME_MS ) ) + { + // Blood has not been detected for the specified period of time so clear the alarm condition + clearAlarmCondition( ALARM_ID_HD_BLOOD_LEAK_DETECTED ); + } + } + else + { + bloodLeakRecoveryStartTimeMS = getMSTimerCount(); + } + + if ( isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_DETECTED ) != TRUE ) + { + // Once the user hit resume, transition back to normal state to continue detecting for blood + // Reset the blood detect counter prior to transitioning + bloodLeakPersistenceCtr = 0; + state = BLOOD_LEAK_NORMAL_STATE; + } + + return state; } /*********************************************************************//** @@ -1049,17 +1085,10 @@ bloodLeakEmbModeRespBuffer[ 0 ] = BLOOD_LEAK_EMB_MODE_FAIL_ASCII; convertString2Integer( bloodLeakEmbModeRqstedCmd, length ); - sendBloodLeakEmbeddedModeCommandResponse( bloodLeakEmbModeRqstedCmd, length, bloodLeakEmbModeRespBuffer ); - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_BLOOD_LEAK_COMM_ERROR ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_BLOOD_LEAK_FPGA_FAULT, (U32)bloodLeakEmbModeRqstedCmd, (U32)MAX_BLOOD_LEAK_COMM_FAILURES_WINDOW_MS ) - } - bloodLeakEmbModeRqstedCmd = NU_EMB_MODE_CMD; state = BLOOD_LEAK_EMB_MODE_WAIT_FOR_COMAND_STATE; - } return state; @@ -1535,7 +1564,22 @@ return getFPGABloodLeakRxFIFOCount() & BLOOD_LEAK_RXFIFO_COUNT_MASK; } +/*********************************************************************//** + * @brief + * The getFPGABloodDetectProcessedStatus function returns the status of the + * blood detect from FPGA meaning the status that is read from the sensor. + * @details Inputs: none + * @details Outputs: none + * @return BLOOD_LEAK_NOT_DETECTED if blood has not been detected otherwise, + * BLOOD_LEAK_DETECTED + *************************************************************************/ +static BLOOD_LEAK_STATUS_T getFPGABloodDetectProcessedStatus( void ) +{ + // If the blood leak status bit is low (0) it means blood has not been detected, otherwise, blood has been detected + return ( BLOOD_LEAK_STATUS_BIT_LOW == getFPGABloodLeakStatus() ? BLOOD_LEAK_NOT_DETECTED : BLOOD_LEAK_DETECTED ); +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Modes/TreatmentStop.c =================================================================== diff -u -r07a39ac5f935a84b2dbb93e3f3d3b3eaa8f37cc4 -r90d598a098a5454769a7eabb8ba2b4595afe47a6 --- firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 07a39ac5f935a84b2dbb93e3f3d3b3eaa8f37cc4) +++ firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 90d598a098a5454769a7eabb8ba2b4595afe47a6) @@ -56,7 +56,7 @@ static TREATMENT_STOP_STATE_T handleTreatmentStopAlarmsAndSignals( TREATMENT_STOP_STATE_T state ); static TREATMENT_STOP_STATE_T handleTreatmentStopDialysateRecircState( void ); static TREATMENT_STOP_STATE_T handleTreatmentStopBloodRecircState( void ); -static TREATMENT_STOP_STATE_T handleTreatmentRecoverBloodDetectState( void ); +static TREATMENT_STOP_STATE_T handleTreatmentStopRecoverBloodDetectState( void ); static void setupForRecoverBloodDetectState( void ); static void handleTreatmentStopBloodSittingTimer( void ); @@ -256,7 +256,7 @@ break; case TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE: - currentTxStopState = handleTreatmentRecoverBloodDetectState(); + currentTxStopState = handleTreatmentStopRecoverBloodDetectState(); break; default: @@ -287,49 +287,42 @@ TREATMENT_STOP_STATE_T result = state; BOOL bloodRecircBlocked = isBloodRecircBlocked(); BOOL dialysateRecircBlocked = isDialysateRecircBlocked(); - BOOL isBloodDetectAlarmActive = FALSE; + if ( ( TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE != state ) && ( dialysateRecircBlocked != TRUE ) && + ( TRUE == isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ) ) && ( FALSE == isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_DETECTED ) ) ) + { + setupForRecoverBloodDetectState(); + result = TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE; + } // Both unblocked and not in recirculate both state - if ( ( TREATMENT_STOP_RECIRC_STATE != state ) && ( FALSE == dialysateRecircBlocked ) && ( FALSE == bloodRecircBlocked ) ) + else if ( ( TREATMENT_STOP_RECIRC_STATE != state ) && ( FALSE == dialysateRecircBlocked ) && ( FALSE == bloodRecircBlocked ) ) { setupForBloodRecirculationState(); setupForDialysateRecirculationState(); result = TREATMENT_STOP_RECIRC_STATE; } - // Both blocked and not in stopped state - if ( ( TREATMENT_STOP_NO_RECIRC_STATE != state ) && ( TRUE == dialysateRecircBlocked ) && ( TRUE == bloodRecircBlocked ) ) + else if ( ( TREATMENT_STOP_NO_RECIRC_STATE != state ) && ( TRUE == dialysateRecircBlocked ) && ( TRUE == bloodRecircBlocked ) ) { setupForBloodRecirculationStopState(); setupForDialysateRecirculationStopState(); result = TREATMENT_STOP_NO_RECIRC_STATE; } - // Dialysate recirculation blocked and not in blood recirc state - if ( ( TREATMENT_STOP_RECIRC_BLOOD_ONLY_STATE != state ) && - ( TRUE == dialysateRecircBlocked ) && - ( FALSE == bloodRecircBlocked ) ) + else if ( ( TREATMENT_STOP_RECIRC_BLOOD_ONLY_STATE != state ) && ( TRUE == dialysateRecircBlocked ) && + ( FALSE == bloodRecircBlocked ) ) { setupForDialysateRecirculationStopState(); result = TREATMENT_STOP_RECIRC_BLOOD_ONLY_STATE; } - // Blood recirculation blocked and not in dialysate recirc state - if ( ( TREATMENT_STOP_RECIRC_DIALYSATE_ONLY_STATE != state ) && - ( TRUE == bloodRecircBlocked ) && - ( FALSE == dialysateRecircBlocked ) ) + else if ( ( TREATMENT_STOP_RECIRC_DIALYSATE_ONLY_STATE != state ) && ( TRUE == bloodRecircBlocked ) && + ( FALSE == dialysateRecircBlocked ) ) { setupForBloodRecirculationStopState(); result = TREATMENT_STOP_RECIRC_DIALYSATE_ONLY_STATE; } - if ( ( TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE != state ) && ( dialysateRecircBlocked != TRUE ) && - ( TRUE == isAlarmActive( ALARM_ID_HD_BLOOD_LEAK_RECOVERING_PLEASE_WAIT ) ) ) - { - setupForRecoverBloodDetectState(); - result = TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE; - } - return result; } @@ -407,7 +400,15 @@ return result; } -static TREATMENT_STOP_STATE_T handleTreatmentRecoverBloodDetectState( void ) +/*********************************************************************//** + * @brief + * The handleTreatmentStopRecoverBloodDetectState function handles the recovering + * for blood detect state in treatment stop. + * @details Inputs: none + * @details Outputs: none + * @return next treatment stop state + *************************************************************************/ +static TREATMENT_STOP_STATE_T handleTreatmentStopRecoverBloodDetectState( void ) { TREATMENT_STOP_STATE_T result = TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE; @@ -416,11 +417,17 @@ return result; } +/*********************************************************************//** + * @brief + * The setupForRecoverBloodDetectState function handles the setup for + * recovering blood detection state. + * @details Inputs: none + * @details Outputs: none + * @return none + *************************************************************************/ static void setupForRecoverBloodDetectState( void ) { doorClosedRequired( TRUE, TRUE ); - // Close dialyzer inlet and go to bypass mode - setValvePosition( VDI, VALVE_POSITION_B_OPEN ); setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_BLOOD_DETECT_RECOVERY_MLPM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); }