Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -rbbd48b033ef7307a30815e490eb28825c7afcc2b -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision bbd48b033ef7307a30815e490eb28825c7afcc2b) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -8,7 +8,7 @@ * @file ModePreTreat.c * * @author (last) Vijay Pamula -* @date (last) 14-Jul-2026 +* @date (last) 17-Aug-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 @@ -21,10 +21,13 @@ #include "Buttons.h" #include "DDInterface.h" #include "HemoDiaFiltration.h" +#include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" +#include "StatePreTxHeparinSetup.h" #include "StatePreTxRecirculate.h" #include "SyringePump.h" +#include "TaskGeneral.h" #include "Timers.h" #include "TubeSetInstall.h" #include "TxParams.h" @@ -36,21 +39,45 @@ * @{ */ +// ********** private definitions ********** + +/// Interval (ms/task time) at which the Pre-Treatment state data is published on the CAN bus. +#define PRE_TREATMENT_STATE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) + +/// Initial offset used to stagger the Pre-Treatment state data broadcast. +#define PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET 5U + +#define PRE_TX_DEFAULT_QD_ML_MIN 400 ///< Default dialysate flow rate during recirculation when Rx is not entered in mL/min. +#define PRE_TX_INTERMEDIATE_QD_ML_MIN 300 ///< Intermediate dialysate flow rate for low prescribed Qd in mL/min. +#define PRE_TX_LOW_QD_THRESHOLD_ML_MIN 200 ///< Maximum prescribed Qd requiring the intermediate Qd transition in mL/min. +#define PRE_TX_LOW_QD_TRANSITION_TIME_MS ( 4 * SEC_PER_MIN * MS_PER_SECOND ) ///< Low Qd transition time before applying the prescribed Qd in milliseconds. + // ********** private data ********** static TD_PRE_TREATMENT_MODE_STATE_T currentPreTreatmentState; ///< Current Pre-Treatment sub-state static BOOL goToInstallStateRequested; ///< Flag indicating a request to transition to Install state. -static BOOL continueFromRecirculateRequested; ///< Flag indicating a request to transition to Patient Connection state. +static BOOL continueFromRecirculateRequested; ///< Flag indicating a request to transition to Confirm Rx state. +static BOOL continueFromHeparinSetupRequested; ///< Flag indicating a request to transition to Patient Connection state. +static BOOL treatmentStartRequested; ///< Flag indicating the UI requested treatment start. +static U32 preTreatmentStateBroadcastTimerCtr; ///< Pre-Treatment state data broadcast timer counter. +static OVERRIDE_U32_T preTreatmentStatePublishInterval; ///< Pre-Treatment state data publication interval override. +static BOOL lowQdTransitionActive; ///< Flag indicating low Qd transition is active. +static U32 lowQdTransitionStartTime; ///< Start time of the low Qd transition. +static BOOL defaultQdApplied; ///< Flag indicating default Qd has been applied while Rx is unavailable. +static BOOL preTreatmentRxUpdated; ///< Flag indicating a new or updated Rx was received. // ********** private function prototypes ********** -static void setPreTreatStateTransition( void ); ///< Configure actuators and variables for Pre-Treatment state transitions. -static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); ///< Handle Install state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); ///< Handle Self Test Dry state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); ///< Handle Prime state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); ///< Handle Recirculate state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); ///< Handle Confirm Rx state during Pre-Treatment -static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); ///< Handle Patient Connection state during Pre-Treatment +static void setPreTreatStateTransition( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleInstallState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleSelfTestDryState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handlePrimeState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleRecirculateState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleRxState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handleHeparinSetupState( void ); +static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ); +static void handlePreTreatmentQdTransition( void ); +static void publishPreTreatmentStates( void ); /*********************************************************************//** * @brief @@ -64,9 +91,26 @@ { // Start a fresh Treatment Parameters session for this run. initTreatmentParameters(); + initPreTxHeparinSetup(); + currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; goToInstallStateRequested = FALSE; continueFromRecirculateRequested = FALSE; + continueFromHeparinSetupRequested = FALSE; + treatmentStartRequested = FALSE; + lowQdTransitionActive = FALSE; + lowQdTransitionStartTime = 0U; + defaultQdApplied = FALSE; + preTreatmentRxUpdated = FALSE; + preTreatmentStateBroadcastTimerCtr = PRE_TREATMENT_STATE_DATA_PUB_INITIAL_OFFSET; + + preTreatmentStatePublishInterval = (OVERRIDE_U32_T) + { + PRE_TREATMENT_STATE_DATA_PUB_INTERVAL, + PRE_TREATMENT_STATE_DATA_PUB_INTERVAL, + PRE_TREATMENT_STATE_DATA_PUB_INTERVAL, + 0 + }; } /*********************************************************************//** @@ -136,20 +180,32 @@ currentPreTreatmentState = handleRecirculateState(); break; + case TD_PRE_TREATMENT_HEPARIN_SETUP_STATE: + currentPreTreatmentState = handleHeparinSetupState(); + break; + case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: - // currentPreTreatmentState = handlePatientConnectionState(); + currentPreTreatmentState = handlePatientConnectionState(); break; default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, (U32)currentPreTreatmentState ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, + SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, + (U32)currentPreTreatmentState ); break; } + if ( currentPreTreatmentState > TD_PRE_TREATMENT_PRIME_STATE ) + { + handlePreTreatmentQdTransition(); + } if ( prevPreTreatmentState != currentPreTreatmentState ) { setPreTreatStateTransition(); } + publishPreTreatmentStates(); + return (U32)currentPreTreatmentState; } @@ -187,16 +243,32 @@ // No action required. break; + case TD_PRE_TREATMENT_HEPARIN_SETUP_STATE: + // Heparin Setup transition is already handled in handleRxState(). + break; + case TD_PRE_TREATMENT_RECIRCULATE_STATE: // No action required. break; case TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE: - // TODO: actuator configuration + signalBloodPumpHardStop(); + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + setAirPumpState( AIR_PUMP_STATE_OFF, AIR_PUMP_MOTOR_OFF ); + set3WayValveState( H13_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + set3WayValveState( H20_VALV, VALVE_3WAY_COMMON_TO_CLOSED_STATE ); + stopSyringePump(); + + // TODO: Set H5 ejector Off. + // TODO: Command DD to bypass dialyzer, set QDt to prescribed rate, + // Quf to 0, and Qs to 0. break; default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, (U32)currentPreTreatmentState ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, + SW_FAULT_ID_MODE_PRE_TREATMENT_INVALID_STATE, + (U32)currentPreTreatmentState ); break; } } @@ -214,12 +286,12 @@ { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; - // call tube set install service to auto-load tube set + // Call Tube Set Install Service to auto-load the tube set. execTubeSetInstall(); if ( TRUE == isTubeSetInstallComplete() ) { - state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE; + state = TD_PRE_TREATMENT_SELF_TEST_DRY_STATE ; } return state; @@ -285,12 +357,30 @@ if ( TRUE == continueFromRecirculateRequested ) { continueFromRecirculateRequested = FALSE; + state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; + } - // TODO: Change to TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE - // when Patient Connection state is implemented. - // state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + return state; +} - requestNewOperationMode( MODE_TREA ); +/*********************************************************************//** + * @brief + * The handleHeparinSetupState function executes the Heparin Setup state of + * pre-treatment mode. + * @details \b Inputs: continueFromHeparinSetupRequested. + * @details \b Outputs: continueFromHeparinSetupRequested + * @return next Pre-Treatment mode state. + *************************************************************************/ +static TD_PRE_TREATMENT_MODE_STATE_T handleHeparinSetupState( void ) +{ + TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_HEPARIN_SETUP_STATE; + + execPreTxHeparinSetup(); + + if ( TRUE == continueFromHeparinSetupRequested ) + { + continueFromHeparinSetupRequested = FALSE; + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } return state; @@ -308,58 +398,155 @@ { BOOL paramsValid = getValidTreatParamsReceived(); BOOL paramsConfirmed = getTreatParamsConfirmed(); + BOOL heparinIsPrescribed = ( ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) > 0.0F ) || + ( getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DELIVERY_RATE ) > 0.0F ) ) ? TRUE : FALSE; BOOL isDialysateGoodToDeliver = TRUE; // TODO replace TRUE with getDialysateGoodToDeliverStatus() when we are ready F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; F32 presUFVolumeL = 0.0F; F32 presUFRateMlMin = 0.0F; + U32 prescribedQd = 0U; + F32 prescribedDialTemp = 0.0F; + F32 ddQd = 0.0F; + F32 ddDialTemp = 0.0F; U32 ddSubMode = getDDSubMode(); TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; DD_OP_MODE_T ddOpMode = getDDOpMode(); - // Valid + confirmed – move to next state: Recirculate State + // Valid + confirmed – move to Heparin Setup or Patient Connection. if ( ( TRUE == paramsValid ) && ( TRUE == paramsConfirmed ) ) { - // TODO this command of requesting dialysate delivery will move to appropriate state in pre-treatment once implemented if ( ( ddOpMode == DD_MODE_PREG ) && ( ddSubMode == DD_PRE_GEN_DIALYSATE_WAIT_FOR_GEND ) ) { presUFVolumeL = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); presUFRateMlMin = ( presUFVolumeL * (F32)ML_PER_LITER ) / (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + + ddQd = (F32)prescribedQd; + ddDialTemp = prescribedDialTemp; + + if ( ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) && + ( ( TRUE == lowQdTransitionActive ) || ( TRUE == preTreatmentRxUpdated ) ) ) + { + ddQd = (F32)PRE_TX_INTERMEDIATE_QD_ML_MIN; + ddDialTemp = prescribedDialTemp + 1.0F; + } + // Direct DD to generate dialysate and bypass while priming blood - cmdStartGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), presUFRateMlMin, 0.0, - getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), TRUE, + cmdStartGenerateDialysate( ddQd, + presUFRateMlMin, + ddDialTemp, + TRUE, getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), bicarbConvFactor, getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); } + if ( TRUE == heparinIsPrescribed ) + { + transitionToPreTxHeparinSetup(); + state = TD_PRE_TREATMENT_HEPARIN_SETUP_STATE; + } + else + { + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; + } + } - state = TD_PRE_TREATMENT_RECIRCULATE_STATE; - } - - return state; + return state; } /*********************************************************************//** * @brief * The handlePatientConnectionState function executes the Patient - * Connection state of pre-treatment mode. - * @details \b Inputs: TODO fill up if any - * @details \b Outputs: TODO fill up if any - * @return next Pre-Treatment mode state. + * Connection pre-treatment step. + * @details \b Inputs: treatmentStartRequested. + * @details \b Outputs: Requests transition to Treatment Mode when the + * UI Start Treatment request is received. + * @return current Pre-Treatment mode state. *************************************************************************/ static TD_PRE_TREATMENT_MODE_STATE_T handlePatientConnectionState( void ) { TD_PRE_TREATMENT_MODE_STATE_T state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; - // TODO : after implementing this state, place the transition in the right place + if ( TRUE == treatmentStartRequested ) + { + treatmentStartRequested = FALSE; + requestNewOperationMode( MODE_TREA ); + } - //requestNewOperationMode( MODE_TREA ); - return state; } /*********************************************************************//** * @brief + * The handlePreTreatmentQdTransition function manages the dialysate flow + * and temperature transition after priming is complete. + * @details \b Inputs: preTreatmentRxUpdated, lowQdTransitionActive, + * lowQdTransitionStartTime, defaultQdApplied, treatment parameters. + * @details \b Outputs: preTreatmentRxUpdated, lowQdTransitionActive, + * lowQdTransitionStartTime, defaultQdApplied, dialysate flow rate, + * dialysate target temperature. + * @return none. + *************************************************************************/ +static void handlePreTreatmentQdTransition( void ) +{ + U32 prescribedQd; + F32 prescribedDialTemp; + + if ( TRUE != getValidTreatParamsReceived() ) + { + if ( TRUE != defaultQdApplied ) + { + cmdChangeQd( PRE_TX_DEFAULT_QD_ML_MIN ); + defaultQdApplied = TRUE; + } + } + else + { + prescribedQd = getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ); + prescribedDialTemp = getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ); + + if ( TRUE == preTreatmentRxUpdated ) + { + preTreatmentRxUpdated = FALSE; + defaultQdApplied = FALSE; + + if ( prescribedQd <= PRE_TX_LOW_QD_THRESHOLD_ML_MIN ) + { + if ( TRUE != lowQdTransitionActive ) + { + cmdChangeQd( PRE_TX_INTERMEDIATE_QD_ML_MIN ); + + lowQdTransitionStartTime = getMSTimerCount(); + lowQdTransitionActive = TRUE; + } + + cmdChangeDialysateTemperature( prescribedDialTemp + 1.0F ); + } + else + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); + + lowQdTransitionActive = FALSE; + } + } + + if ( ( TRUE == lowQdTransitionActive ) && + ( TRUE == didTimeout( lowQdTransitionStartTime, + PRE_TX_LOW_QD_TRANSITION_TIME_MS ) ) ) + { + cmdChangeQd( prescribedQd ); + cmdChangeDialysateTemperature( prescribedDialTemp ); + + lowQdTransitionActive = FALSE; + } + } +} + +/*********************************************************************//** + * @brief * The PreTxRequestTubeSetInstall function signals a request to transition * the Pre-Treatment mode state machine to Install state. * @details \b Inputs: none @@ -374,7 +561,7 @@ /*********************************************************************//** * @brief * The PreTxRequestContinueFromRecirculate function signals a request to - * transition the Pre-Treatment mode state machine to Patient Connection state. + * transition the Pre-Treatment mode state machine to Confirm Rx state. * @details \b Inputs: none * @details \b Outputs: continueFromRecirculateRequested * @return none @@ -386,32 +573,199 @@ /*********************************************************************//** * @brief + * The PreTxRequestContinueFromHeparinSetupRequested function signals a request to + * transition the Pre-Treatment mode state machine to Patient Connection state. + * @details \b Inputs: none + * @details \b Outputs: continueFromHeparinSetupRequested + * @return none + *************************************************************************/ +void PreTxRequestContinueFromHeparinSetupRequested( void ) +{ + continueFromHeparinSetupRequested = TRUE; +} + +/*********************************************************************//** +* @brief +* The handleStartTreatmentRequest function handles the UI request to +* start treatment. +* @details \b Message \b Received: MSG_ID_UI_START_TREATMENT_REQUEST. +* @details \b Message \b Sent: MSG_ID_TD_START_TREATMENT_RESPONSE. +* @details \b Inputs: current operation mode and Pre-Treatment state. +* @details \b Outputs: treatmentStartRequested. +* @param message Pointer to the received Start Treatment request message. +* @return TRUE if the request was accepted, otherwise FALSE. +*************************************************************************/ +BOOL handleStartTreatmentRequest( MESSAGE_T *message ) +{ + TD_OP_MODE_T mode = getCurrentOperationMode(); + TD_PRE_TREATMENT_MODE_STATE_T preTxState = currentPreTreatmentState; + U32 payloadLen = message->hdr.payloadLen; + BOOL accepted = FALSE; + UI_RESPONSE_PAYLOAD_T response; + + response.accepted = FALSE; + response.rejectionReason = REQUEST_REJECT_REASON_ACTION_DISABLED_IN_CURRENT_STATE; + + if ( ( 0U == payloadLen ) && ( MODE_PRET == mode ) && + ( TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE == preTxState ) ) + + { + treatmentStartRequested = TRUE; + accepted = TRUE; + response.accepted = TRUE; + response.rejectionReason = REQUEST_REJECT_REASON_NONE; + } + + sendMessage( MSG_ID_TD_START_TREATMENT_RESPONSE, COMM_BUFFER_OUT_CAN_TD_2_UI, + (U08 *)&response, sizeof( UI_RESPONSE_PAYLOAD_T ) ); + + return accepted; +} + +/*********************************************************************//** +* @brief +* The signalPreTreatmentBackoutToStandby function handles a request to +* back out of Pre-Treatment to Standby. +* @details \b Inputs: current operation mode, currentPreTreatmentState, +* and Tube Set Install state. +* @details \b Outputs: Requests Standby Mode when backout is allowed. +* @return TRUE if the request is accepted, otherwise FALSE. +*************************************************************************/ +BOOL signalPreTreatmentBackoutToStandby( void ) +{ + BOOL accepted = FALSE; + + if ( ( MODE_PRET == getCurrentOperationMode() ) && + ( TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE == currentPreTreatmentState ) && + ( TRUE == isTubeSetInstallAwaitingConfirmation() ) ) + { + requestNewOperationMode( MODE_STAN ); + accepted = TRUE; + } + + return accepted; +} + +/*********************************************************************//** + * @brief + * The signalPreTreatmentRxUpdated function signals that a new or updated + * treatment prescription has been received during Pre-Treatment. + * @details \b Inputs: none. + * @details \b Outputs: preTreatmentRxUpdated. + * @return none. + *************************************************************************/ +void signalPreTreatmentRxUpdated( void ) +{ + preTreatmentRxUpdated = TRUE; +} + +/*********************************************************************//** + * @brief * The signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. - * @details \b Inputs: currentPreTreatmentState - * @details \b Outputs: given alarm action executed - * @param action ID of alarm action to execute + * @details \b Inputs: currentPreTreatmentState and current Heparin Setup sub-state. + * @details \b Outputs: Alarm action handled for the active Pre-Treatment state. + * @param action ID of alarm action to execute. * @return none *************************************************************************/ void signalAlarmActionToPreTreatmentMode( ALARM_ACTION_T action ) { switch ( action ) { case ALARM_ACTION_STOP: - // TODO add logic once we have pre-treatment mode developed + // TODO add logic once we have pre-treatment mode developed. break; case ALARM_ACTION_RESUME: - if ( TD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) - { + if ( TD_PRE_TREATMENT_RECIRCULATE_STATE == currentPreTreatmentState ) + { signalResumePreTxRecirculate(); - } - break; + } + else if ( TD_PRE_TREATMENT_HEPARIN_SETUP_STATE == currentPreTreatmentState ) + { + signalResumePreTxHeparinSetup(); + } + else + { + // No action required. + } + break; + case ALARM_ACTION_ACK: + if ( ( TD_PRE_TREATMENT_HEPARIN_SETUP_STATE == currentPreTreatmentState ) && + ( TRUE == isPreTxHeparinAwaitingSyringeLoadConfirmation() ) && + ( FALSE == isAlarmActive( ALARM_ID_TD_PRE_TX_HEPARIN_LOAD_SYRINGE ) ) ) + { + // OK on the Load Syringe clear-only alarm confirms that + // the syringe was loaded and resumes the paused state. + signalResumePreTxHeparinSetup(); + } + break; + default: - // do not handle other actions in pre-treatment mode + // Do not handle other actions in Pre-Treatment mode. break; } } +/*********************************************************************//** + * @brief + * The publishPreTreatmentStates function publishes the current + * Pre-Treatment state and associated sub-state data to the UI. + * @details \b Inputs: currentPreTreatmentState, preTreatmentStatePublishInterval + * preTreatmentStateBroadcastTimerCtr. + * @details \b Outputs: preTreatmentStateBroadcastTimerCtr. + * @return none + *************************************************************************/ +static void publishPreTreatmentStates( void ) +{ + if ( ++preTreatmentStateBroadcastTimerCtr >= getU32OverrideValue( &preTreatmentStatePublishInterval ) ) + { + PRE_TREATMENT_STATES_DATA_PAYLOAD_T payload = { 0 }; + + preTreatmentStateBroadcastTimerCtr = 0; + + payload.mSubMode = (U32)currentPreTreatmentState; + payload.mInstallState = (U32)getTubeSetInstallState(); + payload.mSelfTestDryState = 0; + payload.mPrimeState = 0; + payload.mRecirculateState = getPreTxRecirculateState(); + payload.mConfirmRxState = 0; + payload.mHeparinState = 0; + payload.mPatientConnectionState = 0; + + broadcastData( MSG_ID_TD_PRE_TREATMENT_STATES_DATA, + COMM_BUFFER_OUT_CAN_TD_BROADCAST, + (U08 *)&payload, + sizeof( PRE_TREATMENT_STATES_DATA_PAYLOAD_T ) ); + } +} + + +/************************************************************************* + * TEST SUPPORT FUNCTIONS + *************************************************************************/ + + +/*********************************************************************//** + * @brief + * The testPreTreatmentStatePublishIntervalOverride function overrides or + * resets the Pre-Treatment state data publication interval. + * @details \b Inputs: message + * @details \b Outputs: preTreatmentStatePublishInterval + * @param message Override message from Dial-in containing the interval + * in milliseconds, or a reset command. + * @return TRUE if the override or reset is successful, otherwise FALSE. + *************************************************************************/ +BOOL testPreTreatmentStatePublishIntervalOverride( MESSAGE_T *message ) +{ + BOOL result = FALSE; + + result = u32BroadcastIntervalOverride( message, + &preTreatmentStatePublishInterval, + TASK_GENERAL_INTERVAL ); + + return result; +} + /**@}*/ Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r8acb1d02ac39d202a47338091b249ff2f30f5ea7 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 8acb1d02ac39d202a47338091b249ff2f30f5ea7) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file ModeTreatment.c * -* @author (last) Vijay Pamula -* @date (last) 26-Jun-2026 +* @author (last) Praneeth Bunne +* @date (last) 10-Aug-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -32,6 +32,8 @@ #include "StateTxDialysis.h" #include "StateTxPaused.h" #include "StateTxHDF.h" +#include "StateTxRecirc.h" +#include "StateTxRinseback.h" //#include "Switches.h" #include "TaskGeneral.h" #include "Timers.h" @@ -94,9 +96,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 bloodPrimeToTreatmentRequest; ///< 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. @@ -135,6 +141,7 @@ treatmentCompleted = FALSE; rinsebackDone = FALSE; resumeBlockedByAlarm = FALSE; + recircAllowed = FALSE; treatmentTimePublishInterval.data = TREATMENT_TIME_DATA_PUB_INTERVAL; treatmentTimePublishInterval.ovData = TREATMENT_TIME_DATA_PUB_INTERVAL; @@ -190,8 +197,8 @@ initBloodPrime(); initDialysis(); initTreatmentPaused(); -// initRinseback(); -// initTreatmentRecirc(); + initRinseback(); + initTreatmentRecirc(); // initTreatmentEnd(); initFluidBolus(); initHDF(); @@ -286,6 +293,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 @@ -369,6 +390,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. @@ -401,6 +451,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; @@ -435,6 +489,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 @@ -586,8 +666,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 ) @@ -633,6 +714,43 @@ result = TREATMENT_DIALYSIS_STATE; } + + // Came back from temp break? + if ( TRUE == recircAllowed ) + { + // Add rinseback volume (ml) to uf volume. + F32 newUFVolumeMl = ( getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ) * + (F32)ML_PER_LITER ) + getDeliveredRinsebackVolume(); + F32 remainingTimeMins = (F32)( getTreatmentTimeRemainingSecs() / SEC_PER_MIN ); + F32 newUFRateMlMin = ( remainingTimeMins > 0.0F ) ? + ( newUFVolumeMl / remainingTimeMins ) : 0.0F; + + // Clamp to max UF volume + if ( newUFVolumeMl > (F32)MAX_UF_VOLUME_ML ) + { + newUFVolumeMl = (F32)MAX_UF_VOLUME_ML; + } + + // Clamp to max UF rate + if ( newUFRateMlMin > MAX_UF_RATE_ML_MIN ) + { + newUFRateMlMin = MAX_UF_RATE_ML_MIN; + } + + presUFVolumeMl = newUFVolumeMl; + presUFRateMlMin = newUFRateMlMin; + setTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME, + presUFVolumeMl / (F32)ML_PER_LITER ); + setDialysisDDParams( getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + presUFVolumeMl, + presUFRateMlMin ); + recircAllowed = FALSE; + } + + transitionToDialysis(); +// // To update partial blood pump occlusion baseline - start of treatment +// signalBloodPumpPressureOcclBaseline(); + result = TREATMENT_DIALYSIS_STATE; } } @@ -751,8 +869,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, recircAllowed * @return next treatment mode state *************************************************************************/ static TREATMENT_STATE_T handleTreatmentPausedState( void ) @@ -763,8 +882,6 @@ // If user requests resumption of treatment, resume treatment if ( TRUE == resumeTreatmentAlarmResponseRequest ) { - resumeTreatmentAlarmResponseRequest = FALSE; - if ( TRUE == getBloodIsPrimed() ) { lastTreatmentTimeStamp = getMSTimerCount(); @@ -786,18 +903,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 { @@ -823,89 +948,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; } @@ -1010,8 +1121,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; // @@ -1194,11 +1305,11 @@ *************************************************************************/ static void resetSignalFlags( void ) { -// rinsebackTopedRequest = FALSE; endTreatmentRequest = FALSE; -// rinsebackToRecircRequest = FALSE; - bloodPrimeToTreatmentRequest = FALSE; -// treatmentEndToRinsebackRequest = FALSE; + rinsebackToRecircRequest = FALSE; + bloodPrimeToDialysisRequest = FALSE; +// treatmentEndToRinsebackRequest = FALSE; // TODO: Declare & uncomment when end treat is implemented. + recirculateToBloodPrimeRequest = FALSE; } /*********************************************************************//** @@ -1213,6 +1324,7 @@ resumeTreatmentAlarmResponseRequest = FALSE; initiateRinsebackAlarmResponseRequest = FALSE; endTreatmentAlarmResponseRequest = FALSE; + initiateTempBreakALarmReponseRequest = FALSE; } /*********************************************************************//** Index: firmware/App/Modes/StateTxDialysis.c =================================================================== diff -u -rfff7eb3560421130e0cd4788f84bce0a8ee7ff44 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision fff7eb3560421130e0cd4788f84bce0a8ee7ff44) +++ firmware/App/Modes/StateTxDialysis.c (.../StateTxDialysis.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -8,7 +8,7 @@ * @file StateTxDialysis.c * * @author (last) Praneeth Bunne -* @date (last) 03-Jun-2026 +* @date (last) 09-Jul-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -119,6 +119,7 @@ // Set user alarm recovery actions allowed in this sub-mode 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 ); Index: firmware/App/Modes/StateTxPaused.c =================================================================== diff -u -rbbd48b033ef7307a30815e490eb28825c7afcc2b -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision bbd48b033ef7307a30815e490eb28825c7afcc2b) +++ firmware/App/Modes/StateTxPaused.c (.../StateTxPaused.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file StateTxPaused.c * -* @author (last) Praneeth Bunne -* @date (last) 26-Jun-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 11-Aug-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -27,7 +27,7 @@ #include "ModeTreatment.h" //#include "NVDataMgmt.h" #include "OperationModes.h" -#include "RotaryValve.h" +#include "Pressures.h" #include "StateTxPaused.h" #include "Switches.h" #include "TaskGeneral.h" @@ -107,21 +107,14 @@ 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 ); // TODO figure out the code -// signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); + signalInitiatePressureStabilization( USE_NORMAL_STABILIZATION_PERIOD ); // Reset blood leak zeroing params // resetBloodLeakZeroingVariables(); @@ -368,34 +361,27 @@ * 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 ) + bloodSittingTimerCtr++; + + if ( FALSE == doesAlarmStatusIndicateEndTxOnly() ) // Alarms appropriate only if we are not already at an alarm stop, end Tx only { - bloodSittingTimerCtr++; - if ( FALSE == doesAlarmStatusIndicateEndTxOnly() ) // Alarms appropriate only if we are not already at an alarm stop, end Tx only + if ( bloodSittingTimerCtr > WARN_TIME_BLOOD_SITTING ) { - if ( bloodSittingTimerCtr > WARN_TIME_BLOOD_SITTING ) - { - activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_WARNING ); - } - if ( bloodSittingTimerCtr > MAX_TIME_BLOOD_SITTING ) - { - // Activate the alarm - activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_TOO_LONG ); - } + activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_WARNING ); } + if ( bloodSittingTimerCtr > MAX_TIME_BLOOD_SITTING ) + { + // Activate the alarm + activateAlarmNoData( ALARM_ID_TD_BLOOD_SITTING_TOO_LONG ); + } } - else - { - bloodSittingTimerCtr = 0; - } } /*********************************************************************//** Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -r8acb1d02ac39d202a47338091b249ff2f30f5ea7 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 8acb1d02ac39d202a47338091b249ff2f30f5ea7) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file AlarmMgmtSWFaults.h * -* @author (last) Praneeth Bunne -* @date (last) 02-Jul-2026 +* @author (last) Vijay Pamula +* @date (last) 12-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -199,6 +199,13 @@ 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_MESSAGE_PAYLOAD_LENGTH = 171, + SW_FAULT_ID_TD_BP_DRIVER_STATE = 172, + SW_FAULT_ID_TD_BP_MODULE_STATE = 173, + SW_FAULT_ID_INVALID_RINSEBACK_STATE = 174, + SW_FAULT_ID_TREATMENT_INVALID_RECIRC_STATE = 175, + SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_STATE =176, + SW_FAULT_ID_TD_INVALID_PRE_TX_HEPARIN_SETUP_REQUESTED_STATE = 177, SW_FAULT_ID_HDF_INVALID_EXEC_STATE = 171, SW_FAULT_ID_TX_HDF_INVALID_STATE1 = 172, NUM_OF_SW_FAULT_IDS Index: firmware/App/Services/DDInterface.c =================================================================== diff -u -rbbd48b033ef7307a30815e490eb28825c7afcc2b -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Services/DDInterface.c (.../DDInterface.c) (revision bbd48b033ef7307a30815e490eb28825c7afcc2b) +++ firmware/App/Services/DDInterface.c (.../DDInterface.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file DDInterface.c * -* @author (last) Varshini Nagabooshanam -* @date (last) 15-Jun-2026 +* @author (last) Vijay Pamula +* @date (last) 19-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -487,6 +487,36 @@ /*********************************************************************//** * @brief + * The cmdChangeDialysateTemperature function sends a generate dialysate + * command to the DD with a given new dialysate temperature. + * @details \b Inputs: none + * @details \b Outputs: dialysateDeliveryCmdSet + * @details \b Message \b Sent: Continue generate dialysate command w/ new + * dialysate temperature. + * @param dialTemp Target dialysate temperature in deg C. + * @return none + *************************************************************************/ +void cmdChangeDialysateTemperature( F32 dialTemp ) +{ + if ( TRUE == dialysateDeliveryCmdSet.start ) + { + dialysateDeliveryCmdSet.dialTemp = dialTemp; + +#ifndef TEST_UI_ONLY + sendMessage( MSG_ID_DD_GEN_DIALYSATE_REQUEST_DATA, + COMM_BUFFER_OUT_CAN_TD_2_DD, + (U08*)(&dialysateDeliveryCmdSet), + sizeof( DIALYSATE_DELIVERY_REQ_PAYLOAD_T ) ); +#endif + } + else + { + // TODO - s/w fault? + } +} + +/*********************************************************************//** + * @brief * The cmdBypassDialyzer function sends a generate dialysate command to the DD * with a given flag indicating whether dialyzer should be bypassed. * @details \b Inputs: none @@ -642,7 +672,8 @@ { dialysateDeliveryCmdSet.substitutionRate = qs; #ifndef TEST_UI_ONLY - sendMessage( MSG_ID_DD_GEN_DIALYSATE_REQUEST_DATA, COMM_BUFFER_OUT_CAN_TD_2_DD, (U08*)(&dialysateDeliveryCmdSet), sizeof( DIALYSATE_DELIVERY_REQ_PAYLOAD_T ) ); + sendMessage( MSG_ID_DD_GEN_DIALYSATE_REQUEST_DATA, COMM_BUFFER_OUT_CAN_TD_2_DD, + (U08*)(&dialysateDeliveryCmdSet), sizeof( DIALYSATE_DELIVERY_REQ_PAYLOAD_T ) ); #endif } else Index: firmware/App/Services/DDInterface.h =================================================================== diff -u -rfff7eb3560421130e0cd4788f84bce0a8ee7ff44 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Services/DDInterface.h (.../DDInterface.h) (revision fff7eb3560421130e0cd4788f84bce0a8ee7ff44) +++ firmware/App/Services/DDInterface.h (.../DDInterface.h) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file DDInterface.h * -* @author (last) Praneeth Bunne -* @date (last) 27-May-2026 +* @author (last) Vijay Pamula +* @date (last) 19-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -63,6 +63,7 @@ void cmdChangeQd( F32 qd ); void cmdChangeQuf( F32 quf ); void cmdChangeQhdf( F32 qsub ); +void cmdChangeDialysateTemperature( F32 dialTemp ); void cmdBypassDialyzer( BOOL bypass ); void cmdStopGenerateDialysate( void ); void cmdSubstitutionRate (F32 qs ); Index: firmware/App/Services/Messaging.c =================================================================== diff -u -r8acb1d02ac39d202a47338091b249ff2f30f5ea7 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision 8acb1d02ac39d202a47338091b249ff2f30f5ea7) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file Messaging.c * -* @author (last) Vijay Pamula -* @date (last) 14-Jul-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 11-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -21,6 +21,7 @@ #include "AirTrap.h" #include "AlarmMgmt.h" #include "BloodFlow.h" +#include "BPModule.h" #include "Bubbles.h" #include "Buttons.h" #include "Compatible.h" @@ -32,15 +33,18 @@ #include "HemoDiaFiltration.h" #include "LevelSensors.h" #include "Messaging.h" +#include "ModeInitPOST.h" +#include "ModePreTreat.h" #include "ModeStandby.h" #include "ModeTreatment.h" #include "OperationModes.h" #include "PAL.h" #include "Pressures.h" -#include "RotaryValve.h" #include "StateTxBloodPrime.h" #include "StateTxDialysis.h" #include "StateTxPaused.h" +#include "StateTxRecirc.h" +#include "StateTxRinseback.h" #include "Switches.h" #include "SyringePump.h" #include "SystemCommTD.h" @@ -112,6 +116,7 @@ { MSG_ID_FW_VERSIONS_REQUEST, &handleVersionRequestMessage }, { MSG_ID_UI_CHECK_IN, &handleUICheckIn }, { MSG_ID_DD_OP_MODE_DATA, &setDDOpMode }, + { MSG_ID_UI_VERSION_INFO_RESPONSE, &handleUIVersionResponse }, { MSG_ID_DD_GEN_DIALYSATE_MODE_DATA, &setDialysateData }, { MSG_ID_DD_PRESSURES_DATA, &setDialysatePressure }, { MSG_ID_UI_TREATMENT_PARAMS_TO_VALIDATE, &validateAndSetTreatmentParameters }, @@ -122,6 +127,7 @@ { MSG_ID_UI_VITALS_ADJUSTMENT_REQUEST, &vitalsAdjustmentHandleChangeRequest }, { MSG_ID_UI_BOLUS_VOLUME_CHANGE_REQUEST, &validateAndSetBolusVolume }, { MSG_ID_UI_INITIATE_TREATMENT_WORKFLOW, &signalUserInitiateTreatment }, + { MSG_ID_UI_START_TREATMENT_REQUEST, &handleStartTreatmentRequest }, { MSG_ID_UI_UF_PAUSE_RESUME_REQUEST, &signalPauseResumeUF }, { MSG_ID_TESTER_LOGIN_REQUEST, &handleTesterLogInRequest }, { MSG_ID_UI_PRESSURE_LIMIT_WIDEN_REQUEST, &pressureLimitHandleWidenRequest }, @@ -135,8 +141,12 @@ { MSG_ID_UI_ADJUST_DISPOSABLES_CONFIRM_REQUEST, &handleAutoLoadRequest }, { MSG_ID_UI_SETUP_TUBING_SET_CONNECTIONS_CONFIRM_REQUEST, &handleSetupTubingSetConnectionConfirmRequest }, { MSG_ID_UI_ADJUST_DISPOSABLES_REMOVAL_CONFIRM_REQUEST, &handleAutoEjectRequest }, + { MSG_ID_UI_BLOOD_PRESSURE_REQUEST, &bpModuleHandleVitalsRequest }, { 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 }, @@ -146,6 +156,7 @@ { MSG_ID_TD_PRESSURE_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testPressuresDataPublishIntervalOverride }, { MSG_ID_TD_AIR_PUMP_SET_STATE_REQUEST, &testSetAirPump }, { MSG_ID_TD_AIR_PUMP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testAirPumpDataPublishIntervalOverride }, + { MSG_ID_TD_AIR_PUMP_RPM_OVERRIDE_REQUEST, &testAirPumpRPMOverride }, { MSG_ID_TD_SWITCHES_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testSwitchesDataPublishIntervalOverride }, { MSG_ID_TD_SWITCH_STATE_OVERRIDE_REQUEST, &testSwitchOverride }, { MSG_ID_TD_OFF_BUTTON_OVERRIDE_REQUEST, &testOffButtonOverride }, @@ -159,9 +170,6 @@ { MSG_ID_TD_AIR_TRAP_LEVEL_RAW_OVERRIDE_REQUEST, &testRawLevelSensorOverride }, { MSG_ID_TD_AIR_TRAP_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testAirTrapDataPublishIntervalOverride }, { MSG_ID_TD_3_WAY_VALVE_SET_STATE_REQUEST, &testSet3WayValve }, - { MSG_ID_TD_ROTARY_PINCH_VALVE_SET_POS_REQUEST, &testSetValve }, - { MSG_ID_TD_ROTARY_PINCH_VALVE_STATUS_OVERRIDE_REQUEST, &testValveStatusOverride }, - { MSG_ID_TD_ROTARY_PINCH_VALVE_POSITION_OVERRIDE_REQUEST, &testValveEncoderPositionOverride }, { MSG_ID_TD_VALVES_PUBLISH_INTERVAL_OVERRIDE_REQUEST, &testValvesDataPublishIntervalOverride }, { MSG_ID_TD_PINCH_VALVE_SET_POSITION_REQUEST, &testValveSetABCCmdPosition }, { MSG_ID_TD_PINCH_VALVE_HOME_REQUEST, &testHomeValve }, @@ -220,6 +228,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 }, { MSG_ID_TD_HDF_START_STOP_OVERRIDE_REQUEST, &testTDHDFStartStopHDFOverride }, { MSG_ID_TD_HDF_CURRENT_RATE_OVERRIDE_REQUEST, &testTDHDFCurrentRateOverride }, { MSG_ID_TD_HDF_TARGET_TMP_OVERRIDE_REQUEST, &testTDHDFTargetTMPOverride }, @@ -244,7 +254,6 @@ static MsgFuncPtr getMsgHandler( U16 msgID ); static BOOL sendTestAckResponseMsg( MSG_ID_T msgID, BOOL ack ); -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ); /*********************************************************************//** * @brief @@ -403,7 +412,7 @@ * @param ack TRUE to ACK, FALSE to NAK * @return TRUE if response message successfully queued for transmit, FALSE if not *************************************************************************/ -static BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) +BOOL sendAckResponseMsg( MSG_ID_T msgID, COMM_BUFFER_T buffer, BOOL ack ) { BOOL result; MESSAGE_T msg; @@ -530,7 +539,79 @@ return result; } +/*********************************************************************//** + * @brief + * The handleUIVersionResponse function handles a response to request for + * UI version information. + * @details Inputs: none + * @details Outputs: none + * @param message a pointer to the message to handle. + * @return none + *************************************************************************/ +BOOL handleUIVersionResponse( MESSAGE_T *message ) +{ + BOOL result = TRUE; + // Get UI version data and have it recorded + if ( sizeof(UI_VERSIONS_T) == message->hdr.payloadLen ) + { + UI_VERSIONS_T uiVersion; + + memcpy( &uiVersion, &message->payload[ 0 ], sizeof(UI_VERSIONS_T) ); + signalUIVersion( uiVersion ); + } + + return result; +} + +/*********************************************************************//** + * The sendPOSTFinalResult function sends the overall TD POST result + * and queues the message for transmit on the appropriate CAN channel. + * @details \b Message \b Sent: MSG_ID_TD_POST_FINAL_TEST_RESULT + * @details \b Inputs: none + * @details \b Outputs: TD POST final result msg queued for CAN transmit. + * @param passed TRUE if all TD POST tests passed, FALSE otherwise. + * @return TRUE if message successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPOSTFinalResult( BOOL passed ) +{ + // Use the generic send helper for transmission. + return sendMessage( MSG_ID_TD_POST_FINAL_TEST_RESULT, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08 *)&passed, sizeof( BOOL ) ); +} + +/*********************************************************************//** + * @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; +} + // *********************************************************************** // ***************** Message Sending Helper Functions ******************** // *********************************************************************** @@ -575,36 +656,108 @@ /*********************************************************************//** * @brief - * The sendOffButtonMsgToUI function constructs an off button msg to the UI - * and queues the msg for transmit on the appropriate CAN channel. - * @details \b Message \b Sent: MSG_ID_OFF_BUTTON_PRESS_REQUEST + * The sendUIVersionRequest function constructs a UI version request msg + * to the UI and queues the msg for transmit on the appropriate CAN channel. + * @details \b Message \b Sent: MSG_ID_TD_UI_VERSION_INFO_REQUEST * @details \b Inputs: none - * @details \b Outputs: Off button msg constructed and queued. - * @param prompt 0=prompt user to confirm, 1=cancel prompt, 2=reject user off request + * @details \b Outputs: none * @return TRUE if msg successfully queued for transmit, FALSE if not *************************************************************************/ -BOOL sendOffButtonMsgToUI( U08 prompt ) +BOOL sendUIVersionRequest( void ) { BOOL result; MESSAGE_T msg; - UI_OFF_BUTTON_RESPONSE_PAYLOAD_T cmd; - cmd.userRequest = prompt; - // Create a message record blankMessage( &msg ); - msg.hdr.msgID = MSG_ID_OFF_BUTTON_PRESS_REQUEST; - msg.hdr.payloadLen = sizeof( UI_OFF_BUTTON_RESPONSE_PAYLOAD_T ); + msg.hdr.msgID = MSG_ID_TD_UI_VERSION_INFO_REQUEST; + msg.hdr.payloadLen = 0; - memcpy( &msg.payload, &cmd, sizeof( UI_OFF_BUTTON_RESPONSE_PAYLOAD_T ) ); - // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_TD_2_UI, ACK_REQUIRED ); return result; } +/*********************************************************************//** + * @brief + * The sendRequestForDDResendAlarms function sends out the TD request for + * DD re-send all active alarms. + * @details \b Inputs: none + * @details \b Outputs: DD alarms re-send request msg constructed and queued + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendRequestForDDResendAlarms( void ) +{ + BOOL result; + MESSAGE_T msg; + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_TD_DD_ALARMS_REQUEST; + msg.hdr.payloadLen = 0; + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_TD_2_DD, ACK_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * The sendPOSTTestResult function sends the result of a single TD POST + * test to the UI. + * @details \b Message \b Sent: MSG_ID_TD_POST_SINGLE_TEST_RESULT + * @details \b Inputs: none + * @details \b Outputs: TD POST test result msg queued for CAN transmit. + * @param test ID of the TD POST test. + * @param passed TRUE if POST test passed, FALSE if POST test failed. + * @return TRUE if message successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPOSTTestResult( TD_POST_STATE_T test, BOOL passed ) +{ + U08 payload[ sizeof( BOOL ) + sizeof( U32 ) ]; + U32 testID = (U32)test; + + memcpy( payload, &passed, sizeof( BOOL ) ); + memcpy( &payload[ sizeof( BOOL ) ], &testID, sizeof( U32 ) ); + + // Use the generic send helper for transmission. + return sendMessage( MSG_ID_TD_POST_SINGLE_TEST_RESULT, COMM_BUFFER_OUT_CAN_TD_BROADCAST, payload, sizeof( payload ) ); +} + +/*********************************************************************//** + * @brief + * The sendConfirmationRequest function constructs and transmits a + * confirmation request message to the UI. + * @details \b Message \b Sent: MSG_ID_TD_UI_GENERIC_CONFIRMATION_REQUEST + * @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 ) ); +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Services/StateServices/TubeSetInstall.c =================================================================== diff -u -r8acb1d02ac39d202a47338091b249ff2f30f5ea7 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Services/StateServices/TubeSetInstall.c (.../TubeSetInstall.c) (revision 8acb1d02ac39d202a47338091b249ff2f30f5ea7) +++ firmware/App/Services/StateServices/TubeSetInstall.c (.../TubeSetInstall.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -8,7 +8,7 @@ * @file TubeSetInstall.c * * @author (last) Vijay Pamula -* @date (last) 14-Jul-2026 +* @date (last) 28-Jul-2026 * * @author (original) Praneeth Bunne * @date (original) 01-May-2026 @@ -338,6 +338,19 @@ /*********************************************************************//** * @brief + * The getTubeSetInstallState function returns the current Tube Set + * Install sub-state. + * @details \b Inputs: currentInstallState. + * @details \b Outputs: none. + * @return Current Tube Set Install sub-state. + *************************************************************************/ +TUBE_SET_INSTALL_STATE_T getTubeSetInstallState( void ) +{ + return currentInstallState; +} + +/*********************************************************************//** + * @brief * The handleAutoLoadRequest function handles a UI request to * confirm tubeset installation. * @details \b Message \b Sent: MSG_ID_TD_ADJUST_DISPOSABLES_CONFIRM_RESPONSE @@ -490,4 +503,18 @@ } } +/*********************************************************************//** + * @brief + * The isTubeSetInstallAwaitingConfirmation function reports whether the + * Tube Set Install service is awaiting tubing set confirmation. + * @details \b Inputs: currentInstallState. + * @details \b Outputs: none. + * @return TRUE when awaiting tubing set confirmation, otherwise FALSE. + *************************************************************************/ +BOOL isTubeSetInstallAwaitingConfirmation( void ) +{ + return ( TUBE_SET_INSTALL_STATE_AWAIT_TUBE_SET_CONFIRMATION == + currentInstallState ) ? TRUE : FALSE; +} + /**@}*/ Index: firmware/App/Tasks/TaskGeneral.c =================================================================== diff -u -rfff7eb3560421130e0cd4788f84bce0a8ee7ff44 -ra89b071a59a5575e9bcd1b04d133ec318e24a411 --- firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision fff7eb3560421130e0cd4788f84bce0a8ee7ff44) +++ firmware/App/Tasks/TaskGeneral.c (.../TaskGeneral.c) (revision a89b071a59a5575e9bcd1b04d133ec318e24a411) @@ -7,8 +7,8 @@ * * @file TaskGeneral.c * -* @author (last) Praneeth Bunne -* @date (last) 27-May-2026 +* @author (last) Varshini Nagabooshanam +* @date (last) 14-Aug-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -18,10 +18,12 @@ #include "AirPump.h" #include "AirTrap.h" #include "BloodFlow.h" +#include "BPModule.h" #include "Ejector.h" #include "HemoDiaFiltration.h" #include "Messaging.h" #include "OperationModes.h" +#include "PinchValve.h" #include "Pressures.h" #include "Switches.h" #include "SystemCommTD.h" @@ -108,9 +110,15 @@ // Control air trap valve execAirTrapController(); - // Control pinch valves + // Control blood pressure vitals + execBPModule(); + + // Control valves execValvesController(); + // Control pinch valves + execPinchValveFunction(); + // Control ejector execEjectorController();