Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rb777859b2667c350c6ca9fda60a668c9eb5fe02d -r934ce8fc097623360b8db3619194348fb4fad09f --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision b777859b2667c350c6ca9fda60a668c9eb5fe02d) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 934ce8fc097623360b8db3619194348fb4fad09f) @@ -7,8 +7,8 @@ * * @file ModeStandby.c * -* @author (last) Raghu Kallala -* @date (last) 06-Apr-2026 +* @author (last) Arpita Srivastava +* @date (last) 18-May-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 @@ -104,7 +104,6 @@ } doorClosedRequired( FALSE ); // door no longer required to be closed in standby mode -// syringeDetectionRequired( FALSE ); // Request DD service record and usage information from DD // sendDGServiceRequestToDG(); @@ -219,6 +218,7 @@ { TD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_TREATMENT_STATE; DD_OP_MODE_T ddOperationMode = getDDOpMode(); + F32 bicarbConvFactor = BICARBONATE_CONVERSION_FACTOR; // switch ( dgOperationMode ) // { @@ -270,6 +270,13 @@ respRecord.venPresLimitAsymmetricmmHg = getSysConfigTreatmentParameterU32DefaultValue( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); respRecord.tmpPresLimitWindowmmHg = getSysConfigTreatmentParameterU32DefaultValue( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ); sendPressureLimitsChangeResponse( &respRecord ); + // start DD pre-gen // TODO + cmdStartPreGenerateDialysate( (F32)getTreatmentParameterU32( TREATMENT_PARAM_DIALYSATE_FLOW ), + getTreatmentParameterF32( TREATMENT_PARAM_DIALYSATE_TEMPERATURE ), + getTreatmentParameterF32( TREATMENT_PARAM_ACID_CONCENTRATE_CONV_FACTOR ), + bicarbConvFactor, + getTreatmentParameterU32( TREATMENT_PARAM_SODIUM ), + getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); // Start treatment workflow with pretreatment mode requestNewOperationMode( MODE_PRET ); treatStartReqReceived = FALSE; Index: firmware/App/Modes/StateTxBloodPrime.c =================================================================== diff -u -rb777859b2667c350c6ca9fda60a668c9eb5fe02d -r934ce8fc097623360b8db3619194348fb4fad09f --- firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision b777859b2667c350c6ca9fda60a668c9eb5fe02d) +++ firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision 934ce8fc097623360b8db3619194348fb4fad09f) @@ -7,8 +7,8 @@ * * @file StateTxBloodPrime.c * -* @author (last) Varshini Nagabooshanam -* @date (last) 17-Mar-2026 +* @author (last) Praneeth Bunne +* @date (last) 03-Jun-2026 * * @author (original) Varshini Nagabooshanam * @date (original) 09-Jan-2026 @@ -19,6 +19,7 @@ #include "BloodFlow.h" #include "Buttons.h" #include "DDInterface.h" +#include "FluidBolus.h" #include "Messaging.h" #include "ModeTreatment.h" #include "TxParams.h" @@ -66,9 +67,11 @@ static BLOOD_PRIME_STATE_T bloodPrimeState; ///< Current state of the blood prime sub-mode. static BLOOD_PRIME_STATE_T bloodPrimeResumeState; ///< Blood prime sub-state prior to pause. +static BLOOD_PRIME_STATE_T bolusCallingState; ///< Fluid Bolus calling state. static BOOL pendingPauseRequest; ///< Flag indicating UI has requested blood prime pause. static BOOL pendingResumeRequest; ///< Flag indicating UI has requested blood prime resume. static BOOL pendingFlowChangeRequest; ///< Flag indicating UI has requested blood prime flow change +static BOOL fluidBolusRequested; ///< Flag indicating fluid bolus has been requested by user. static F32 bloodPrimeRampFlowRate_mL_min; ///< Current blood pump ramp flow rate. static F32 bloodPrimeRampStep_mL; ///< Blood pump volume step size for ramping. @@ -78,9 +81,10 @@ static U32 bloodPrimePublishTimerCtr; ///< Timer counter for determining interval for blood prime status to be published. static U32 lastBloodPrimeFlowRate_mL_min; ///< Flow rate prior to pausing blood prime. static U32 requestedBloodFlowRate_mL_min; ///< Requested blood flow rate from UI. -static U32 bloodPrimeStartMS = 0; ///< Start time of Blood Prime (ms timer count) -static U32 bloodPrimeTimeoutSec = 0; ///< -static U32 bloodPrimeCountdownSec = 0; ///< +static U32 bloodPrimeStartMS; ///< Start time of Blood Prime (ms timer count) +static U32 bloodPrimeTimeoutSec; ///< Blood prime pause timeout duration (broadcast to UI) +static U32 bloodPrimeCountdownSec; ///< Blood prime pause countdown remaining time (broadcast to UI) +static U32 pausedElapsedMS; ///< Elapsed pause time saved when fluid bolus starts from paused state. /// Interval (in task intervals) at which to publish blood prime data to CAN bus. static OVERRIDE_U32_T bloodPrimePublishInterval = { BLOOD_PRIME_DATA_PUBLISH_INTERVAL, BLOOD_PRIME_DATA_PUBLISH_INTERVAL, BLOOD_PRIME_DATA_PUBLISH_INTERVAL, 0 }; @@ -94,6 +98,7 @@ static BLOOD_PRIME_STATE_T handleBloodPrimeRampState( void ); static BLOOD_PRIME_STATE_T handleBloodPrimeRunState( void ); static BLOOD_PRIME_STATE_T handleBloodPrimePausedState( void ); +static BLOOD_PRIME_STATE_T handleBloodPrimeFluidBolusState( void ); static void handleBloodPrimePauseTimer( void ); static void publishBloodPrimeData( void ); @@ -112,6 +117,7 @@ bloodPrimeState = BLOOD_PRIME_RAMP_STATE; bloodPrimeResumeState = BLOOD_PRIME_RAMP_STATE; + bolusCallingState = BLOOD_PRIME_RAMP_STATE; bloodPrimeRampControlTimerCtr = 0; bloodPrimePublishTimerCtr = BLOOD_PRIME_DATA_PUBLISH_INTERVAL - 2; // setup so publish will occur time after next cumulativeBloodPrimeVolume_mL.data = 0.0; @@ -130,6 +136,10 @@ } bloodPrimeRampStep_mL = rampRateSpan / estRampSeconds; bloodPrimeStartMS = 0; + bloodPrimeTimeoutSec = 0; + bloodPrimeCountdownSec = 0; + pausedElapsedMS = 0; + fluidBolusRequested = FALSE; } /*********************************************************************//** @@ -234,6 +244,10 @@ bloodPrimeState = handleBloodPrimePausedState(); break; + case BLOOD_PRIME_FLUID_BOLUS_STATE: + bloodPrimeState = handleBloodPrimeFluidBolusState(); + break; + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_BLOOD_PRIME_INVALID_STATE, bloodPrimeState ); break; @@ -297,6 +311,17 @@ bloodPrimeResumeState = BLOOD_PRIME_RUN_STATE; result = BLOOD_PRIME_RUN_STATE; } + // When UI requests fluid bolus + else if ( TRUE == fluidBolusRequested ) + { + fluidBolusRequested = FALSE; + bloodPrimeResumeState = bloodPrimeState; + bolusCallingState = bloodPrimeState; + lastBloodPrimeFlowRate_mL_min = getTargetBloodFlowRate(); + // Start bolus and transition to bolus state + signalStartFluidBolus( lastBloodPrimeFlowRate_mL_min ); + result = BLOOD_PRIME_FLUID_BOLUS_STATE; + } else { // Continue ramping @@ -352,6 +377,21 @@ pendingFlowChangeRequest = FALSE; setBloodPumpTargetFlowRate( requestedBloodFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); } + // When UI requests fluid bolus + else if ( TRUE == fluidBolusRequested ) + { + fluidBolusRequested = FALSE; + bloodPrimeResumeState = bloodPrimeState; + bolusCallingState = bloodPrimeState; + lastBloodPrimeFlowRate_mL_min = getTargetBloodFlowRate(); + // Start bolus and transition to bolus state + signalStartFluidBolus( lastBloodPrimeFlowRate_mL_min ); + result = BLOOD_PRIME_FLUID_BOLUS_STATE; + } + else + { + // No action required. + } return result; } @@ -372,19 +412,73 @@ if ( TRUE == pendingResumeRequest ) { pendingResumeRequest = FALSE; + bolusCallingState = bloodPrimeResumeState; setBloodPumpTargetFlowRate( (U32)lastBloodPrimeFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); // Open art/ven pinch valves setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); // Return to state prior to pause result = bloodPrimeResumeState; } + // When UI requests fluid bolus + else if ( TRUE == fluidBolusRequested ) + { + fluidBolusRequested = FALSE; + bolusCallingState = bloodPrimeState; + // Save elapsed time + pausedElapsedMS = calcTimeSince( bloodPrimeStartMS ); + // Start bolus and transition to bolus state + signalStartFluidBolus( lastBloodPrimeFlowRate_mL_min ); + result = BLOOD_PRIME_FLUID_BOLUS_STATE; + } + else + { + // No action required. + } return result; } /*********************************************************************//** * @brief + * The handleBloodPrimeFluidBolusState function handles the fluid bolus + * state of the blood prime sub-mode. + * @details \b Inputs: bolusCallingState, lastBloodPrimeFlowRate_mL_min, + * bloodPrimeStartMS, pausedElapsedMS + * @details \b Outputs: bolusCallingState + * @return next blood prime state + *************************************************************************/ +static BLOOD_PRIME_STATE_T handleBloodPrimeFluidBolusState( void ) +{ + BLOOD_PRIME_STATE_T result = BLOOD_PRIME_FLUID_BOLUS_STATE; + + // Restore actuators and return to pre-bolus sub-state upon bolus complete or abort + if ( FALSE == isFluidBolusActive() ) + { + if( BLOOD_PRIME_PAUSED_STATE == bolusCallingState ) + { + // Resume from saved elapsed + bloodPrimeStartMS = getMSTimerCount() - pausedElapsedMS; + pausedElapsedMS = 0; + // Arterial valve is open to saline, not required here + setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); + setBloodPumpTargetFlowRate( 0, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + else + { + setValvePosition( H1_VALV, VALVE_POSITION_B_OPEN ); + setValvePosition( H19_VALV, VALVE_POSITION_B_OPEN ); + setBloodPumpTargetFlowRate( lastBloodPrimeFlowRate_mL_min, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + + result = bolusCallingState; + } + + return result; +} + +/*********************************************************************//** + * @brief * The getCurrentBloodPrimeState function returns the current state of the * blood prime state. * @details \b Inputs: bloodPrimeState @@ -499,7 +593,7 @@ * @brief * The handleBloodPrimePauseTimer function monitors the Blood Prime * pause timer. -* @details Inputs: bloodPrimeStartMS +* @details Inputs: bloodPrimeStartMS, pausedElapsedMS * @details Outputs: bloodPrimeTimeoutSec, bloodPrimeCountdownSec * @details Alarms: ALARM_ID_TD_BLOOD_PRIME_PAUSE_WARNING * ALARM_ID_TD_BLOOD_PRIME_PAUSE_TIMEOUT @@ -510,9 +604,18 @@ U32 elapsedMS; U32 elapsedSec; - if ( BLOOD_PRIME_PAUSED_STATE == bloodPrimeState ) + if ( ( BLOOD_PRIME_PAUSED_STATE == bloodPrimeState ) || ( BLOOD_PRIME_PAUSED_STATE == bolusCallingState ) ) { - elapsedMS = calcTimeSince( bloodPrimeStartMS ); + if ( BLOOD_PRIME_FLUID_BOLUS_STATE == bloodPrimeState ) + { + // Time frozen during bolus + elapsedMS = pausedElapsedMS; + } + else + { + elapsedMS = calcTimeSince( bloodPrimeStartMS ); + } + elapsedSec = elapsedMS / MS_PER_SECOND; bloodPrimeTimeoutSec = BLOOD_PRIME_PAUSE_TIMEOUT_SEC; if ( elapsedSec < BLOOD_PRIME_PAUSE_TIMEOUT_SEC ) @@ -543,6 +646,25 @@ /*********************************************************************//** * @brief + * The bloodPrimeSetPendingFluidBolusRequest function handles a fluid bolus + * request while in blood prime sub-mode. + * @details \b Inputs: none + * @details \b Outputs: fluidBolusRequested + * @return TRUE if request is accepted, FALSE if rejected. + *************************************************************************/ +BOOL signalBloodPrimeFluidBolusRequest( void ) +{ + BOOL result = FALSE; + + // Allow from all the states + fluidBolusRequested = TRUE; + result = TRUE; + + return result; +} + +/*********************************************************************//** + * @brief * The publishBloodPrimeData function publishes blood prime data * at interval. * @details \b Message \b Sent: MSG_ID_TD_BLOOD_PRIME_PROGRESS_DATA Index: firmware/App/Services/AlarmMgmtSWFaults.h =================================================================== diff -u -rb777859b2667c350c6ca9fda60a668c9eb5fe02d -r934ce8fc097623360b8db3619194348fb4fad09f --- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision b777859b2667c350c6ca9fda60a668c9eb5fe02d) +++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 934ce8fc097623360b8db3619194348fb4fad09f) @@ -7,28 +7,28 @@ * * @file AlarmMgmtSWFaults.h * -* @author (last) Raghu Kallala -* @date (last) 29-Apr-2026 +* @author (last) Vijay Pamula +* @date (last) 12-Jun-2026 * * @author (original) Sean Nash * @date (original) 01-Aug-2024 * ***************************************************************************/ - -#ifndef __ALARM_MGMT_SW_FAULTS_H__ -#define __ALARM_MGMT_SW_FAULTS_H__ - -/** - * @addtogroup AlarmManagement - * @{ - */ - -// ********** public definitions ********** - -/// Listing of specific software faults for logging purposes. -typedef enum -{ - SW_FAULT_ID_NONE = 0, + +#ifndef __ALARM_MGMT_SW_FAULTS_H__ +#define __ALARM_MGMT_SW_FAULTS_H__ + +/** + * @addtogroup AlarmManagement + * @{ + */ + +// ********** public definitions ********** + +/// Listing of specific software faults for logging purposes. +typedef enum +{ + SW_FAULT_ID_NONE = 0, SW_FAULT_ID_ALARM_LAMP_INVALID_PATTERN_REQUESTED = 1, SW_FAULT_ID_ALARM_LAMP_INVALID_SELF_TEST_STATE = 2, SW_FAULT_ID_MODE_INIT_POST_INVALID_POST_STATE = 3, @@ -61,7 +61,7 @@ SW_FAULT_ID_CAN_PARITY_ERROR = 30, SW_FAULT_ID_CAN_OFF_ERROR = 31, SW_FAULT_ID_UNEXPECTED_DMA_INTERRUPT = 32, - SW_FAULT_ID_AVAILABLE1 = 33, + SW_FAULT_ID_MODE_UPDATE_INVALID_STATE = 33, SW_FAULT_ID_MSG_PENDING_ACK_LIST_FULL = 34, SW_FAULT_ID_MSG_QUEUES_ADD_QUEUE_FULL = 35, SW_FAULT_ID_MSG_QUEUES_ADD_INVALID_QUEUE = 36, @@ -186,10 +186,21 @@ SW_FAULT_ID_TD_AIR_PUMP_DUTY_CYCLE_OUT_OF_RANGE = 155, SW_FAULT_ID_PI_CTRL_INVALID_CONTROLLER = 156, SW_FAULT_ID_INVALID_TREATMENT_MODALITY = 157, - SW_FAULT_ID_TD_VALVES_INVALID_VALVE2 = 158, + SW_FAULT_ID_INVALID_DD_DIALYSATE_DATA = 158, + SW_FAULT_ID_TD_SYRINGE_INVALID_BOLUS_CMD = 159, + SW_FAULT_ID_TD_SYRINGE_INVALID_CONT_CMD = 160, + SW_FAULT_ID_TD_SYRINGE_INVALID_STATE = 161, + SW_FAULT_ID_TD_SYRINGE_INVALID_VREF = 162, + SW_FAULT_ID_MODE_PRE_TX_INSTALL_INVALID_STATE = 163, + SW_FAULT_ID_MODE_POST_TREATMENT_INVALID_STATE = 164, + SW_FAULT_ID_MODE_POST_TREATMENT_INVALID_STATE1 = 165, + SW_FAULT_ID_MODE_POST_TX_AUTO_EJECT_INVALID_STATE = 166, + SW_FAULT_ID_INVALID_FLUID_BOLUS_STATE = 167, + SW_FAULT_ID_PRE_TX_RECIRC_INVALID_STATE = 168, + SW_FAULT_ID_TD_VALVES_INVALID_VALVE2 = 169, NUM_OF_SW_FAULT_IDS -} SW_FAULT_ID_T; - +} SW_FAULT_ID_T; + /**@}*/ -#endif +#endif