Index: firmware/App/Modes/TreatmentStop.c =================================================================== diff -u -r3833c8a7a90288a6010a625a884048c775c598d3 -r03f5d100a81e31a02bdf549e0150ae71b9a5d5e5 --- firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 3833c8a7a90288a6010a625a884048c775c598d3) +++ firmware/App/Modes/TreatmentStop.c (.../TreatmentStop.c) (revision 03f5d100a81e31a02bdf549e0150ae71b9a5d5e5) @@ -8,7 +8,7 @@ * @file TreatmentStop.c * * @author (last) Sean Nash -* @date (last) 21-Jun-2023 +* @date (last) 11-Jul-2023 * * @author (original) Sean * @date (original) 15-Jan-2020 @@ -36,7 +36,8 @@ // ********** private definitions ********** /// Treatment stop status broadcast interval. -#define TREATMENT_STOP_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +#define TREATMENT_STOP_DATA_PUBLISH_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) +#define DIALYSATE_FLOW_RATE_FOR_BLOOD_DETECT_RECOVERY_MLPM 600 ///< Dialysate flow rate for blood detect recovery in mL/min. // ********** private data ********** @@ -52,9 +53,11 @@ static TREATMENT_STOP_STATE_T handleTreatmentStopNoRecircState( void ); static void setupForDialysateRecirculationState( void ); static void setupForBloodRecirculationState( void ); +static void setupForRecoverBloodDetectState( void ); 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 handleTreatmentStopRecoverBloodDetectState( void ); static void handleTreatmentStopBloodSittingTimer( void ); static void publishTreatmentStopData( void ); @@ -109,7 +112,7 @@ setupForDialysateRecirculationState(); - signalUserRateChange(); // so pressure limits re-stabilize + signalInitiatePressureStabilization(); // Reset saline bolus state in case alarm interrupted one resetSalineBolus(); @@ -186,6 +189,21 @@ /*********************************************************************//** * @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 ); + cmdStartDGTrimmerHeater(); + setDialInPumpTargetFlowRate( DIALYSATE_FLOW_RATE_FOR_BLOOD_DETECT_RECOVERY_MLPM, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); +} + +/*********************************************************************//** + * @brief * The setupForDialysateRecirculationStopState function sets actuators appropriately * for dialysate re-circulation stopped state. * @details Inputs: none @@ -252,6 +270,10 @@ currentTxStopState = handleTreatmentStopNoRecircState(); break; + case TREATMENT_STOP_RECOVER_BLOOD_DETECT_STATE: + currentTxStopState = handleTreatmentStopRecoverBloodDetectState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_STOP_INVALID_STATE, currentTxStopState ); break; @@ -277,38 +299,39 @@ static TREATMENT_STOP_STATE_T handleTreatmentStopAlarmsAndSignals( TREATMENT_STOP_STATE_T state ) { TREATMENT_STOP_STATE_T result = state; - BOOL bloodRecircBlocked = isBloodRecircBlocked(); - BOOL dialysateRecircBlocked = isDialysateRecircBlocked(); + BOOL bloodRecircBlocked = isBloodRecircBlocked(); + BOOL dialysateRecircBlocked = isDialysateRecircBlocked(); + 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; @@ -393,6 +416,25 @@ /*********************************************************************//** * @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; + + // Keep reseting the blood sitting timer + handleTreatmentStopBloodSittingTimer(); + result = handleTreatmentStopAlarmsAndSignals( result ); + + return result; +} + +/*********************************************************************//** + * @brief * The handleTreatmentStopBloodSittingTimer function handles the no re-circ * blood timer. It should only be called when Blood is NOT circulating. * Increments and checks for warning and alarm timeouts. Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r3833c8a7a90288a6010a625a884048c775c598d3 -r03f5d100a81e31a02bdf549e0150ae71b9a5d5e5 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 3833c8a7a90288a6010a625a884048c775c598d3) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 03f5d100a81e31a02bdf549e0150ae71b9a5d5e5) @@ -254,6 +254,33 @@ /*********************************************************************//** * @brief + * The isACPowerLost function determines whether A/C power loss has + * been detected. This function sets the alarms blocked condition to + * allow smooth alarm recovery. + * + * @details Inputs: alarmStatus + * @details Outputs: alarmsBlockedTimer + * @return TRUE if A/C power loss alarm is in effect, FALSE if not + *************************************************************************/ +BOOL isACPowerLost( void ) +{ + BOOL result = TRUE; + + // Continue to block new alarms until the alarms are cleared. + if ( ( FALSE == isAlarmConditionDetected( ALARM_ID_HD_AC_POWER_LOST ) ) && + ( FALSE == isAlarmConditionDetected( ALARM_ID_HD_AC_POWER_LOST_IN_TREATMENT ) ) ) + { + result = FALSE; + } + else + { + alarmsBlockedTimer = ALARM_BLOCKED_COUNT_AFTER_AC_RETURN; + } + return result; +} + +/*********************************************************************//** + * @brief * The activateAlarm function activates a given alarm. * @details Inputs: none * @details Outputs: alarmIsActive[], alarmStartedAt[], alarmStatus is updated @@ -262,6 +289,11 @@ *************************************************************************/ static void activateAlarm( ALARM_ID_T alarm ) { + // Block new alarms, occuring during loss of AC power + if ( ( TRUE == getCPLDACPowerLossDetected() ) ) + { + alarmsBlockedTimer = ALARM_BLOCKED_COUNT_AFTER_AC_RETURN; + } // Verify valid alarm index if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { @@ -358,12 +390,7 @@ * @return none *************************************************************************/ void activateAlarm2Data( ALARM_ID_T alarm, ALARM_DATA_T alarmData1, ALARM_DATA_T alarmData2 ) -{ - // Block if new alarms are occur during loss of AC power - if ( ( TRUE == getCPLDACPowerLossDetected() ) ) - { - alarmsBlockedTimer = ALARM_BLOCKED_COUNT_AFTER_AC_RETURN; - } +{ // Sanity check, verify valid alarm index if ( ( alarm > ALARM_ID_NO_ALARM ) && ( alarm < NUM_OF_ALARM_IDS ) ) { Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -r3833c8a7a90288a6010a625a884048c775c598d3 -r03f5d100a81e31a02bdf549e0150ae71b9a5d5e5 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 3833c8a7a90288a6010a625a884048c775c598d3) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 03f5d100a81e31a02bdf549e0150ae71b9a5d5e5) @@ -204,6 +204,7 @@ void setAlarmUserActionEnabled( ALARM_USER_ACTION_T action, BOOL enabled ); void signalAlarmSilence( ALARM_SILENCE_CMD_T cmd ); void signalAlarmUserActionInitiated( ALARM_USER_ACTION_T action ); +BOOL isACPowerLost( void ); BOOL isAlarmActive( ALARM_ID_T alarm ); BOOL isAlarmConditionDetected( ALARM_ID_T alarm ); BOOL isAnyAlarmActive( void );