Index: firmware/App/Monitors/Pressures.c =================================================================== diff -u -r505bb60b1df9cedd1277e6aa81cbeb9a620e44a5 -rad7e95175b631c22d32a39df14e9d321277d4194 --- firmware/App/Monitors/Pressures.c (.../Pressures.c) (revision 505bb60b1df9cedd1277e6aa81cbeb9a620e44a5) +++ firmware/App/Monitors/Pressures.c (.../Pressures.c) (revision ad7e95175b631c22d32a39df14e9d321277d4194) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. +* Copyright (c) 2024-2026 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * -* @file Pressure.c +* @file Pressures.c * -* @author (last) Vinayakam Mani -* @date (last) 06-May-2024 +* @author (last) Varshini Nagabooshanam +* @date (last) 11-Dec-2025 * -* @author (original) Sean -* @date (original) 15-Jan-2020 +* @author (original) Sean Nash +* @date (original) 24-Sep-2024 * ***************************************************************************/ @@ -21,8 +21,8 @@ #include "DDInterface.h" #include "FpgaTD.h" #include "Messaging.h" -//#include "ModeTreatment.h" -//#include "ModeTreatmentParams.h" +#include "ModeTreatment.h" +#include "TxParams.h" //#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" @@ -43,7 +43,6 @@ #define PRESSURE_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the pressure/occlusion data is published on the CAN bus. #define PRES_LIMIT_STABILIZATION_OFF ( 0 ) ///< pressure limit stabilization period off -#define PRES_LIMIT_STABILIZATION_2_TIME_MS ( 60 * MS_PER_SECOND ) ///< Duration of pressure limit second stage stabilization period (in ms) #define PRES_LIMIT_STABILIZATION_TIME_MS ( 60 * MS_PER_SECOND ) ///< Duration of pressure limit stabilization period (in ms). #define PRES_LIMIT_SHORT_STABILIZE_TIME_MS ( 10 * MS_PER_SECOND ) ///< Duration of pressure limit short stabilization period (in ms). #define PRES_LIMIT_RESTABILIZE_TIME_MS ( 15 * SEC_PER_MIN * MS_PER_SECOND ) ///< Duration of pressure limit re-stabilize period (in ms). @@ -77,10 +76,16 @@ #define VENOUS_PRESSURE_EXEMPTION_PERIOD ( ( 2 * MS_PER_SECOND ) / \ TASK_GENERAL_INTERVAL ) ///< Venous pressure low exemption period (in task interval) after fill for all blood flow rate +#define TMP_PRESSURE_LIMIT_MAX_MMHG ( 500.0F ) ///< Maximum transmembrane pressure limit (in mmHg) +#define TMP_PRESSURE_LIMIT_MIN_MMHG ( -500.0F ) ///< Minimum transmembrane pressure limit (in mmHg) +#define TMP_PRESSURE_HIGH_ABSOLUTE_MMHG ( 500.0F ) ///< Transmembrane pressure high absolute (in mmHg) +#define TMP_ALARM_PERSISTENCE ( ( 1 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Alarm persistence period for transmembrane pressure alarms + #define MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_MS ( 1200 ) ///< To monitor low Venous pressure in the defined interval in a case where continuous air fill event happens followed by exemption period to stabilize the pressure -#define MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_WINDOW ( MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_MS / \ - TASK_GENERAL_INTERVAL ) ///< Low Venous pressure monitoring window between air fill events based on the task interval time +///< Low Venous pressure monitoring window between air fill events based on the task interval time +#define MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_WINDOW ( MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_MS / TASK_GENERAL_INTERVAL ) + #define MAX_ART_VEN_OFFSET_MMHG 15.0F ///< Maximum arterial/venous offset allowed. #define EMPTY_SALINE_BAG_THRESHOLD_MMHG -300.0F ///< Threshold below which the saline bag is considered empty (in mmHg). @@ -142,10 +147,13 @@ static PRESSURE_LIMITS_STATES_T currPresLimitsState; ///< Current pressure limits state. static S32 stableArterialPressure; ///< Arterial pressure that limit window is based on (in mmHg). static S32 stableVenousPressure; ///< Venous pressure that limit window is based on (in mmHg). +static S32 stableTmpPressure; ///< TMP pressure that limit window is based on (in mmHg). static S32 currentArterialMaxLimit; ///< Maximum arterial pressure limit (in mmHg). static S32 currentArterialMinLimit; ///< Minimum arterial pressure limit (in mmHg). static S32 currentVenousMaxLimit; ///< Maximum venous pressure limit (in mmHg). static S32 currentVenousMinLimit; ///< Minimum venous pressure limit (in mmHg). +static S32 currentTmpMaxLimit; ///< Maximum TMP pressure limit (in mmHg). +static S32 currentTmpMinLimit; ///< Minimum TMP pressure limit (in mmHg). static BOOL pressureLimitsActive; ///< Flag indicates whether arterial and venous pressure alarm limits are active. static U32 stabilizationStartTimeMs; ///< Timestamp taken when pressure limit stabilization began (ms). static F32 longFilteredArterialPressure; ///< Measured arterial pressure after long (10 s) filter (in mmHg). @@ -184,7 +192,7 @@ static BARO_MOVING_AVG_DATA_T baroMovingAvg; ///< Barometric sensor moving average. static PRESSURE_SELF_TEST_STATE_T pressurePostState; ///< Pressure self test post state. -//static HD_PRESSURE_SENSORS_CAL_RECORD_T pressureSensorsCalRecord; ///< Pressure sensors calibration record. +//static HD_PRESSURE_SENSORS_CAL_RECORD_T pressureSensorsCalRecord; ///< Pressure sensors calibration record. // ********** private function prototypes ********** @@ -193,6 +201,7 @@ static void execPressureLimits( void ); static void checkArterialPressureInRange( void ); static void checkVenousPressureInRange( void ); +static void checkTmpPressureInRange( void ); static void publishPressureData( void ); static void determineArtVenPressureLimits( void ); static void filterInlinePressureReadings( F32 artPres, F32 venPres ); @@ -217,6 +226,8 @@ initPersistentAlarm( ALARM_ID_TD_VENOUS_PRESSURE_HIGH, 0, HIGH_VEN_PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_TD_ARTERIAL_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_TD_VENOUS_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_TD_TMP_PRESSURE_LOW, 0, ( TMP_ALARM_PERSISTENCE * TASK_GENERAL_INTERVAL ) ); + initPersistentAlarm( ALARM_ID_TD_TMP_PRESSURE_HIGH, 0, ( TMP_ALARM_PERSISTENCE * TASK_GENERAL_INTERVAL ) ); setPressureLimitsToOuterBounds(); @@ -227,6 +238,7 @@ stabilizationStartTimeMs = 0; stableArterialPressure = 0; stableVenousPressure = 0; + stableTmpPressure = 0; venLowPresExemptAfterAirTrapFillTimerCtr = 0; prevVenLowPresExemptAfterAirTrapFillTimerCtr = 0; emptySalineBagCtr = 0; @@ -359,7 +371,8 @@ * limits for arterial and venous pressure to their outer boundaries. * @details \b Inputs: none * @details \b Outputs: currentArterialMaxLimit, currentArterialMinLimit, - * currentVenousMaxLimit, currentVenousMinLimit + * currentVenousMaxLimit, currentVenousMinLimit, currentTmpMaxLimit, + * currentTmpMinLimit * @return none *************************************************************************/ void setPressureLimitsToOuterBounds( void ) @@ -368,6 +381,8 @@ currentArterialMinLimit = (S32)ARTERIAL_PRESSURE_LIMIT_MIN_MMHG; currentVenousMaxLimit = (S32)VENOUS_PRESSURE_LIMIT_MAX_MMHG; currentVenousMinLimit = (S32)VENOUS_PRESSURE_LIMIT_MIN_MMHG; + currentTmpMaxLimit = (S32)TMP_PRESSURE_LIMIT_MAX_MMHG; + currentTmpMinLimit = (S32)TMP_PRESSURE_LIMIT_MIN_MMHG; } /*********************************************************************//** @@ -379,15 +394,18 @@ * resume will start a new stabilization period ending in another set of * stable pressures before windowed limits recalculated. * @details \b Inputs: pressureStabilizeTime - * @details \b Outputs: stableArterialPressure, stableVenousPressure + * @details \b Outputs: stableArterialPressure, stableVenousPressure, + * stableTmpPressure * @return none *************************************************************************/ void updatePressureLimitWindows( void ) { F32 filtArt; F32 filtVen; + F32 filtTmp; S32 curArtPres; S32 curVenPres; + S32 curTmpPres; if ( USE_SHORT_STABILIZATION_PERIOD == pressureStabilizeTime ) { @@ -400,10 +418,15 @@ filtVen = getLongFilteredVenousPressure(); } + // TMP uses the same venous filter selection as the pressure stabilization and the latest dialysate pressure. + filtTmp = filtVen - ( getDialysatePressure() * PSI_TO_MMHG ); + curArtPres = FLOAT_TO_INT_WITH_ROUND( filtArt ); curVenPres = FLOAT_TO_INT_WITH_ROUND( filtVen ); + curTmpPres = FLOAT_TO_INT_WITH_ROUND( filtTmp ); stableArterialPressure = curArtPres; stableVenousPressure = curVenPres; + stableTmpPressure = curTmpPres; // want to broadcast new limits right away so UI can update tx screen pressureDataPublicationTimerCounter = getU32OverrideValue( &pressuresDataPublishInterval ); @@ -439,8 +462,7 @@ stabilizationStartTimeMs = getMSTimerCount(); } } - else if ( ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) || - ( PRESSURE_LIMITS_STATE_STABILIZATION_2 == currPresLimitsState ) ) + else if ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) { pressureStabilizeTime = stabilizationPeriod; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; @@ -459,13 +481,13 @@ *************************************************************************/ static void determineArtVenPressureLimits( void ) { - if ( ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) || - ( PRESSURE_LIMITS_STATE_STABILIZATION_2 == currPresLimitsState ) ) + if ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) { // apply pressure windows when stable - S32 artOffset = 120; //getTreatmentParameterS32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ) / 2; - S32 venMinOffset = 100; //getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); - S32 venMaxOffset = 20; //getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ) - venMinOffset; + S32 artOffset = getTreatmentParameterS32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ) / 2; + S32 venMinOffset = getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); + S32 venMaxOffset = getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ) - venMinOffset; + S32 tmpOffset = getTreatmentParameterS32( TREATMENT_PARAM_TMP_PRES_LIMIT_WINDOW ) / 2; currentArterialMinLimit = stableArterialPressure - artOffset; currentArterialMinLimit = MAX( currentArterialMinLimit, ARTERIAL_PRESSURE_LIMIT_MIN_MMHG ); @@ -475,6 +497,8 @@ currentVenousMinLimit = MAX( currentVenousMinLimit, VENOUS_PRESSURE_LIMIT_MIN_MMHG ); currentVenousMaxLimit = stableVenousPressure + venMaxOffset; currentVenousMaxLimit = MIN( currentVenousMaxLimit, VENOUS_PRESSURE_LIMIT_MAX_MMHG ); + currentTmpMinLimit = MAX( currentTmpMinLimit, TMP_PRESSURE_LIMIT_MIN_MMHG ); + currentTmpMaxLimit = MIN( currentTmpMaxLimit, TMP_PRESSURE_LIMIT_MAX_MMHG ); } else { // apply outer limits when not stable @@ -654,38 +678,7 @@ { updatePressureLimitWindows(); stabilizationStartTimeMs = getMSTimerCount(); - currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION_2; - pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; - } - break; - - case PRESSURE_LIMITS_STATE_STABILIZATION_2: - // zero stabilize time for 15 mins once pressure limits adjust scenario - if ( STABILIZATION_PERIOD_OFF == pressureStabilizeTime ) - { - stabilizeTime = PRES_LIMIT_STABILIZATION_OFF; - } - //60 sec second stage stabilization - else - { - stabilizeTime = PRES_LIMIT_STABILIZATION_2_TIME_MS; - } - - // second stage stabilization helps to re determine the pressure due to UF control change etc., - if ( bpRunning != TRUE ) - { - currPresLimitsState = PRESSURE_LIMITS_STATE_IDLE; - } - else if ( ( currTxState != TREATMENT_DIALYSIS_STATE ) && ( currTxState != TREATMENT_PAUSED_STATE ) ) - { - currPresLimitsState = PRESSURE_LIMITS_STATE_WIDE; - } - else if ( TRUE == didTimeout( stabilizationStartTimeMs, stabilizeTime ) ) - { - updatePressureLimitWindows(); - stabilizationStartTimeMs = getMSTimerCount(); currPresLimitsState = PRESSURE_LIMITS_STATE_STABLE; - // Reset to normal period as default. pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; } break; @@ -704,7 +697,7 @@ { stabilizationStartTimeMs = getMSTimerCount(); pressureStabilizeTime = STABILIZATION_PERIOD_OFF; - currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION_2; + currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; } break; @@ -866,6 +859,50 @@ /*********************************************************************//** * @brief + * The checkTmpPressureInRange function checks that the calculated TMP + * pressure is within the set alarm limits. + * @details \b Alarm: ALARM_ID_TD_TMP_PRESSURE_LOW if TMP pressure is low. + * @details \b Alarm: ALARM_ID_TD_TMP_PRESSURE_HIGH if TMP pressure is high. + * @details \b Inputs: tmpPressure, pressureLimitsActive, currentTmpMinLimit, currentTmpMaxLimit + * @details \b Outputs: none + * @return none + *************************************************************************/ +static void checkTmpPressureInRange( void ) +{ + F32 tmpPres = getTMPPressure(); + + // TMP alarms are when pressure limits are active. + if ( pressureLimitsActive != FALSE ) + { + BOOL tmpPresLow; + BOOL tmpPresHigh; + F32 tmpHighLimit; + + // High limit is windowed around stabilized TMP, but must also respect absolute floor. + tmpHighLimit = MAX( (F32)currentTmpMaxLimit, TMP_PRESSURE_HIGH_ABSOLUTE_MMHG ); + + tmpPresLow = ( tmpPres < (F32)currentTmpMinLimit ? TRUE : FALSE ); + tmpPresHigh = ( tmpPres > tmpHighLimit ? TRUE : FALSE ); + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_TMP_PRESSURE_LOW, tmpPresLow ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_TMP_PRESSURE_LOW, tmpPres, (F32)currentTmpMinLimit ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_TMP_PRESSURE_HIGH, tmpPresHigh ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_TMP_PRESSURE_HIGH, tmpPres, tmpHighLimit ); + } + } + else + { + // Reset persistence if limits inactive + isPersistentAlarmTriggered( ALARM_ID_TD_TMP_PRESSURE_LOW, FALSE ); + isPersistentAlarmTriggered( ALARM_ID_TD_TMP_PRESSURE_HIGH, FALSE ); + } +} + +/*********************************************************************//** + * @brief * The signalLowVenousPressureCheck function sets the low venous pressure Exempt check flag to increment the counter. * @details \b Inputs: lowVenousPressureExemptCheck * @details \b Outputs: lowVenousPressureExemptCheck @@ -1059,8 +1096,8 @@ data.h2LongFilterPres = longFilteredArterialPressure; data.h14LongFilterPres = longFilteredVenousPressure; data.tmpPressure = getTMPPressure(); - data.tmpMinLimit = -400.0F; // TODO - use windowed min/max values based on user set params when implemented - data.tmpMaxLimit = 100.0F; + data.tmpMinLimit = (F32)currentTmpMinLimit; + data.tmpMaxLimit = (F32)currentTmpMaxLimit; data.h23Pressure = getBaroPressurePSI(); broadcastData( MSG_ID_TD_PRESSURE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( PRESSURE_DATA_T ) ); @@ -1116,10 +1153,10 @@ BOOL calStatus = TRUE; //FALSE; // Get the pressure sensors and occlusion sensors calibration records -// calStatus |= getNVRecord2Driver( GET_CAL_PRESSURE_SENSORS, (U08*)&pressureSensorsCalRecord, sizeof( HD_PRESSURE_SENSORS_CAL_RECORD_T ), -// NUM_OF_CAL_DATA_HD_PRESSURE_SESNSORS, ALARM_ID_NO_ALARM ); +// calStatus |= getNVRecord2Driver( GET_CAL_PRESSURE_SENSORS, (U08*)&pressureSensorsCalRecord, sizeof( TD_PRESSURE_SENSORS_CAL_RECORD_T ), +// NUM_OF_CAL_DATA_TD_PRESSURE_SESNSORS, ALARM_ID_NO_ALARM ); // -// calStatus |= getNVRecord2Driver( GET_CAL_OCCLUSION_SESNSORS, (U08*)&occlusionSensorsCalRecord, sizeof( HD_OCCLUSION_SENSORS_CAL_RECORD_T ), +// calStatus |= getNVRecord2Driver( GET_CAL_OCCLUSION_SESNSORS, (U08*)&occlusionSensorsCalRecord, sizeof( TD_OCCLUSION_SENSORS_CAL_RECORD_T ), // NUM_OF_CAL_DATA_OCCLUSION_SENSORS, ALARM_ID_NO_ALARM ); pressurePostState = PRESSURE_TEST_STATE_COMPLETE;