Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r7c3e70e76a480c56e52a181fb0d2d32f13847530 -rd0afb42f8728fd5ee05c90ec0e57e1f4eec4067b --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 7c3e70e76a480c56e52a181fb0d2d32f13847530) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision d0afb42f8728fd5ee05c90ec0e57e1f4eec4067b) @@ -150,7 +150,6 @@ static OVERRIDE_F32_T bpFlowWearBTerm; ///< Blood flow estimation term for wear offset. static OVERRIDE_F32_T bpStrokeVolumeMlPerRev; ///< Blood flow estimation term for stroke volume (mL per rotor rev). static OVERRIDE_U32_T bpMaxRotorCountForWear; ///< Maximum rotor count used for cartridge wear estimation. - //static TD_PUMPS_CAL_RECORD_T bloodPumpCalRecord; ///< Blood pump calibration record. // ********** private function prototypes ********** @@ -1438,15 +1437,15 @@ } /*********************************************************************//** - * @brief - * The testBPStrokeVolumeOverride function overrides the stroke volume - * (mL per rotor revolution) used in the blood flow estimation equation. - * @details \b Inputs: none - * @details \b Outputs: bpStrokeVolumeMlPerRev - * @param message Override message from Dialin which includes the stroke - * volume (mL per rotor revolution) to override with. - * @return TRUE if override successful, FALSE if not - *************************************************************************/ +* @brief +* The testBPStrokeVolumeOverride function overrides the stroke volume +* (mL per rotor revolution) used in the blood flow estimation equation. +* @details \b Inputs: none +* @details \b Outputs: bpStrokeVolumeMlPerRev +* @param message Override message from Dialin which includes the stroke +* volume (mL per rotor revolution) to override with. +* @return TRUE if override successful, FALSE if not +*************************************************************************/ BOOL testBPStrokeVolumeOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &bpStrokeVolumeMlPerRev ); Index: firmware/App/Modes/StateTxBloodPrime.c =================================================================== diff -u -rc01e44290174eb4098c14b17031ac538d7560b03 -rd0afb42f8728fd5ee05c90ec0e57e1f4eec4067b --- firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision c01e44290174eb4098c14b17031ac538d7560b03) +++ firmware/App/Modes/StateTxBloodPrime.c (.../StateTxBloodPrime.c) (revision d0afb42f8728fd5ee05c90ec0e57e1f4eec4067b) @@ -7,8 +7,8 @@ * * @file StateTxBloodPrime.c * -* @author (last) Varshini Nagabooshanam -* @date (last) 10-Mar-2026 +* @author (last) Raghu Kallala +* @date (last) 20-Feb-2026 * * @author (original) Varshini Nagabooshanam * @date (original) 09-Jan-2026 @@ -26,6 +26,7 @@ #include "StateTxBloodPrime.h" #include "Switches.h" #include "TaskGeneral.h" +#include "Timers.h" #include "Utilities.h" #include "Valves.h" #include "Valve3Way.h" @@ -55,6 +56,9 @@ /// Tubing portion of blood prime volume to prime the blood side circuit (in mL). #define TUBING_BLOOD_PRIME_VOLUME_ML 126 +/// Timeout duration for Blood Prime pause state. +#define BLOOD_PRIME_PAUSE_TIMEOUT_SEC ( 5 * SEC_PER_MIN ) + // ********** private data ********** static BLOOD_PRIME_STATE_T bloodPrimeState; ///< Current state of the blood prime sub-mode. @@ -71,6 +75,9 @@ 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; ///< /// 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 }; @@ -84,6 +91,7 @@ static BLOOD_PRIME_STATE_T handleBloodPrimeRampState( void ); static BLOOD_PRIME_STATE_T handleBloodPrimeRunState( void ); static BLOOD_PRIME_STATE_T handleBloodPrimePausedState( void ); +static void handleBloodPrimePauseTimer( void ); static void publishBloodPrimeData( void ); /*********************************************************************//** @@ -118,6 +126,7 @@ estRampSeconds = (F32)MIN_RAMP_TIME_SEC; } bloodPrimeRampStep_mL = rampRateSpan / estRampSeconds; + bloodPrimeStartMS = 0; } /*********************************************************************//** @@ -230,6 +239,8 @@ // Blood prime flags should be handled by now - reset in case not handled by current state resetBloodPrimeFlags(); + handleBloodPrimePauseTimer(); + // Publish blood prime progress while in blood prime sub-mode publishBloodPrimeData(); } @@ -272,6 +283,7 @@ setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); result = BLOOD_PRIME_PAUSED_STATE; + bloodPrimeStartMS = getMSTimerCount(); } // When UI changes blood flow rate else if ( TRUE == pendingFlowChangeRequest ) @@ -329,6 +341,7 @@ setValvePosition( H1_VALV, VALVE_POSITION_C_CLOSE ); setValvePosition( H19_VALV, VALVE_POSITION_C_CLOSE ); result = BLOOD_PRIME_PAUSED_STATE; + bloodPrimeStartMS = getMSTimerCount(); } // When UI changes blood flow rate else if ( TRUE == pendingFlowChangeRequest ) @@ -480,6 +493,50 @@ } /*********************************************************************//** +* @brief +* The handleTreatmentPausedBloodSittingTimer function handles the pause +* timeout and trigger warning/alarm. +* @details Inputs: bloodPrimeStartMS +* @details Outputs: bloodPrimeTimeoutSec, bloodPrimeCountdownSec +* @return none +*************************************************************************/ +static void handleBloodPrimePauseTimer( void ) +{ + U32 elapsedMS; + U32 elapsedSec; + + if ( BLOOD_PRIME_PAUSED_STATE == bloodPrimeState ) + { + elapsedMS = calcTimeSince( bloodPrimeStartMS ); + elapsedSec = elapsedMS / MS_PER_SECOND; + bloodPrimeTimeoutSec = BLOOD_PRIME_PAUSE_TIMEOUT_SEC; + if ( elapsedSec < BLOOD_PRIME_PAUSE_TIMEOUT_SEC ) + { + bloodPrimeCountdownSec = BLOOD_PRIME_PAUSE_TIMEOUT_SEC - elapsedSec; + } + else + { + bloodPrimeCountdownSec = 0; + } + // Warning when 1 minute is remaining + if ( bloodPrimeCountdownSec <= SEC_PER_MIN ) + { + activateAlarmNoData( ALARM_ID_TD_BLOOD_PRIME_PAUSE_WARNING ); + } + // Alarm when timeout reached + if ( bloodPrimeCountdownSec == 0 ) + { + activateAlarmNoData( ALARM_ID_TD_BLOOD_PRIME_PAUSE_TIMEOUT ); + } + } + else + { + bloodPrimeTimeoutSec = 0; + bloodPrimeCountdownSec = 0; + } +} + +/*********************************************************************//** * @brief * The publishBloodPrimeData function publishes blood prime data * at interval. @@ -491,15 +548,17 @@ *************************************************************************/ static void publishBloodPrimeData( void ) { - if ( ++bloodPrimePublishTimerCtr >= getU32OverrideValue( &bloodPrimePublishInterval ) ) - { - BLOOD_PRIME_DATA_PAYLOAD_T data; + if ( ++bloodPrimePublishTimerCtr >= getU32OverrideValue( &bloodPrimePublishInterval ) ) + { + BLOOD_PRIME_DATA_PAYLOAD_T data; + bloodPrimePublishTimerCtr = 0; + data.targetBloodPrimeVolumeMl = bloodPrimeTargetVolume_mL; + data.deliveredBloodPrimeVolumeMl = MAX( 0.0, getBloodPrimeVolume() ); + data.bloodPrimeTimeoutSec = bloodPrimeTimeoutSec; + data.bloodPrimeCountdownSec = bloodPrimeCountdownSec; - bloodPrimePublishTimerCtr = 0; - data.targetBloodPrimeVolumeMl = bloodPrimeTargetVolume_mL; - data.deliveredBloodPrimeVolumeMl = MAX( 0.0, getBloodPrimeVolume() ); - broadcastData( MSG_ID_TD_BLOOD_PRIME_PROGRESS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( BLOOD_PRIME_DATA_PAYLOAD_T ) ); - } + broadcastData( MSG_ID_TD_BLOOD_PRIME_PROGRESS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( BLOOD_PRIME_DATA_PAYLOAD_T ) ); + } }