Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r83310420ae862de4724f8cfbbaeda9936c47801b -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 83310420ae862de4724f8cfbbaeda9936c47801b) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -30,6 +30,8 @@ #include "StateTxBloodPrime.h" #include "StateTxDialysis.h" #include "StateTxPaused.h" +#include "StateTxRecirc.h" +#include "StateTxRinseback.h" //#include "Switches.h" #include "TaskGeneral.h" #include "Timers.h" @@ -91,9 +93,13 @@ static BOOL resumeTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment resume. static BOOL initiateRinsebackAlarmResponseRequest; ///< Flag indicates user has requested rinseback. static BOOL endTreatmentAlarmResponseRequest; ///< Flag indicates user has requested treatment end. +static BOOL initiateTempBreakALarmReponseRequest; ///< Flag indicates user has requested temporary break. static BOOL endTreatmentRequest; ///< Flag indicates user has requested end of treatment from rinseback workflow. static BOOL bloodPrimeToDialysisRequest; ///< Flag indicates blood prime has completed and time to start dialysis. static BOOL resumeBlockedByAlarm; ///< Flag indicates an alarm has blocked resume of this treatment. +static BOOL rinsebackToRecircRequest; ///< Flag indicates rinseback sub-mode has requested transition to Re-circulate. +static BOOL recirculateToBloodPrimeRequest; ///< Flag indicates re-circulate sub-mode has requested transition to Treatment Blood prime. +static BOOL recircAllowed; ///< Flag indicates re-circulate allowed only if user selects temp break option. static U32 treatmentStartTimeStamp; ///< Treatment start timestamp for logging purpose. static U32 treatmentEndTimeStamp; ///< Treatment end timestamp for logging purpose. @@ -131,6 +137,7 @@ treatmentCompleted = FALSE; rinsebackDone = FALSE; resumeBlockedByAlarm = FALSE; + recircAllowed = FALSE; treatmentTimePublishInterval.data = TREATMENT_TIME_DATA_PUB_INTERVAL; treatmentTimePublishInterval.ovData = TREATMENT_TIME_DATA_PUB_INTERVAL; @@ -185,8 +192,8 @@ initBloodPrime(); initDialysis(); initTreatmentPaused(); -// initRinseback(); -// initTreatmentRecirc(); + initRinseback(); + initTreatmentRecirc(); // initTreatmentEnd(); initFluidBolus(); @@ -266,6 +273,20 @@ /*********************************************************************//** * @brief + * The isRecircAllowed function determines whether the recirculation is + * allowed or not. Only allowed in temporary break option + * seen an alarm that prevents resumption. + * @details \b Inputs: recircAllowed + * @details \b Outputs: none + * @return isRecircAllowed + *************************************************************************/ +BOOL isRecircAllowed( void ) +{ + return recircAllowed; +} + +/*********************************************************************//** + * @brief * The getTreatmentTimeRemainingSecs function determines the number of seconds * remaining in the treatment. * @details \b Inputs: presTreatmentTimeSecs, treatmentTimeMS @@ -349,6 +370,35 @@ /*********************************************************************//** * @brief + * The setRinsebackIsCompleted function sets that flag indicating whether a + * rinseback has been completed. Call this function with TRUE when rinseback + * operation is completed. Call this function with FALSE at start of blood + * prime operation. + * @details Inputs: none + * @details Outputs: rinsebackDone + * @param flag TRUE if rinseback has been completed, FALSE if not + * @return none + *************************************************************************/ +void setRinsebackIsCompleted( BOOL flag ) +{ + rinsebackDone = flag; +} + +/*********************************************************************//** + * @brief + * The getRinsebackIsCompleted function determines whether a rinseback has been + * completed (indicating blood-side circuit should be primarily saline or online fluid). + * @details Inputs: rinsebackDone + * @details Outputs: none + * @return rinsebackDone + *************************************************************************/ +BOOL getRinsebackIsCompleted( void ) +{ + return rinsebackDone; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToTreatmentMode function executes the given alarm action * as appropriate while in Treatment Mode. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if invalid alarm action given. @@ -381,6 +431,10 @@ // Nothing to be done here break; + case ALARM_ACTION_TEMPORARY_BREAK: + initiateTempBreakALarmReponseRequest = TRUE; + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_TREATMENT_INVALID_ALARM_ACTION, (U32)action ) break; @@ -415,6 +469,32 @@ /*********************************************************************//** * @brief + * The signalGoToBloodPrime function signals that user wants to return + * to treatment blood prime from recirculate workflow. + * @details Inputs: none + * @details Outputs: recirculateToBloodPrimeRequest + * @return none + *************************************************************************/ +void signalGoToBloodPrime( void ) +{ + recirculateToBloodPrimeRequest = TRUE; +} + +/*********************************************************************//** + * @brief + * The signalRinsebackToRecirc function signals that user wants to continue + * on to re-circulate portion of rinseback workflow. + * @details Inputs: none + * @details Outputs: rinsebackToRecircRequest + * @return none + *************************************************************************/ +void signalRinsebackToRecirc( void ) +{ + rinsebackToRecircRequest = TRUE; +} + +/*********************************************************************//** + * @brief * The execTreatmentMode function executes the Treatment Mode state machine. * @details \b Alarm: ALARM_ID_TD_TREATMENT_PED_BY_USER if user presses * the button @@ -562,8 +642,9 @@ * @brief * The handleTreatmentBloodPrimeState function handles the blood prime state of * the Treatment Mode state machine. - * @details \b Inputs: presUFRate - * @details \b Outputs: none + * @details \b Inputs: presUFRate, bloodPrimeToDialysisRequest, recircAllowed + * @details \b Outputs: lastTreatmentTimeStamp, presUFRate, presUFVolumeMl, + * presUFRateMlMin, recircAllowed * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentBloodPrimeState( void ) @@ -594,6 +675,20 @@ // { // sendTreatmentLogEventData( UF_START_RESUME_EVENT, 0.0, presUFRate ); // } + + // Came back from temp break? + if ( TRUE == recircAllowed ) + { + F32 rinsebackVolume_L = getDeliveredRinsebackVolume() / (F32)ML_PER_LITER; + + presUFVolumeMl = ( getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ) + rinsebackVolume_L ) * (F32)ML_PER_LITER; + presUFRateMlMin = presUFVolumeMl / (F32)( getTreatmentTimeRemainingSecs() / SEC_PER_MIN ); + // Add rinseback volume to UF volume (fluid in circuit goes back to the patient when we resume treatment) + setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, presUFVolumeMl ); + setDialysisDDParams( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFVolumeMl, presUFRateMlMin ); + recircAllowed = FALSE; + } + transitionToDialysis(); // // To update partial blood pump occlusion baseline - start of treatment // signalBloodPumpPressureOcclBaseline(); @@ -659,8 +754,9 @@ * @brief * The handleTreatmentPausedState function executes the Paused state of the * Treatment Mode state machine. - * @details \b Inputs: none - * @details \b Outputs: treatment paused sub-mode executed. + * @details \b Inputs: resumeTreatmentAlarmResponseRequest, initiateTempBreakALarmReponseRequest, + * initiateRinsebackAlarmResponseRequest, endTreatmentAlarmResponseRequest + * @details \b Outputs: lastTreatmentTimeStamp * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentPausedState( void ) @@ -671,8 +767,6 @@ // If user requests resumption of treatment, resume treatment if ( TRUE == resumeTreatmentAlarmResponseRequest ) { - resumeTreatmentAlarmResponseRequest = FALSE; - if ( TRUE == getBloodIsPrimed() ) { lastTreatmentTimeStamp = getMSTimerCount(); @@ -686,18 +780,26 @@ } signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); } - // If user requests rinseback, go to rinseback -// else if ( TRUE == initiateRinsebackAlarmResponseRequest ) -// { -// transitionToRinseback(); -// result = TREATMENT_RINSEBACK_STATE; -// } + // If user requests temp break, go to rinseback and then recirc + else if ( TRUE == initiateTempBreakALarmReponseRequest ) + { + recircAllowed = TRUE; + transitionToRinseback(); + result = TREATMENT_RINSEBACK_STATE; + } + // If user requests blood return & end treatemnt, go to rinseback only and end treat + else if ( TRUE == initiateRinsebackAlarmResponseRequest ) + { + recircAllowed = FALSE; + transitionToRinseback(); + result = TREATMENT_RINSEBACK_STATE; + } // If user requests treatment end, end treatment -// else if ( TRUE == endTreatmentAlarmResponseRequest ) -// { -// sendLastTreatmentPeriodicData = TRUE; -// requestNewOperationMode( MODE_POST ); -// } + else if ( TRUE == endTreatmentAlarmResponseRequest ) + { + //sendLastTreatmentPeriodicData = TRUE; TODO + requestNewOperationMode( MODE_POST ); + } // Otherwise execute state machine for treatment paused sub-mode else { @@ -723,89 +825,75 @@ * The handleTreatmentRinsebackState function executes the rinseback state of the * Treatment Mode state machine. * @details \b Inputs: endTreatmentAlarmResponseRequest, resumeTreatmentAlarmResponseRequest, - * rinsebackToRecircRequest, rinsebackTopedRequest, endTreatmentRequest - * @details \b Outputs: treatment rinseback sub-mode executed, sendLastTreatmentPeriodicData + * rinsebackToRecircRequest + * @details \b Outputs: sendLastTreatmentPeriodicData * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentRinsebackState( void ) { TREATMENT_STATE_T result = TREATMENT_RINSEBACK_STATE; -// // If user requests treatment end, end treatment -// if ( TRUE == endTreatmentAlarmResponseRequest ) -// { -// sendLastTreatmentPeriodicData = TRUE; -// requestNewOperationMode( MODE_POST ); -// } -// // Otherwise execute state machine for treatment rinseback sub-mode -// else -// { -// // If user requests resumption of treatment, resume rinseback -// if ( TRUE == resumeTreatmentAlarmResponseRequest ) -// { -// resumeTreatmentAlarmResponseRequest = FALSE; -// signalRinsebackAlarmResumeUserAction(); -// } -// // Execute treatment rinseback sub-mode -// execRinseback(); -// } -// -// // Handle signals from rinseback sub-mode -// if ( TRUE == rinsebackToRecircRequest ) -// { -// transitionToTreatmentRecirc(); -// result = TREATMENT_RECIRC_STATE; -// } -// else if ( TRUE == rinsebackTopedRequest ) -// { -// transitionToTreatment(); -// result = TREATMENT_PAUSED_STATE; -// } -// else if ( TRUE == endTreatmentRequest ) -// { -// requestNewOperationMode( MODE_POST ); -// } + // If user requests treatment end, end treatment + if ( TRUE == endTreatmentAlarmResponseRequest ) + { + //sendLastTreatmentPeriodicData = TRUE; TODO + requestNewOperationMode( MODE_POST ); + } + else + { + // Forward alarm resume action to rinseback sub-mode as a rinseback specific resume + if ( TRUE == resumeTreatmentAlarmResponseRequest ) + { + signalRinsebackAlarmResumeUserAction(); + } + // Execute treatment rinseback sub-mode + execRinseback(); + } + + // Handle signals from rinseback sub-mode + if ( TRUE == rinsebackToRecircRequest ) + { + transitionToTreatmentRecirc(); + result = TREATMENT_RECIRC_STATE; + } + return result; } /*********************************************************************//** * @brief * The handleTreatmentRecircState function executes the re-circulate state of the * Treatment Mode state machine. - * @details \b Inputs: endTreatmentAlarmResponseRequest, rinsebackTopedRequest, - * endTreatmentRequest + * @details \b Inputs: endTreatmentAlarmResponseRequest, recirculateToBloodPrimeRequest * @details \b Outputs: sendLastTreatmentPeriodicData * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentRecircState( void ) { TREATMENT_STATE_T result = TREATMENT_RECIRC_STATE; -// // If user requests treatment end, end treatment -// if ( TRUE == endTreatmentAlarmResponseRequest ) -// { -// sendLastTreatmentPeriodicData = TRUE; -// requestNewOperationMode( MODE_POST ); -// } -// else -// { -// // Execute treatment re-circ sub-mode -// execTreatmentRecirc(); -// } -// -// // Handle signals from treatment re-circ sub-mode -// if ( TRUE == rinsebackTopedRequest ) -// { -// Dialysis(); -// transitionToTreatment(); -// result = TREATMENT__STATE; -// } -// else if ( TRUE == endTreatmentRequest ) -// { -// requestNewOperationMode( MODE_POST ); -// } + // If user requests treatment end, end treatment + if ( TRUE == endTreatmentAlarmResponseRequest ) + { + //sendLastTreatmentPeriodicData = TRUE; TODO + // Stop dialysate generation + cmdStopGenerateDialysate(); + requestNewOperationMode( MODE_POST ); + } + else + { + // Execute treatment re-circ sub-mode + execTreatmentRecirc(); + } + // Back to blood prime when user requests resume treatment + if ( TRUE == recirculateToBloodPrimeRequest ) + { + transitionToBloodPrime(); + result = TREATMENT_BLOOD_PRIME_STATE; + } + return result; } @@ -910,8 +998,8 @@ payload.dialysisState = getDialysisState(); payload.isoUFState = 0; payload.txPausedState = getCurrentTreatmentPausedState(); - payload.rinsebackState = 0; // getCurrentRinsebackState(); - payload.txRecircState = 0; // getCurrentTreatmentRecircState(); + payload.rinsebackState = getCurrentRinsebackState(); + payload.txRecircState = getCurrentTreatmentRecircState(); payload.txEndState = 0; // getCurrentTreatmentEndState(); payload.txFluidBolusState = getCurrentFluidBolusState(); payload.txHepState = 0; // @@ -1095,11 +1183,11 @@ *************************************************************************/ static void resetSignalFlags( void ) { -// rinsebackTopedRequest = FALSE; endTreatmentRequest = FALSE; -// rinsebackToRecircRequest = FALSE; + rinsebackToRecircRequest = FALSE; bloodPrimeToDialysisRequest = FALSE; // treatmentEndToRinsebackRequest = FALSE; + recirculateToBloodPrimeRequest = FALSE; } /*********************************************************************//** @@ -1114,6 +1202,7 @@ resumeTreatmentAlarmResponseRequest = FALSE; initiateRinsebackAlarmResponseRequest = FALSE; endTreatmentAlarmResponseRequest = FALSE; + initiateTempBreakALarmReponseRequest = FALSE; } /*********************************************************************//** Index: firmware/App/Modes/StateTxBloodPrime.c =================================================================== diff -u -r046ffdda014e511363b04ed523eb3399a3eb4ad0 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision 046ffdda014e511363b04ed523eb3399a3eb4ad0) +++ firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -156,6 +156,7 @@ { // Set user alarm recovery actions allowed in this state setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_TEMPORARY_BREAK, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); @@ -184,6 +185,13 @@ cmdChangeQd( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ) ); cmdChangeQuf( 0.0F ); + // Reset cumulative when we come back from temp break + if ( TRUE == getRinsebackIsCompleted() ) + { + cumulativeBloodPrimeVolume_mL.data = 0.0; + setRinsebackIsCompleted( FALSE ); + } + setCurrentSubState( (U32)bloodPrimeState ); } Index: firmware/App/Modes/StateTxPaused.c =================================================================== diff -u -r8345f0415ce34f2f47afcbf613a00216769f51c6 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision 8345f0415ce34f2f47afcbf613a00216769f51c6) +++ firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -106,15 +106,8 @@ setCurrent4thLevelState( NO_SUB_STATE ); // Set user alarm recovery actions allowed in this sub-mode setAlarmUserActionEnabled( ALARM_USER_ACTION_RESUME, TRUE ); - if ( FALSE ) // TODO ( TRUE == getRinsebackCompleted() ) - { - // block rinseback action if already done - setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, FALSE ); - } - else - { - setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); - } + setAlarmUserActionEnabled( ALARM_USER_ACTION_RINSEBACK, TRUE ); + setAlarmUserActionEnabled( ALARM_USER_ACTION_TEMPORARY_BREAK, TRUE ); setAlarmUserActionEnabled( ALARM_USER_ACTION_END_TREATMENT, TRUE ); transitionToTxPausedState( currentTxPausedState ); @@ -367,15 +360,14 @@ * The handleTreatmentPausedBloodSittingTimer 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. - * @details Inputs: bloodSittingTimerCtr - * @details Outputs: bloodSittingTimerCtr - * @return next treatment paused state + * @details \b Inputs: bloodSittingTimerCtr + * @details \b Outputs: bloodSittingTimerCtr + * @return none *************************************************************************/ static void handleTreatmentPausedBloodSittingTimer( void ) { // Ensure we do not sit in stopped state for too long (if blood in line) - //if ( getRinsebackCompleted() != TRUE ) // TODO rinseback - if ( TRUE ) + if ( getRinsebackIsCompleted() != TRUE ) { bloodSittingTimerCtr++; if ( FALSE == doesAlarmStatusIndicateEndTxOnly() ) // Alarms appropriate only if we are not already at an alarm stop, end Tx only Index: firmware/App/Modes/StateTxRecirc.c =================================================================== diff -u -r909d4064e98d5684ee139534f0ac6cbc5f8774d5 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Modes/StateTxRecirc.c (.../StateTxRecirc.c) (revision 909d4064e98d5684ee139534f0ac6cbc5f8774d5) +++ firmware/App/Modes/StateTxRecirc.c (.../StateTxRecirc.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -214,6 +214,7 @@ * @brief * The execTreatmentRecirc function executes the Treatment Re-circulate * sub-mode state machine. + * @details \b Inputs: ALARM_ID_TD_SOFTWARE_FAULT if exec state is invalid * @details \b Inputs: currentRecircState * @details \b Outputs: currentRecircState, recircTimerCtr * @return none @@ -247,7 +248,9 @@ break; default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_TREATMENT_RECIRC_INVALID_STATE, (U32)currentRecircState ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, + SW_FAULT_ID_TREATMENT_INVALID_RECIRC_STATE, + (U32)currentRecircState ); break; } @@ -366,6 +369,8 @@ * @brief * The signalTreatmentRecircUserAction function signals a re-circ user action * has been requested. The request is handled and responded to. + * @details \b Message \b Sent: MSG_ID_TD_RECIRCULATE_RESPONSE to send response + * for recirc user action acceptance * @details \b Inputs: none * @details \b Outputs: none * @param message UI message which has requested user action @@ -403,7 +408,8 @@ break; case REQUESTED_USER_ACTION_TX_RECIRC_END_TREATMENT: - // Send message to UI to get user confirmation to end treatment - action initiated only upon receipt of user confirmation from UI + // Send message to UI to get user confirmation to end treatment + // - action initiated only upon receipt of user confirmation from UI addConfirmationRequest( GENERIC_CONFIRM_ID_TREATMENT_END, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0U ); result = TRUE; break; @@ -426,7 +432,10 @@ // Respond to user action request response.accepted = result; response.rejectionReason = rejReason; - sendMessage( MSG_ID_TD_RECIRCULATE_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); + sendMessage( MSG_ID_TD_RECIRCULATE_RESPONSE, + COMM_BUFFER_OUT_CAN_TD_2_UI, + (U08*)&response, + sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } @@ -561,7 +570,7 @@ * The publishTreatmentRecircData function broadcasts re-circulate countdown * data to the UI at 1 Hz. * @details \b Inputs: recircPublishTimerCtr, recircTimerCtr - * @details \b Outputs: none + * @details \b Outputs: recircPublishTimerCtr * @return none *************************************************************************/ static void publishTreatmentRecircData( void ) @@ -577,7 +586,10 @@ recircPublishTimerCtr = 0; - broadcastData( MSG_ID_TD_RECIRCULATE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( TREATMENT_RECIRC_PAYLOAD_T ) ); + broadcastData( MSG_ID_TD_RECIRCULATE_DATA, + COMM_BUFFER_OUT_CAN_TD_BROADCAST, + (U08*)&data, + sizeof( TREATMENT_RECIRC_PAYLOAD_T ) ); } } Index: firmware/App/Modes/StateTxRinseback.c =================================================================== diff -u -rb56dffdfe60950630de83b03eb8527a1e10e1f63 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Modes/StateTxRinseback.c (.../StateTxRinseback.c) (revision b56dffdfe60950630de83b03eb8527a1e10e1f63) +++ firmware/App/Modes/StateTxRinseback.c (.../StateTxRinseback.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -59,12 +59,12 @@ static U32 rinsebackAdditionalTimerCtr; ///< Timer counter for duration of an additional rinseback delivery. static U32 rinsebackPublishTimerCtr; ///< Timer counter for determining interval for rinseback status to be published. static U32 rinsebackTargetVolume_mL; ///< Calculated target rinseback volume (based on selected dialyzer and fixed tubing volume). -static OVERRIDE_F32_T cummulativeRinsebackVolume_mL = { 0.0, 0.0, 0.0, 0 }; ///< Total cumulative rinseback volume (in mL) from measured blood flow rate. +static OVERRIDE_F32_T cummulativeRinsebackVolume_mL; ///< Total cumulative rinseback volume (in mL) from measured blood flow rate. static F32 targetRinsebackVolumePlusAdditional_mL; ///< Target rinseback volume w/ additional volume(s) added (in mL). static F32 additionalRinsebackVolume_mL; ///< Total volume (in mL) delivered so far for additional volume request. /// Interval (in task intervals) at which to publish rinseback data to CAN bus. -static OVERRIDE_U32_T rinsebackPublishInterval = { RINSEBACK_DATA_PUBLISH_INTERVAL, RINSEBACK_DATA_PUBLISH_INTERVAL, RINSEBACK_DATA_PUBLISH_INTERVAL, 0}; +static OVERRIDE_U32_T rinsebackPublishInterval; static BOOL startRinsebackRequested; ///< Flag indicating user requesting rinseback start (confirming saline bag move to arterial line end). static BOOL incrRinsebackFlowRateRequested; ///< Flag indicating user requesting rinseback flow rate be increased. @@ -108,17 +108,26 @@ *************************************************************************/ void initRinseback( void ) { - currentRinsebackState = RINSEBACK_STOP_INIT_STATE; - fluidType = FLUID_TYPE_SALINE; //getFluidType(); + currentRinsebackState = RINSEBACK_STOP_INIT_STATE; + fluidType = getFluidType(); setSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE, (U32)DEFAULT_RINSEBACK_FLOW_RATE_ML_MIN ); // Set to default rate before rinseback start - rinsebackTargetVolume_mL = getTreatmentParameterU32( TREATMENT_PARAM_PRIME_RINSEBACK_VOLUME ); + rinsebackTargetVolume_mL = getTreatmentParameterU32( TREATMENT_PARAM_PRIME_RINSEBACK_VOLUME ); targetRinsebackVolumePlusAdditional_mL = rinsebackTargetVolume_mL; - bloodSittingTimerCtr = 0; - cummulativeRinsebackVolume_mL.data = 0.0F; - additionalRinsebackVolume_mL = 0.0F; - rinsebackAdditionalTimerCtr = 0; - rinsebackPublishTimerCtr = 0; + bloodSittingTimerCtr = 0; + additionalRinsebackVolume_mL = 0.0F; + rinsebackAdditionalTimerCtr = 0; + rinsebackPublishTimerCtr = 0; resetRinsebackFlags(); + + cummulativeRinsebackVolume_mL.data = 0.0; + cummulativeRinsebackVolume_mL.ovInitData = 0.0; + cummulativeRinsebackVolume_mL.ovData = 0.0; + cummulativeRinsebackVolume_mL.override = OVERRIDE_RESET; + + rinsebackPublishInterval.data = RINSEBACK_DATA_PUBLISH_INTERVAL; + rinsebackPublishInterval.ovInitData = RINSEBACK_DATA_PUBLISH_INTERVAL; + rinsebackPublishInterval.ovData = 0; + rinsebackPublishInterval.override = OVERRIDE_RESET; } /*********************************************************************//** @@ -185,7 +194,8 @@ // Select the rinseback fluid source based fluid medium, which is based on modality. if ( FLUID_TYPE_SALINE == fluidType ) { - setBloodPumpTargetFlowRate( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ), MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); + setBloodPumpTargetFlowRate( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ), + MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_CLOSED_LOOP ); } else { @@ -253,6 +263,8 @@ * @brief * The handleRinsebackBloodSittingAlarms function handles blood sitting alarms * (when blood pump is not running). + * @details \b Alarms: ALARM_ID_TD_BLOOD_SITTING_WARNING if 1 min left from timeout, + * ALARM_ID_TD_BLOOD_SITTING_TOO_LONG if blood sitting timeout * @details \b Inputs: bloodSittingTimerCtr * @details \b Outputs: none * @return none @@ -273,6 +285,7 @@ /*********************************************************************//** * @brief * The execRinseback function executes the Rinseback sub-mode state machine. + * @details \b Inputs: ALARM_ID_TD_SOFTWARE_FAULT if exec state is invalid * @details \b Inputs: currentRinsebackState * @details \b Outputs: currentRinsebackState, bloodSittingTimerCtr * @return none @@ -357,9 +370,10 @@ * timeout, ALARM_ID_TD_EMPTY_SALINE_BAG if saline bag is empty or * saline line is clamped * @details \b Inputs: rinsebackTargetVolume_mL, pauseRinsebackRequestd, - * incrRinsebackFlowRateRequested, decrRinsebackFlowRateRequested - * @details \b Outputs: bloodSittingTimerCtr, cumulativeRinsebackVolume_mL, - * rinsebackRate_mL_min, incrRinsebackFlowRateRequested, decrRinsebackFlowRateRequested + * incrRinsebackFlowRateRequested, decrRinsebackFlowRateRequested, fluidType + * @details \b Outputs: bloodSittingTimerCtr, cummulativeRinsebackVolume_mL, + * rinsebackRate_mL_min, incrRinsebackFlowRateRequested, decrRinsebackFlowRateRequested, + * targetRinsebackVolumePlusAdditional_mL * @return next rinseback state *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackRunState( void ) @@ -370,7 +384,8 @@ bloodSittingTimerCtr = 0; // Update rinseback volume delivered so far - cummulativeRinsebackVolume_mL.data += ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) * RINSEBACK_FLOW_INTEGRATOR ); + cummulativeRinsebackVolume_mL.data += ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) * + RINSEBACK_FLOW_INTEGRATOR ); // Check for empty saline bag if we are using saline to rinseback. if ( ( FLUID_TYPE_SALINE == fluidType ) && ( TRUE == isSalineBagEmpty() ) ) @@ -428,10 +443,8 @@ * @brief * The handleRinsebackPausedState function handles the rinseback paused * state operations. - * @details \b Alarms: ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM if rinseback - * timeout - * @details \b Inputs: bloodSittingTimerCtr, resumeRinsebackRequested - * @details \b Outputs: targetRinsebackVolumePlusAdditional_mL + * @details \b Inputs: resumeRinsebackRequested + * @details \b Outputs: none * @return next rinseback state *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackPausedState( void ) @@ -455,7 +468,7 @@ * @details \b Alarms: ALARM_ID_TD_RINSEBACK_TIMEOUT_ALARM if rinseback * timeout * @details \b Inputs: bloodSittingTimerCtr, rinsebackTargetVolume_mL, recircRequested, - * additionalRinsebackRequested + * additionalRinsebackRequested, recircRequested * @details \b Outputs: additionalRinsebackRequested, * rinsebackAdditionalTimerCtr, additionalRinsebackVolume_mL * @return next rinseback state @@ -474,14 +487,14 @@ } else if ( TRUE == additionalRinsebackRequested ) { - additionalRinsebackRequested = FALSE; - - if ( ( bloodSittingTimerCtr < MAX_TIME_BLOOD_SITTING ) || ( getDeliveredRinsebackVolume() >= rinsebackTargetVolume_mL ) ) + if ( ( bloodSittingTimerCtr < MAX_TIME_BLOOD_SITTING ) || + ( getDeliveredRinsebackVolume() >= rinsebackTargetVolume_mL ) ) { rinsebackAdditionalTimerCtr = 0; additionalRinsebackVolume_mL = getDeliveredRinsebackVolume(); targetRinsebackVolumePlusAdditional_mL += TARGET_ADDITIONAL_RINSEBACK_VOLUME_ML; - setSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE, DEFAULT_RINSEBACK_FLOW_RATE_ML_MIN ); + setSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE, + DEFAULT_RINSEBACK_FLOW_RATE_ML_MIN ); setupForRinsebackDelivery(); state = RINSEBACK_RUN_ADDITIONAL_STATE; } @@ -498,17 +511,19 @@ * @brief * The handleRinsebackRunAdditionalState function handles the rinseback additional * state operations. - * @details \b Alarms: ALARM_ID_TD_EMPTY_SALINE_BAG if saline bag is empty or + * @details \b Alarms: ALARM_ID_TD_SALINE_BAG_VOLUME_LOW_ALARM if saline bag is empty or * saline line is clamped. - * @details \b Inputs: additionalRinsebackVolume_mL, rinsebackAdditionalTimerCtr - * @details \b Outputs: bloodSittingTimerCtr, additionalRinsebackVolume_mL, cumulativeRinsebackVolume_mL, - * rinsebackAdditionalTimerCtr, targetRinsebackVolumePlusAdditional_mL + * @details \b Inputs: additionalRinsebackVolume_mL, rinsebackAdditionalTimerCtr, fluidType + * @details \b Outputs: bloodSittingTimerCtr, additionalRinsebackVolume_mL, + * cummulativeRinsebackVolume_mL, rinsebackAdditionalTimerCtr, + * targetRinsebackVolumePlusAdditional_mL * @return next rinseback state *************************************************************************/ static RINSEBACK_STATE_T handleRinsebackAdditionalState( void ) { RINSEBACK_STATE_T state = RINSEBACK_RUN_ADDITIONAL_STATE; - F32 rinsebackVolumeSinceLast = ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) * RINSEBACK_FLOW_INTEGRATOR ); + F32 rinsebackVolumeSinceLast = ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) * + RINSEBACK_FLOW_INTEGRATOR ); // Reset rinseback t/o bloodSittingTimerCtr = 0; @@ -533,7 +548,8 @@ state = RINSEBACK_STOP_STATE; } // Has alarm requested stop or timed out? - else if ( ( TRUE == doesAlarmStatusIndicateStop() ) || ( rinsebackAdditionalTimerCtr >= MAX_RINSEBACK_ADDITIONAL_TIME ) ) + else if ( ( TRUE == doesAlarmStatusIndicateStop() ) || + ( rinsebackAdditionalTimerCtr >= MAX_RINSEBACK_ADDITIONAL_TIME ) ) { setupForRinsebackStopOrPause(); targetRinsebackVolumePlusAdditional_mL = getDeliveredRinsebackVolume(); @@ -617,7 +633,8 @@ break; case REQUESTED_USER_ACTION_RINSEBACK_END_TREATMENT: - // Send message to UI to get user confirmation to end treatment - action initiated only upon receipt of user confirmation from UI + // Send message to UI to get user confirmation to end treatment - action + // initiated only upon receipt of user confirmation from UI addConfirmationRequest( GENERIC_CONFIRM_ID_TREATMENT_END, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0U ); result = TRUE; break; @@ -640,7 +657,10 @@ // Respond to user action request response.accepted = result; response.rejectionReason = rejReason; - sendMessage( MSG_ID_TD_RINSEBACK_CMD_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, (U08*)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); + sendMessage( MSG_ID_TD_RINSEBACK_CMD_RESPONSE, + COMM_BUFFER_OUT_CAN_TD_2_UI, + (U08*)&response, + sizeof( UI_RESPONSE_PAYLOAD_T ) ); return result; } @@ -678,15 +698,16 @@ * flow rate user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. * @details \b Inputs: currentRinsebackState - * @details \b Outputs: incrRinsebackFlowRateRequested + * @details \b Outputs: incrRinsebackFlowRateRequested, rinsebackPublishTimerCtr * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ static BOOL handleIncrRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) { BOOL result = FALSE; - if ( ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) + RINSEBACK_FLOW_RATE_ADJ_ML_MIN ) <= MAX_RINSEBACK_FLOW_RATE_ML_MIN ) + if ( ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) + + RINSEBACK_FLOW_RATE_ADJ_ML_MIN ) <= MAX_RINSEBACK_FLOW_RATE_ML_MIN ) { if ( RINSEBACK_RUN_STATE == currentRinsebackState ) { @@ -713,15 +734,16 @@ * flow rte user action request. It is assumed that the calling function will set * the reject reason parameter to None beforehand. * @details \b Inputs: currentRinsebackState - * @details \b Outputs: decrRinsebackFlowRateRequested + * @details \b Outputs: decrRinsebackFlowRateRequested, rinsebackPublishTimerCtr * @param rejReason Code indicating reason for rejection * @return TRUE if user action accepted, FALSE if not *************************************************************************/ static BOOL handleDecrRinsebackUserAction( REQUEST_REJECT_REASON_CODE_T *rejReason ) { BOOL result = FALSE; - if ( ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) - RINSEBACK_FLOW_RATE_ADJ_ML_MIN ) >= MIN_RINSEBACK_FLOW_RATE_ML_MIN ) + if ( ( getSysConfigTreatmentParameterU32( TREATMENT_PARAM_RINSEBACK_FLOW_RATE ) - + RINSEBACK_FLOW_RATE_ADJ_ML_MIN ) >= MIN_RINSEBACK_FLOW_RATE_ML_MIN ) { if ( RINSEBACK_RUN_STATE == currentRinsebackState ) { @@ -864,7 +886,7 @@ * at 1 Hz interval. * @details \b Inputs: rinsebackPublishTimerCtr, bloodSittingTimerCtr, targetRinsebackVolumePlusAdditional_mL * rinsebackRate_mL_min - * @details \b Outputs: none + * @details \b Outputs: rinsebackPublishTimerCtr * @return none *************************************************************************/ static void publishRinsebackData( void ) @@ -890,13 +912,17 @@ } else { - U32 countdown = ( bloodSittingTimerCtr <= MAX_TIME_BLOOD_SITTING ) ? ( MAX_TIME_BLOOD_SITTING - bloodSittingTimerCtr ) : 0; + U32 countdown = ( bloodSittingTimerCtr <= MAX_TIME_BLOOD_SITTING ) ? + ( MAX_TIME_BLOOD_SITTING - bloodSittingTimerCtr ) : 0; data.timeout = MAX_TIME_BLOOD_SITTING / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); data.countdown = countdown / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ); } - broadcastData( MSG_ID_TD_RINSEBACK_PROGRESS, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( RINSEBACK_DATA_PAYLOAD_T ) ); + broadcastData( MSG_ID_TD_RINSEBACK_PROGRESS, + COMM_BUFFER_OUT_CAN_TD_BROADCAST, + (U08*)&data, + sizeof( RINSEBACK_DATA_PAYLOAD_T ) ); } } Index: firmware/App/Monitors/Pressures.c =================================================================== diff -u -r909d4064e98d5684ee139534f0ac6cbc5f8774d5 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Monitors/Pressures.c (.../Pressures.c) (revision 909d4064e98d5684ee139534f0ac6cbc5f8774d5) +++ firmware/App/Monitors/Pressures.c (.../Pressures.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -7,8 +7,8 @@ * * @file Pressures.c * -* @author (last) Vijay Pamula -* @date (last) 29-May-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 03-Aug-2026 * * @author (original) Sean Nash * @date (original) 24-Sep-2024 @@ -72,7 +72,7 @@ #define VENOUS_PRESSURE_MAX_MMHG ( 2000.0F ) ///< Maximum venous pressure reading (in mmHg) for range check. #define VENOUS_PRESSURE_MIN_MMHG ( -1500.0F ) ///< Minimum venous pressure reading (in mmHg) for range check. #define VENOUS_PRESSURE_LIMIT_MAX_MMHG ( 400.0F ) ///< Maximum venous pressure limit (in mmHg). -#define VENOUS_PRESSURE_LIMIT_MIN_MMHG ( 20.0F ) ///< Minimum venous pressure limit (in mmHg). +#define VENOUS_PRESSURE_LIMIT_MIN_MMHG ( 10.0F ) ///< Minimum venous pressure limit (in mmHg). #define VENOUS_PRESSURE_EXEMPTION_PERIOD ( ( 2 * MS_PER_SECOND ) / \ TASK_GENERAL_INTERVAL ) ///< Venous pressure low exemption period (in task interval) after fill for all blood flow rate @@ -431,7 +431,7 @@ } // Using final TMP value for override. - filtTmp = getTMPPressure(); + filtTmp = getLongFilteredTMPPressure(); curArtPres = FLOAT_TO_INT_WITH_ROUND( filtArt ); curVenPres = FLOAT_TO_INT_WITH_ROUND( filtVen ); @@ -496,10 +496,10 @@ if ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) { // apply pressure windows when stable - S32 artOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ) / 2; - S32 venMinOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); - S32 venMaxOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ) - venMinOffset; - S32 tmpOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ) / 2; + S32 artOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ); + S32 venMinOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_HIGH_LIMIT_WINDOW ); + S32 venMaxOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_LOW_LIMIT_WINDOW ); + S32 tmpOffset = (S32)getSysConfigTreatmentParameterU32( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ); currentArterialMinLimit = stableArterialPressure - artOffset; currentArterialMinLimit = MAX( currentArterialMinLimit, ARTERIAL_PRESSURE_LIMIT_MIN_MMHG ); @@ -711,9 +711,9 @@ } else if ( TRUE == didTimeout( stabilizationStartTimeMs, PRES_LIMIT_RESTABILIZE_TIME_MS ) ) { - stabilizationStartTimeMs = getMSTimerCount(); - pressureStabilizeTime = STABILIZATION_PERIOD_OFF; - currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; + stabilizationStartTimeMs = getMSTimerCount(); + pressureStabilizeTime = STABILIZATION_PERIOD_OFF; + currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; } break; Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r8345f0415ce34f2f47afcbf613a00216769f51c6 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 8345f0415ce34f2f47afcbf613a00216769f51c6) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -199,6 +199,8 @@ SW_FAULT_ID_PRE_TX_RECIRC_INVALID_STATE = 168, SW_FAULT_ID_TD_VALVES_INVALID_VALVE2 = 169, SW_FAULT_ID_INVALID_TUBE_SET_TYPE = 170, + SW_FAULT_ID_INVALID_RINSEBACK_STATE = 171, + SW_FAULT_ID_TREATMENT_INVALID_RECIRC_STATE = 172, NUM_OF_SW_FAULT_IDS } SW_FAULT_ID_T; Index: firmware/App/Services/AlarmMgmtTD.c =================================================================== diff -u -rcda13e3e3b9219fbac05354d8d1f8a25f45276cb -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision cda13e3e3b9219fbac05354d8d1f8a25f45276cb) +++ firmware/App/Services/AlarmMgmtTD.c (.../AlarmMgmtTD.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -158,6 +158,7 @@ alarmStatus.noBloodRecirc = FALSE; alarmStatus.noDialRecirc = FALSE; alarmStatus.ok = FALSE; + alarmStatus.noTempBreak = FALSE; alarmsBlockedTimer = 0; lastUserAlarmActionReceivedTime = 0; @@ -501,6 +502,13 @@ } break; + case ALARM_USER_ACTION_TEMPORARY_BREAK: + if ( ( alarmStatus.noTempBreak != TRUE ) && ( alarmStatus.noRinseback != TRUE ) ) + { + alarmActionIsValid = TRUE; + } + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_ALARM_USER_ACTION1, action ); break; @@ -547,7 +555,8 @@ break; case ALARM_USER_ACTION_RINSEBACK: - initiateAlarmAction( ALARM_ACTION_RINSEBACK ); + // Send message to UI to get user confirmation to rinseback (blood return & end treatment) - action initiated only upon receipt of user confirmation from UI + addConfirmationRequest( GENERIC_CONFIRM_ID_RINSEBACK, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0 ); break; case ALARM_USER_ACTION_END_TREATMENT: @@ -559,6 +568,11 @@ initiateAlarmAction( ALARM_ACTION_ACK ); break; + case ALARM_USER_ACTION_TEMPORARY_BREAK: + // Send message to UI to get user confirmation to temporary break - action initiated only upon receipt of user confirmation from UI + addConfirmationRequest( GENERIC_CONFIRM_ID_TEMPORARY_BREAK, GENERIC_CONFIRM_CMD_REQUEST_OPEN, 0 ); + break; + // This default cannot be reached in VectorCAST due to check above for alarmActionIsValid #ifndef _VECTORCAST_ default: @@ -893,7 +907,7 @@ } } -/*********************************************************************//** +/*********************************************************************//** * @brief * The getAlarmStartTime function gets the start time of a given alarm. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if given alarm ID is invalid. @@ -928,7 +942,8 @@ /*********************************************************************//** * @brief * The monitorAlarms function monitors alarm audio current and also looks - * for and executes a user confirmation of user request to end treatment. + * for and executes a user confirmation of user request to shutdown, + * end treatment, temporary break, rinseback. * @details \b Inputs: none * @details \b Outputs: none * @return none @@ -946,6 +961,20 @@ initiateAlarmAction( ALARM_ACTION_END_TREATMENT ); } + // Check for user confirmation of rinseback (Blood return & end treatment) alarm response + if ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == getConfirmationRequestStatus( GENERIC_CONFIRM_ID_RINSEBACK ) ) + { + clearAllRecoverableAlarms( ALARM_USER_ACTION_RINSEBACK ); + initiateAlarmAction( ALARM_ACTION_RINSEBACK ); + } + + // Check for user confirmation of temp break alarm response + if ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == getConfirmationRequestStatus( GENERIC_CONFIRM_ID_TEMPORARY_BREAK ) ) + { + clearAllRecoverableAlarms( ALARM_USER_ACTION_TEMPORARY_BREAK ); + initiateAlarmAction( ALARM_ACTION_TEMPORARY_BREAK ); + } + // TODO - Check current vs. expected audio output } @@ -1153,6 +1182,7 @@ BOOL endTxOnlyAlarmActive = FALSE; BOOL usrAckReq = FALSE; BOOL noMinimize = TRUE; + BOOL noTempBreak = FALSE; TD_OP_MODE_T currentMode = getCurrentOperationMode(); ALARM_T propsTop = getAlarmProperties( alarmStatus.alarmTop ); ALARM_ID_T a; @@ -1161,10 +1191,12 @@ alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RESUME ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ? FALSE : TRUE ); alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_RINSEBACK ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RINSEBACK ] ? FALSE : TRUE ); alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_END_TREATMENT ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_END_TREATMENT ] ? FALSE : TRUE ); + alarmButtonBlockers[ ALARM_BUTTON_STATE_BLOCK_TEMP_BREAK ] = ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_TEMPORARY_BREAK ] ? FALSE : TRUE ); // Reset user alarm recovery actions allowed by active alarms flags alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RESUME ] = FALSE; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] = FALSE; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] = FALSE; + alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_TEMP_BREAK ] = FALSE; // Determine alarm flags for ( a = ALARM_ID_NO_ALARM; a < NUM_OF_ALARM_IDS; a++ ) @@ -1181,6 +1213,7 @@ alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RESUME ] |= props.alarmNoResume; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_RINSEBACK ] |= props.alarmNoRinseback; alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT ] |= props.alarmNoEndTreatment; + alarmButtonBlockers[ ALARM_BUTTON_TABLE_BLOCK_TEMP_BREAK ] |= props.alarmNoRinseback; if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_RESUME ] ) { noResume = ( TRUE == props.alarmNoResume ? TRUE : noResume ); @@ -1205,6 +1238,14 @@ { noEndTreatment = TRUE; } + if ( TRUE == alarmUserRecoveryActionEnabled[ ALARM_USER_ACTION_TEMPORARY_BREAK ] ) + { + noTempBreak = ( TRUE == props.alarmNoRinseback ? TRUE : noTempBreak ); + } + else + { + noTempBreak = TRUE; + } // if there are any active alarms that only allow end treatment, set flag so we can ensure we do not allow OK option. if ( ( TRUE == props.alarmNoResume ) && ( TRUE == props.alarmNoRinseback ) && @@ -1230,6 +1271,7 @@ noResume = TRUE; noRinseback = TRUE; noEndTreatment = TRUE; + noTempBreak = TRUE; } // if OK option enabled and there are any active alarms that only allow end treatment, block OK option and allow end treatment option (DEN-16594). @@ -1246,6 +1288,7 @@ noResume = TRUE; noRinseback = TRUE; noEndTreatment = TRUE; + noTempBreak = TRUE; } // If in Treatment-Stop state or Fault/Service/Standby Mode, allow user to minimize the alarm window @@ -1264,6 +1307,7 @@ alarmStatus.noEndTreatment = noEndTreatment; alarmStatus.ok = usrAckReq; alarmStatus.noMinimize = noMinimize; + alarmStatus.noTempBreak = noTempBreak; resumeBlockedByAlarmProperty = noResumePerAlarmPropertyOnly; } @@ -1402,6 +1446,7 @@ payload.alarmsFlags |= ( almStatus.noResume ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_RESUME) : 0 ); payload.alarmsFlags |= ( almStatus.noRinseback ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_RINSEBACK) : 0 ); payload.alarmsFlags |= ( almStatus.noEndTreatment ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_END_TREATMENT) : 0 ); + payload.alarmsFlags |= ( almStatus.noTempBreak ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_NO_TEMPORARY_BREAK) : 0 ); payload.alarmsFlags |= ( almStatus.ok ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_OK_BUTTON_ONLY) : 0 ); payload.alarmsFlags |= ( almStatus.alarmsSilenced ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_ALARMS_SILENCED) : 0 ); payload.alarmsFlags |= ( almStatus.lampOn ? BIT_BY_POS(ALARM_STATE_FLAG_BIT_POS_LAMP_ON) : 0 ); Index: firmware/App/Services/AlarmMgmtTD.h =================================================================== diff -u -rcda13e3e3b9219fbac05354d8d1f8a25f45276cb -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Services/AlarmMgmtTD.h (.../AlarmMgmtTD.h) (revision cda13e3e3b9219fbac05354d8d1f8a25f45276cb) +++ firmware/App/Services/AlarmMgmtTD.h (.../AlarmMgmtTD.h) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -47,6 +47,7 @@ ALARM_ACTION_RINSEBACK, ///< User selected rinseback from alarm recovery options ALARM_ACTION_END_TREATMENT, ///< User selected end treatment from alarm recovery options ALARM_ACTION_ACK, ///< User selected Ack from alarm recovery options + ALARM_ACTION_TEMPORARY_BREAK, ///< User selected Temp break from alarm recover options NUMBER_OF_ALARM_ACTIONS ///< Number of alarm actions } ALARM_ACTION_T; @@ -71,7 +72,7 @@ BOOL ok; ///< Display OK button instead of other options BOOL noMinimize; ///< Prevent user from minimizing the alarm window BOOL lampOn; ///< The alarm lamp is on - BOOL unused; ///< Flag not used - available + BOOL noTempBreak; ///< Temporary break may not be initiated at this time. } COMP_ALARM_STATUS_T; #pragma pack(pop) @@ -82,9 +83,11 @@ ALARM_BUTTON_TABLE_BLOCK_RESUME = 0, ///< Alarm table properties are blocking alarm resume button ALARM_BUTTON_TABLE_BLOCK_RINSEBACK, ///< Alarm table properties are blocking alarm rinseback button ALARM_BUTTON_TABLE_BLOCK_END_TREATMENT, ///< Alarm table properties are blocking alarm end treatment button + ALARM_BUTTON_TABLE_BLOCK_TEMP_BREAK, ///< Alarm table properties are blocking alarm temp break button ALARM_BUTTON_STATE_BLOCK_RESUME, ///< State properties are blocking alarm resume button ALARM_BUTTON_STATE_BLOCK_RINSEBACK, ///< State properties are blocking alarm rinseback button ALARM_BUTTON_STATE_BLOCK_END_TREATMENT, ///< State properties are blocking alarm end treatment button + ALARM_BUTTON_STATE_BLOCK_TEMP_BREAK, ///< State properties are blocking alarm temp break button NUM_OF_ALARM_BUTTON_BLOCKERS ///< Number of alarm actions } ALARM_BUTTON_BLOCKER_T; Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r83310420ae862de4724f8cfbbaeda9936c47801b -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 83310420ae862de4724f8cfbbaeda9936c47801b) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -40,6 +40,8 @@ #include "StateTxBloodPrime.h" #include "StateTxDialysis.h" #include "StateTxPaused.h" +#include "StateTxRecirc.h" +#include "StateTxRinseback.h" #include "Switches.h" #include "SyringePump.h" #include "SystemCommTD.h" @@ -136,6 +138,9 @@ { MSG_ID_UI_ADJUST_DISPOSABLES_REMOVAL_CONFIRM_REQUEST, &handleAutoEjectRequest }, { MSG_ID_FFU_SIGNAL_TD_UPDATE_AVAILABLE, &handleUpdateAvailable }, { MSG_ID_UI_FLUID_BOLUS_REQUEST, &handleFluidBolusRequest }, + { MSG_ID_UI_RINSEBACK_CMD_REQUEST, &signalRinsebackUserAction }, + { MSG_ID_UI_RECIRCULATE_REQUEST, &signalTreatmentRecircUserAction }, + { MSG_ID_UI_GENERIC_CONFIRMATION_RESULT_RESPONSE, &handleUIConfirmation }, { MSG_ID_TD_SOFTWARE_RESET_REQUEST, &testTDSoftwareResetRequest }, { MSG_ID_TD_BUBBLE_OVERRIDE_REQUEST, &testBubbleDetectOverride }, { MSG_ID_TD_BUBBLE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testBubblesDataPublishIntervalOverride }, @@ -219,6 +224,8 @@ { MSG_ID_TD_HEPARIN_BOLUS_TARGET_RATE_OVERRIDE_REQUEST, &testHeparinBolusTargetRateOverride }, { MSG_ID_TD_SYRINGE_PUMP_FORCE_SENSOR_CALIBRATION_REQUEST, &testCalibrateForceSensor }, { MSG_ID_TD_GET_ALARM_PROPERTIES_REQUEST, &testGetAlarmPropertiesRequest }, + { MSG_ID_TD_RINSEBACK_VOLUME_OVERRIDE, &testRinsebackVolumeOverride }, + { MSG_ID_TD_RINSEBACK_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testRinsebackPublishIntervalOverride }, }; /// Number of entries in the message handling function lookup table. @@ -739,6 +746,67 @@ /*********************************************************************//** * @brief + * The sendConfirmationRequest function constructs and transmits a + * confirmation request message to the UI. + * @details \b Inputs: none + * @details \b Outputs: none + * @param requestID ID of the confirmation being requested + * @param requestType Type of confirmation being requested + * @param rejectReason Reason for reject if type is reject, 0 otherwise + * @return none + *************************************************************************/ +void sendConfirmationRequest( GENERIC_CONFIRM_ID_T requestID, GENERIC_CONFIRM_COMMAND_T requestType, U32 rejectReason ) +{ + GENERIC_CONFIRMATION_REQUEST_T payload; + + payload.requestID = (U32)requestID; + payload.requestType = (U32)requestType; + payload.rejectReason = rejectReason; + payload.genericPayload1 = 0.0F; + payload.genericPayload2 = 0.0F; + payload.genericPayload3 = 0.0F; + payload.genericPayload4 = 0.0F; + + sendMessage( MSG_ID_TD_UI_GENERIC_CONFIRMATION_REQUEST, + COMM_BUFFER_OUT_CAN_TD_2_UI, + (U08*)&payload, + sizeof( GENERIC_CONFIRMATION_REQUEST_T ) ); +} + +/*********************************************************************//** + * @brief + * The handleUIConfirmationResponse function handles a UI response for a + * confirmation request. + * @details \b Inputs: none + * @details \b Outputs: none + * @param message pointer to the received confirmation response message + * @return TRUE if message handled successfully, FALSE if not + *************************************************************************/ +BOOL handleUIConfirmation( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + if ( ( 2U * sizeof(U32) ) == message->hdr.payloadLen ) + { + U32 requestID; + U32 status; + + memcpy( &requestID, message->payload, sizeof(U32) ); + memcpy( &status, message->payload + sizeof(U32), sizeof(U32) ); + + if ( ( CONFIRMATION_REQUEST_STATUS_ACCEPTED == ( CONFIRMATION_REQUEST_STATUS_T)status ) || + ( CONFIRMATION_REQUEST_STATUS_REJECTED == ( CONFIRMATION_REQUEST_STATUS_T)status ) ) + { + setConfirmationRequestStatus( ( GENERIC_CONFIRM_ID_T )requestID, ( CONFIRMATION_REQUEST_STATUS_T)status ); + result = TRUE; + } + } + + return result; +} + +/*********************************************************************//** + * @brief * The testTDSoftwareResetRequest function handles a request to reset the * TD firmware processor. * @note If reset is successful, this function will not return. Index: firmware/App/Services/StateServices/FluidBolus.c =================================================================== diff -u -r8345f0415ce34f2f47afcbf613a00216769f51c6 -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision 8345f0415ce34f2f47afcbf613a00216769f51c6) +++ firmware/App/Services/StateServices/FluidBolus.c (.../FluidBolus.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -337,7 +337,7 @@ * saline bag is empty. For substitution medium, aborts if dialysate is no * longer good to deliver. Completes the bolus when the target volume is * reached or an abort is requested. - * @details \b Alarms: ALARM_ID_TD_EMPTY_SALINE_BAG if saline bag is empty or + * @details \b Alarms: ALARM_ID_TD_SALINE_BAG_VOLUME_LOW_ALARM if saline bag is empty or * saline line is clamped. * @details \b Inputs: bolusFluidVolumeDelivered_mL, fluidBolusAbortRequested, * currentFluidBolusMedium @@ -356,7 +356,7 @@ // Check for empty saline bag per arterial line pressure if ( TRUE == isSalineBagEmpty() ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_EMPTY_SALINE_BAG, getFilteredArterialPressure() ); + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_SALINE_BAG_VOLUME_LOW_ALARM, getFilteredArterialPressure() ); state = FLUID_BOLUS_IDLE_STATE; } } Index: firmware/App/Services/TxParams.c =================================================================== diff -u -r83310420ae862de4724f8cfbbaeda9936c47801b -rb30f390acbd6c972d4ecea536b875a409a2c8e77 --- firmware/App/Services/TxParams.c (.../TxParams.c) (revision 83310420ae862de4724f8cfbbaeda9936c47801b) +++ firmware/App/Services/TxParams.c (.../TxParams.c) (revision b30f390acbd6c972d4ecea536b875a409a2c8e77) @@ -151,6 +151,7 @@ { CRITICAL_DATA_TYPE_U32, {.uInt=40}, {.uInt=140}, {.uInt=40} }, // TREATMENT_PARAM_HEART_RATE_LOW_ALARM_LIMIT { CRITICAL_DATA_TYPE_U32, {.uInt=80}, {.uInt=180}, {.uInt=120} }, // TREATMENT_PARAM_HEART_RATE_HIGH_ALARM_LIMIT { CRITICAL_DATA_TYPE_U32, {.uInt=1}, {.uInt=5}, {.uInt=1} }, // TREATMENT_PARAM_PRES_ALARM_PERSISTENCE + { CRITICAL_DATA_TYPE_U32, {.uInt=30}, {.uInt=120}, {.uInt=30} }, // TREATMENT_PARAM_TEMPORARY_BREAK_RECIRC_TIMEOUT }; /// Dialyzer volumes (blood and dialysate) table in mL for each type of dialyzer.