Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1 -r3d5a2ff09f3f4983699bfc61c7b63df1732970e0 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 3d5a2ff09f3f4983699bfc61c7b63df1732970e0) @@ -15,6 +15,7 @@ * ***************************************************************************/ +#include "Buttons.h" #include "ModePreTreat.h" #include "OperationModes.h" #include "Prime.h" Index: firmware/App/Modes/ModeService.c =================================================================== diff -u -r38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1 -r3d5a2ff09f3f4983699bfc61c7b63df1732970e0 --- firmware/App/Modes/ModeService.c (.../ModeService.c) (revision 38f6b0b6ff1608eb1fd046e91add7fd2c65de4b1) +++ firmware/App/Modes/ModeService.c (.../ModeService.c) (revision 3d5a2ff09f3f4983699bfc61c7b63df1732970e0) @@ -15,6 +15,7 @@ * ***************************************************************************/ +#include "Buttons.h" #include "OperationModes.h" #include "ModeService.h" Index: firmware/App/Modes/TreatmentEnd.c =================================================================== diff -u --- firmware/App/Modes/TreatmentEnd.c (revision 0) +++ firmware/App/Modes/TreatmentEnd.c (revision 3d5a2ff09f3f4983699bfc61c7b63df1732970e0) @@ -0,0 +1,392 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file TreatmentEnd.c +* +* @author (last) Sean Nash +* @date (last) 04-Feb-2021 +* +* @author (original) Sean +* @date (original) 04-Feb-2021 +* +***************************************************************************/ + +#include "AirTrap.h" +#include "BloodFlow.h" +#include "Buttons.h" +#include "DialInFlow.h" +#include "DialOutFlow.h" +#include "ModeTreatment.h" +#include "OperationModes.h" +#include "TaskGeneral.h" +#include "TreatmentStop.h" +#include "Valves.h" + +/** + * @addtogroup TreatmentEnd + * @{ + */ + +// ********** private definitiions *********** + +/// Target flow rate for blood while waiting for user to initiate final rinseback. +#define TX_END_BP_FLOW_RATE_ML_MIN 100 + +/// Max time to wait for user to initiate final rinseback. +#define TX_END_TIMEOUT_MS ( ( 15 * 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) // TODO - get time from Systems + +// ********** private data ********** + +static TREATMENT_END_STATE_T treatmentEndState; ///< Current state of the treatment end sub-mode. + +static U32 txEndTimerCtr; ///< Timer counter (in GP task intervals) counts time spent waiting for user to initiate final rinseback. + +static BOOL txEndStopRequested; ///< Flag indicates alarm requesting to stop slow blood flow. +static BOOL txEndAlarmResumeRequested; ///< Flag indicates user requesting resume from alarm. +static BOOL txEndAlarmRinsebackRequested; ///< Flag indicates user requesting rinseback from alarm. +static BOOL txEndAlarmEndTreatmentRequested; ///< Flag indicates user requesting end treatment from alarm. +static BOOL txEndRinsebackRequested; ///< Flag indicates user requesting final rinseback. + +// ********** private function prototypes ********** + +static void resetTreatmentEndFlags( void ); + +static void setupForTxEndWait4RinsebackState( void ); +static void setupForTxEndPausedState( void ); + +static TREATMENT_END_STATE_T handleTxEndWait4RinsebackState( void ); +static TREATMENT_END_STATE_T handleTxEndPausedState( void ); + +static BOOL handleTxEndRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ); + +/*********************************************************************//** + * @brief + * The initTreatmentEnd function initializes the Treatment End sub-mode + * module. + * @details Inputs: none + * @details Outputs: Treatment Stop sub-mode module initialized. + * @return none + *************************************************************************/ +void initTreatmentEnd( void ) +{ + treatmentEndState = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE; + txEndTimerCtr = 0; + resetTreatmentEndFlags(); +} + +/*********************************************************************//** + * @brief + * The resetTreatmentEndFlags function resets the treatment end request flags. + * @details Inputs: none + * @details Outputs: Treatment end request flags reset to FALSE. + * @return none + *************************************************************************/ +static void resetTreatmentEndFlags( void ) +{ + txEndStopRequested = FALSE; + txEndAlarmResumeRequested = FALSE; + txEndAlarmRinsebackRequested = FALSE; + txEndAlarmEndTreatmentRequested = FALSE; + txEndRinsebackRequested = FALSE; +} + +/*********************************************************************//** + * @brief + * The transitionToTreatmentEnd function prepares for transition to treatment + * end sub-mode. + * @details Inputs: none + * @details Outputs: actuators set for initial state of treatment end sub-mode + * @return none + *************************************************************************/ +void transitionToTreatmentEnd( void ) +{ + // Set valves + setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); + setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); + setValvePosition( VBA, VALVE_POSITION_B_OPEN ); + setValvePosition( VBV, VALVE_POSITION_B_OPEN ); + + // Ensure all pumps except BP stopped + signalDialInPumpHardStop(); + signalDialOutPumpHardStop(); + // TODO - stop Heparin pump + setBloodPumpTargetFlowRate( TX_END_BP_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + + // Continue air trap control + startAirTrapControl(); + + // Set user alarm recovery actions allowed in this sub-mode + setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); +} + +/*********************************************************************//** + * @brief + * The setupForTxEndWait4RinsebackState function sets actuators appropriately + * for treatment end wait for rinseback state. + * @details Inputs: none + * @details Outputs: arterial and venous lines opened, blood pump started, + * and air trap leveling control is started. + * @return none + *************************************************************************/ +static void setupForTxEndWait4RinsebackState( void ) +{ + // Open VBA and VBV valves to allow flow from saline bag and to patient venous line + setValvePosition( VBA, VALVE_POSITION_B_OPEN ); + setValvePosition( VBV, VALVE_POSITION_B_OPEN ); + // Start blood pump at Tx End slow flow rate + setBloodPumpTargetFlowRate( TX_END_BP_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + // Start air trap leveling control + startAirTrapControl(); +} + +/*********************************************************************//** + * @brief + * The setupForTxEndPausedState function sets actuators appropriately + * for treatment end paused state. + * @details Inputs: none + * @details Outputs: Blood pump stopped, arterial and venous lines closed, + * and air trap leveling control is stopped. + * @return none + *************************************************************************/ +static void setupForTxEndPausedState( void ) +{ + // Stop blood pump + signalBloodPumpHardStop(); + // Close arterial and venous lines + setValvePosition( VBA, VALVE_POSITION_C_CLOSE ); + setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); + // Stop air trap leveling control + endAirTrapControl(); +} + +/*********************************************************************//** + * @brief + * The execTreatmentEnd function executes the Treatment End sub-mode + * state machine. + * @details Inputs: treatmentEndState + * @details Outputs: treatmentEndState + * @return none + *************************************************************************/ +void execTreatmentEnd( void ) +{ + txEndTimerCtr++; + + switch ( treatmentEndState ) + { + case TREATMENT_END_WAIT_FOR_RINSEBACK_STATE: + treatmentEndState = handleTxEndWait4RinsebackState(); + break; + + case TREATMENT_END_PAUSED_STATE: + treatmentEndState = handleTxEndPausedState(); + break; + + default: + // TODO - s/w fault + break; + } + + // Re-circulate flags should be handled by now - reset in case not handled by current state + resetTreatmentEndFlags(); +} + +/*********************************************************************//** + * @brief + * The handleTxEndWait4RinsebackState function handles the treatment end + * wait for rinseback state operations. + * @details Inputs: flags + * @details Outputs: flags handled + * @return next treatment end wait for rinseback state + *************************************************************************/ +static TREATMENT_END_STATE_T handleTxEndWait4RinsebackState( void ) +{ + TREATMENT_END_STATE_T result = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE; + + // Is alarm stop or user reconnect requested? + if ( TRUE == txEndStopRequested ) + { + setupForTxEndPausedState(); + result = TREATMENT_END_PAUSED_STATE; + } + // Is final rinseback requested? + else if ( ( TRUE == txEndRinsebackRequested ) || ( TRUE == txEndAlarmRinsebackRequested ) ) + { + signalGoToRinseback(); + } + // Has max time waiting for user to initiate final rinseback been exceeded? + else if ( txEndTimerCtr > TX_END_TIMEOUT_MS ) + { + activateAlarmNoData( ALARM_ID_END_TREATMENT_TIMEOUT_ALARM ); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The handleTxEndPausedState function handles the treatment end paused + * state operations. + * @details Inputs: flags + * @details Outputs: flags handled + * @return next Treatment end paused state + *************************************************************************/ +static TREATMENT_END_STATE_T handleTxEndPausedState( void ) +{ + TREATMENT_END_STATE_T result = TREATMENT_END_PAUSED_STATE; + + // Is final rinseback requested? + if ( ( TRUE == txEndRinsebackRequested ) || ( TRUE == txEndAlarmRinsebackRequested ) ) + { + signalGoToRinseback(); + } + // Is slow blood flow resume requested? + else if ( TRUE == txEndAlarmResumeRequested ) + { + setupForTxEndWait4RinsebackState(); + result = TREATMENT_END_WAIT_FOR_RINSEBACK_STATE; + } + // Is treatment end requested? + else if ( TRUE == txEndAlarmEndTreatmentRequested ) + { + signalEndTreatment(); + } + + return result; +} + +/*********************************************************************//** + * @brief + * The signalStopTreatmentEnd function signals the treatment end + * sub-mode to stop per an active alarm. + * @details Inputs: none + * @details Outputs: txEndStopRequested + * @return none + *************************************************************************/ +void signalStopTreatmentEnd( void ) +{ + txEndStopRequested = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalTreatmentEndAlarmResumeUserAction function signals the treatment end + * sub-mode to stop per an active alarm. + * @details Inputs: none + * @details Outputs: txEndAlarmResumeRequested + * @return none + *************************************************************************/ +void signalTreatmentEndAlarmResumeUserAction( void ) +{ + txEndAlarmResumeRequested = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalTreatmentEndAlarmRinsebackUserAction function signals the treatment end + * sub-mode to stop per an active alarm. + * @details Inputs: none + * @details Outputs: txEndAlarmRinsebackRequested + * @return none + *************************************************************************/ +void signalTreatmentEndAlarmRinsebackUserAction( void ) +{ + txEndAlarmRinsebackRequested = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalTreatmentEndAlarmEndTxUserAction function signals the treatment end + * sub-mode to stop per an active alarm. + * @details Inputs: none + * @details Outputs: txEndAlarmEndTreatmentRequested + * @return none + *************************************************************************/ +void signalTreatmentEndAlarmEndTxUserAction( void ) +{ + txEndAlarmEndTreatmentRequested = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalTreatmentEndUserAction function signals a treatment end user + * action has been requested. The request is handled and responded to. + * @details Inputs: none + * @details Outputs: action handled, request responded to + * @param action User action requested + * @return none + *************************************************************************/ +void signalTreatmentEndUserAction( REQUESTED_TREATMENT_RECIRC_USER_ACTIONS_T action ) +{ + BOOL accepted = FALSE; + REQUEST_REJECT_REASON_CODE_T rejReason = REQUEST_REJECT_REASON_NONE; + + // Reject user action requests if any alarm is currently active. User must clear alarm first. + if ( FALSE == isAnyAlarmActive() ) + { + switch ( action ) + { + case REQUESTED_USER_ACTION_TX_END_RINSEBACK_START: + accepted = handleTxEndRinsebackUserAction( &rejReason ); + break; + + default: + rejReason = REQUEST_REJECT_REASON_INVALID_COMMAND; + break; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_ALARM_IS_ACTIVE; + } + + // Respond to user action request + sendRinsebackCmdResponse( accepted, (U32)rejReason ); +} + +/*********************************************************************//** + * @brief + * The handleTxEndRinsebackUserAction function handles a end treatment rinseback + * user action request. It is assumed that the calling function will set + * the reject reason parameter to None beforehand. + * @details Inputs: treatmentEndState + * @details Outputs: rinseback action handled + * @param rejReason Code indicating reason for rejection + * @return TRUE if user action accepted, FALSE if not + *************************************************************************/ +static BOOL handleTxEndRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) +{ + BOOL result = FALSE; + + if ( TREATMENT_END_WAIT_FOR_RINSEBACK_STATE == treatmentEndState ) + { + result = TRUE; + txEndRinsebackRequested = TRUE; + } + else + { + *rejReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + } + + return result; +} + +/*********************************************************************//** + * @brief + * The getCurrentTreatmentEndState function returns the current state of the + * treatment end sub-mode. + * @details Inputs: treatmentEndState + * @details Outputs: none + * @return treatmentEndState + *************************************************************************/ +TREATMENT_END_STATE_T getCurrentTreatmentEndState( void ) +{ + return treatmentEndState; +} + +/**@}*/ Index: firmware/App/Modes/TreatmentEnd.h =================================================================== diff -u --- firmware/App/Modes/TreatmentEnd.h (revision 0) +++ firmware/App/Modes/TreatmentEnd.h (revision 3d5a2ff09f3f4983699bfc61c7b63df1732970e0) @@ -0,0 +1,52 @@ +/************************************************************************** +* +* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* +* THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN +* WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. +* +* @file TreatmentEnd.h +* +* @author (last) Sean Nash +* @date (last) 04-Feb-2021 +* +* @author (original) Sean +* @date (original) 04-Feb-2021 +* +***************************************************************************/ + +#ifndef __TREATMENT_END_H__ +#define __TREATMENT_END_H__ + +#include "HDCommon.h" +#include "HDDefs.h" + +/** + * @defgroup TreatmentEnd TreatmentEnd + * @brief Treatment end sub-mode of treatment mode. + * The treatment end state is where we go when treatment has completed. + * In this state, no more Heparin delivery and no more ultrafiltration. + * In this state, treatment is over. No dialysis. Dialyzer is bypassed. + * In this state, blood pump is slowed while we wait for user to initiate + * a final rinseback of blood. + * + * @addtogroup TreatmentEnd + * @{ + */ + +// ********** private function prototypes ********** + +void initTreatmentEnd( void ); +void transitionToTreatmentEnd( void ); +void execTreatmentEnd( void ); + +void signalStopTreatmentEnd( void ); // from alarm +void signalTreatmentEndAlarmResumeUserAction( void ); // from user for alarm +void signalTreatmentEndAlarmRinsebackUserAction( void ); // from user for alarm +void signalTreatmentEndAlarmEndTxUserAction( void ); // from user for alarm +void signalTreatmentEndUserAction( REQUESTED_TREATMENT_END_USER_ACTIONS_T action ); // from user +TREATMENT_END_STATE_T getCurrentTreatmentEndState( void ); + +/**@}*/ + +#endif