Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -rcff19e1c44fd570e139a2a3f49b5a05f0193367d -ra70cb02cb99d80ea585e44824964857a372075f9 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision cff19e1c44fd570e139a2a3f49b5a05f0193367d) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision a70cb02cb99d80ea585e44824964857a372075f9) @@ -8,7 +8,7 @@ * @file ModePreTreat.c * * @author (last) Vijay Pamula -* @date (last) 14-Jul-2026 +* @date (last) 31-Jul-2026 * * @author (original) Dara Navaei * @date (original) 25-Sep-2025 @@ -20,11 +20,13 @@ #include "BloodFlow.h" #include "Buttons.h" #include "DDInterface.h" +#include "Messaging.h" #include "ModePreTreat.h" #include "OperationModes.h" #include "PinchValve.h" #include "StatePreTxRecirculate.h" #include "SyringePump.h" +#include "TaskGeneral.h" #include "Timers.h" #include "TubeSetInstall.h" #include "TxParams.h" @@ -36,11 +38,22 @@ * @{ */ +// ********** 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 + // ********** 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. +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. // ********** private function prototypes ********** @@ -51,6 +64,7 @@ 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 publishPreTreatmentStates( void ); ///< Publish Pre-Treatment states to the UI. /*********************************************************************//** * @brief @@ -67,6 +81,16 @@ currentPreTreatmentState = TD_PRE_TREATMENT_TUBING_SET_INSTALL_STATE; goToInstallStateRequested = FALSE; continueFromRecirculateRequested = FALSE; + treatmentStartRequested = 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 + }; } /*********************************************************************//** @@ -137,11 +161,13 @@ 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; } @@ -150,6 +176,8 @@ setPreTreatStateTransition(); } + publishPreTreatmentStates(); + return (U32)currentPreTreatmentState; } @@ -192,11 +220,23 @@ 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; } } @@ -285,12 +325,7 @@ if ( TRUE == continueFromRecirculateRequested ) { continueFromRecirculateRequested = FALSE; - - // TODO: Change to TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE - // when Patient Connection state is implemented. - // state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; - - requestNewOperationMode( MODE_TREA ); + state = TD_PRE_TREATMENT_CONFIRM_RX_STATE; } return state; @@ -333,7 +368,7 @@ getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); } - state = TD_PRE_TREATMENT_RECIRCULATE_STATE; + state = TD_PRE_TREATMENT_PATIENT_CONNECTION_STATE; } return state; @@ -342,19 +377,22 @@ /*********************************************************************//** * @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; } @@ -374,7 +412,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,6 +424,68 @@ /*********************************************************************//** * @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 signalAlarmActionToPreTreatmentMode function executes the given alarm action * as appropriate while in Pre-Treatment Mode. * @details \b Inputs: currentPreTreatmentState @@ -414,4 +514,64 @@ } } +/*********************************************************************//** + * @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/ModeStandby.c =================================================================== diff -u -r7bb46513e0563ac58f769f654ac67ae694f369ad -ra70cb02cb99d80ea585e44824964857a372075f9 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 7bb46513e0563ac58f769f654ac67ae694f369ad) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision a70cb02cb99d80ea585e44824964857a372075f9) @@ -8,7 +8,7 @@ * @file ModeStandby.c * * @author (last) Vijay Pamula -* @date (last) 07-Jul-2026 +* @date (last) 27-Jul-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -400,8 +400,9 @@ } else if ( USER_COMMAND_CANCEL == cmd ) { - //result = signalUserCancelTreatment(); - if ( result != TRUE ) + result = signalPreTreatmentBackoutToStandby(); + + if ( TRUE != result ) { rejReason = REQUEST_REJECT_REASON_NOT_ALLOWED_IN_CURRENT_MODE; } Index: firmware/App/Services/Messaging.c =================================================================== diff -u -re0060cd79d971c0ed94b8aed6949d2754480fe92 -ra70cb02cb99d80ea585e44824964857a372075f9 --- firmware/App/Services/Messaging.c (.../Messaging.c) (revision e0060cd79d971c0ed94b8aed6949d2754480fe92) +++ firmware/App/Services/Messaging.c (.../Messaging.c) (revision a70cb02cb99d80ea585e44824964857a372075f9) @@ -8,7 +8,7 @@ * @file Messaging.c * * @author (last) Vijay Pamula -* @date (last) 14-Jul-2026 +* @date (last) 27-Jul-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -31,6 +31,7 @@ #include "FpgaTD.h" #include "LevelSensors.h" #include "Messaging.h" +#include "ModePreTreat.h" #include "ModeStandby.h" #include "ModeTreatment.h" #include "OperationModes.h" @@ -120,6 +121,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 }, Index: firmware/App/TDCommon.h =================================================================== diff -u -rf35ae0e2ac747080dad50ea6fecb138807ee1383 -ra70cb02cb99d80ea585e44824964857a372075f9 --- firmware/App/TDCommon.h (.../TDCommon.h) (revision f35ae0e2ac747080dad50ea6fecb138807ee1383) +++ firmware/App/TDCommon.h (.../TDCommon.h) (revision a70cb02cb99d80ea585e44824964857a372075f9) @@ -39,7 +39,7 @@ // #define TEST_UI_ONLY 1 // Alpha test with TD and UI only - no DD // #define TEST_DISABLE_UI_ALARMS 1 // Disable UI alarms // #define TEST_USE_OFF_AS_STOP_BUTTON 1 // Alpha test re-purposing off button as a stop button -// #define TEST_NO_PRESSURE_CHECKS 1 // Alpha test with no pressure sensor checks +// #define TEST_NO_PRESSURE_CHECKS 1 // Alpha test with no pressure sensor checks // #define TEST_NO_STOP_CONSUME_CHECK 1 // Alpha test with no check for stop button timeout // #define ASN_DEMO 1