Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r222b05e39082f727dcfa2d144fa6e040501882f0 -r52787cd53986cfd0abb7e674bf096898e5070f9a --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 222b05e39082f727dcfa2d144fa6e040501882f0) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 52787cd53986cfd0abb7e674bf096898e5070f9a) @@ -7,8 +7,8 @@ * * @file ModeTreatment.c * -* @author (last) Raghu Kallala -* @date (last) 04-May-2026 +* @author (last) Vijay Pamula +* @date (last) 26-Jun-2026 * * @author (original) Sean Nash * @date (original) 21-Apr-2025 @@ -20,6 +20,7 @@ #include "Bubbles.h" #include "Buttons.h" #include "DDInterface.h" +#include "FluidBolus.h" #include "Messaging.h" #include "ModeService.h" #include "ModeTreatment.h" @@ -54,8 +55,6 @@ #define TREATMENT_SETTINGS_RANGES_PUB_INTERVAL ( ( 60 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) /// Ultrafiltration data broadcast interval (ms/task time) count. #define ULTRAFILTRATION_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) -/// Saline bolus data broadcast interval (ms/task time) count. // TODO - move to StateTxSalineBolus.c when implemented -#define SALINE_BOLUS_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) /// Macro to calculate the elapsed treatment time in seconds. #define CALC_ELAPSED_TREAT_TIME_IN_SECS() ( treatmentTimeMS / MS_PER_SECOND ) @@ -73,7 +72,7 @@ static BOOL treatmentCompleted; ///< Flag indicates whether the treatment has completed. static U32 presTreatmentTimeSecs; ///< Prescribed treatment time (in seconds). -static F32 presUFVolumeMl; ///< Prescribed ultrafiltration volume (in L). +static F32 presUFVolumeMl; ///< Prescribed ultrafiltration volume (in Ml). static F32 presUFRateMlMin; ///< Prescribed ultrafiltration rate (in mL/Min). static U32 treatmentTimeMS; ///< Elapsed treatment time (in ms). @@ -85,6 +84,7 @@ static U32 isolatedUFBroadcastTimerCtr; ///< Isolated UF data broadcast timer counter used to schedule when to transmit data. static U32 salineBolusBroadcastTimerCtr; ///< Saline bolus data broadcast timer counter used to schedule when to transmit data. + /// Interval (in task intervals) at which to publish alarm status to CAN bus. static OVERRIDE_U32_T treatmentTimePublishInterval; /// Interval (in task intervals) at which to publish alarm status to CAN bus. @@ -114,7 +114,6 @@ static void broadcastTreatmentSettingsRanges( void ); static void broadcastTreatmentPeriodicData(); -static void publishSalineBolusData( void ); // TODO - move to StateTxSalineBolus.c when implemented static void publishUltrafiltrationData( void ); static void publishIsolatedUFData( void ); static U32 getMinTreatmentTimeInMinutes( void ); @@ -123,7 +122,6 @@ static TREATMENT_STATE_T handleTreatmentDialysisState( void ); static TREATMENT_STATE_T handleTreatmentIsoUFState( void ); static TREATMENT_STATE_T handleTreatmentDialysatePausedState( void ); -static TREATMENT_STATE_T handleTreatmentSalineBolusState( void ); static TREATMENT_STATE_T handleTreatmentPausedState( void ); static TREATMENT_STATE_T handleTreatmentRinsebackState( void ); static TREATMENT_STATE_T handleTreatmentRecircState( void ); @@ -172,7 +170,6 @@ treatmentParamsRangesBroadcastTimerCtr = TREATMENT_SETTINGS_RANGES_PUB_INTERVAL; // So we send ranges immediately when we begin treatment mode ultrafiltrationBroadcastTimerCtr = ULTRAFILTRATION_DATA_PUB_INTERVAL; // So we send ultrafiltration immediately when we begin treatment mode isolatedUFBroadcastTimerCtr = ULTRAFILTRATION_DATA_PUB_INTERVAL; // So we send isolated UF immediately when we enter isolated UF - salineBolusBroadcastTimerCtr = SALINE_BOLUS_DATA_PUB_INTERVAL; // So we send saline bolus data immediately when we begin treatment mode presTreatmentTimeSecs = 0; presUFVolumeMl = 0.0F; @@ -232,6 +229,7 @@ // initRinseback(); // initTreatmentRecirc(); // initTreatmentEnd(); + initFluidBolus(); // Started the treatment - set the start time in epoch // setTxLastStartTimeEpoch( getRTCTimestamp() ); @@ -260,8 +258,8 @@ getTreatmentParameterU32( TREATMENT_PARAM_BICARBONATE ) ); // Read back limits for transmit to UI. respRecord.artPresLimitWindowmmHg = getSysConfigTreatmentParameterU32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ); - respRecord.venPresLimitWindowmmHg = getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ); - respRecord.venPresLimitAsymmetricmmHg = getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); + respRecord.venPresLimitWindowmmHg = getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_HIGH_LIMIT_WINDOW ); + respRecord.venPresLimitAsymmetricmmHg = getSysConfigTreatmentParameterU32( TREATMENT_PARAM_VEN_PRES_LOW_LIMIT_WINDOW ); respRecord.tmpPresLimitWindowmmHg = getSysConfigTreatmentParameterU32( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ); // Send response sendPressureLimitsChangeResponse( &respRecord ); @@ -707,12 +705,12 @@ publishUltrafiltrationData(); // Publish isolated UF data only while isolated UF is active publishIsolatedUFData(); - // Publish saline bolus data at set interval (whether we are delivering one or not) - publishSalineBolusData(); - // Manage air trap control execAirTrapMonitorTreatment(); + // Call fluid bolus + execFluidBolus(); + return currentTreatmentState; } @@ -827,10 +825,15 @@ U32 msSinceLast = calcTimeBetween( lastTreatmentTimeStamp, newTime ); DIALYSIS_STATE_T dialysisState = getDialysisState(); - // Update treatment time - treatmentTimeMS += msSinceLast; + // Always update timestamp to avoid time jump on bolus exit lastTreatmentTimeStamp = newTime; + // Only update treatment time when fluid bolus is not active + if ( FALSE == isFluidBolusActive() ) + { + treatmentTimeMS += msSinceLast; + } + // End treatment if treatment duration has been reached if ( CALC_ELAPSED_TREAT_TIME_IN_SECS() >= presTreatmentTimeSecs ) { @@ -1210,14 +1213,32 @@ payload.rinsebackState = 0; // getCurrentRinsebackState(); payload.txRecircState = 0; // getCurrentTreatmentRecircState(); payload.txEndState = 0; // getCurrentTreatmentEndState(); - payload.txSalBolusState = 0; // + payload.txFluidBolusState = getCurrentFluidBolusState(); payload.txHepState = 0; // broadcastData( MSG_ID_TD_TREATMENT_STATE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)(&payload), sizeof( TREATMENT_STATE_DATA_T ) ); } } /*********************************************************************//** * @brief + * The updateTreatmentBroadcastData function updates treatment broadcast + * data values used for treatment time and ultrafiltration broadcasts. + * @details \b Inputs: none. + * @details \b Outputs: presTreatmentTimeSecs, presUFVolumeMl, presUFRateMlMin. + * @param ufRateLhr ultrafiltration rate in L/hr. + * @return none. + *************************************************************************/ +void updateTreatmentBroadcastData( F32 ufRateLhr ) +{ + presTreatmentTimeSecs = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ) * SEC_PER_MIN; + + presUFVolumeMl = getTreatmentParameterF32( TREATMENT_PARAM_UF_VOLUME ); + + presUFRateMlMin = ( ufRateLhr * (F32)ML_PER_LITER ) / (F32)MIN_PER_HOUR; +} + +/*********************************************************************//** + * @brief * The broadcastTreatmentSettingsRanges function computes and broadcasts * updated treatment parameter ranges that the user may change during treatment. * It is assumed that prescription settings have already been set prior to calling @@ -1286,7 +1307,7 @@ // F32 const arterialPres = getFilteredArterialPressure(); // F32 const venousPres = getFilteredVenousPressure(); // -// if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) +// if ( ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getTreatmentState() != TREATMENT_SALINE_BOLUS_STATE ) ) // { // treatmentBloodFlowRateTotal_mL_min += getMeasuredBloodFlowRate(); // treatmentDialysateFlowRateTotal_mL_min += getMeasuredDialInFlowRate(); @@ -1397,30 +1418,6 @@ /*********************************************************************//** * @brief - * The publishSalineBolusData function publishes the saline bolus data - * at the set time interval. - * @details \b Inputs: none - * @details \b Outputs: none - * @param dialysisState next dialysis state - * @return next saline bolus state - *************************************************************************/ -static void publishSalineBolusData( void ) -{ - if ( ++salineBolusBroadcastTimerCtr >= SALINE_BOLUS_DATA_PUB_INTERVAL ) - { - SALINE_BOLUS_DATA_PAYLOAD_T data; - - data.tgtSalineVolumeMl = getTreatmentParameterU32( TREATMENT_PARAM_FLUID_BOLUS_VOLUME ); - data.cumSalineVolumeMl = 0.0F; // TODO - data.bolSalineVolumeMl = 0.0F; // TODO - - sendMessage( MSG_ID_TD_SALINE_BOLUS_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)(&data), sizeof( SALINE_BOLUS_DATA_PAYLOAD_T ) ); - salineBolusBroadcastTimerCtr = 0; - } -} - -/*********************************************************************//** - * @brief * The publishUltrafiltrationData function publishes the ultrafiltration data * at the set time interval. * @details \b Inputs: none @@ -1437,7 +1434,7 @@ presUFRateLHr = presUFVolumeL / ( (F32)getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ) / (F32)MIN_PER_HOUR ); data.setUFVolumeL = presUFVolumeL; - data.tgtUFRateLHr = presUFRateLHr; + data.tgtUFRateLHr = ( presUFRateMlMin * (F32)MIN_PER_HOUR ) / (F32)ML_PER_LITER; data.ufVolumeDeliveredL = getUltrafiltrationVolumeDrawn(); data.ufState = (U32)getDialysisState();