Index: firmware/App/Controllers/AirTrap.c =================================================================== diff -u -r36d007b4b475ace14b370ab06366aed2196274f1 -r2fbfc45cea26e36bc8295d4c81c48bb597ca63d3 --- firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 36d007b4b475ace14b370ab06366aed2196274f1) +++ firmware/App/Controllers/AirTrap.c (.../AirTrap.c) (revision 2fbfc45cea26e36bc8295d4c81c48bb597ca63d3) @@ -38,9 +38,11 @@ #define AIR_TRAP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the air trap data is published on the CAN bus. #define AIR_TRAP_FILL_TIMEOUT_MS ( 6 * MS_PER_SECOND ) ///< Air trap fill timeout period (in ms). +#define AIR_PUMP_ON_DELAY_TIME_MS ( 10 * MS_PER_SECOND ) ///< Delay between air pump On (in ms). #define AIR_PUMP_UPPER_LEVEL_PERSISTENCE ( 300 / TASK_GENERAL_INTERVAL ) ///< Persistence time for air pump operation after air trap upper level reads air. #define AIR_PUMP_ON_ERROR_MAX_CNT 6 ///< Maximum number of air pump on events within time window before alarm triggered. Do not exceed MAX_TIME_WINDOWED_COUNT. #define AIR_PUMP_ON_ERROR_TIME_WIN_MS ( 60 * MS_PER_SECOND ) ///< Time window for Air Pump on count error. +#define AIR_TRAP_LEVEL_DEBOUNCE_TIME_MS ( 400 ) ///< Air trap level sensor debounce time /// Persistence period for illegal level sensors fault. #define AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Air trap illegal values timeout (in ms) @@ -66,11 +68,13 @@ /// Interval (in ms) at which to publish air trap data to CAN bus. static OVERRIDE_U32_T airTrapDataPublishInterval = { AIR_TRAP_DATA_PUB_INTERVAL, AIR_TRAP_DATA_PUB_INTERVAL, AIR_TRAP_DATA_PUB_INTERVAL, 0 }; static OVERRIDE_U32_T airTrapLevels[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Detected air trap level for each level sensor. +static U32 airTrapLevelsDebounceStartTime[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; ///< Debounce start time for airtrap level sensor. static BOOL pendingStartAirTrapController = FALSE; ///< Flag indicates an air trap controller start request is pending. static BOOL pendingStopAirTrapController = FALSE; ///< Flag indicates an air trap controller stop request is pending. static U32 fillStartTime = 0; ///< Time stamp for start of air trap fill. +static U32 airPumpOnDelayStartTime = 0; ///< Air pump On start time. static U32 airPumpUpperLevelCtr = 0; ///< Timer count for air pump persistence. @@ -95,13 +99,15 @@ resetAirTrap(); airTrapDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; airPumpUpperLevelCtr = 0; + airPumpOnDelayStartTime = getMSTimerCount(); for ( i = 0; i < NUM_OF_AIR_TRAP_LEVEL_SENSORS; i++ ) { airTrapLevels[i].data = 0; airTrapLevels[i].ovData = 0; airTrapLevels[i].ovInitData = 0; airTrapLevels[i].override = OVERRIDE_RESET; + airTrapLevelsDebounceStartTime[i] = 0; } initPersistentAlarm( ALARM_ID_HD_AIR_TRAP_ILLEGAL_LEVELS, AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS, AIR_TRAP_ILLEGAL_LEVELS_TIMEOUT_MS ); @@ -186,12 +192,40 @@ BOOL lower, upper; BOOL isAirTrapLevelsValid = FALSE; AIR_TRAP_LEVELS_T lowerAirTrap, upperAirTrap; + AIR_TRAP_LEVEL_SENSORS_T airTrapLevelSensor; + AIR_TRAP_LEVELS_T currentLevelStatus[ NUM_OF_AIR_TRAP_LEVEL_SENSORS ]; // Get latest level readings getFPGAAirTrapLevels( &lower, &upper ); - airTrapLevels[ AIR_TRAP_LEVEL_SENSOR_LOWER ].data = (U32)( TRUE == lower ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); - airTrapLevels[ AIR_TRAP_LEVEL_SENSOR_UPPER ].data = (U32)( TRUE == upper ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); + currentLevelStatus[ AIR_TRAP_LEVEL_SENSOR_LOWER ] = ( TRUE == lower ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); + currentLevelStatus[ AIR_TRAP_LEVEL_SENSOR_UPPER ] = ( TRUE == upper ? AIR_TRAP_LEVEL_AIR : AIR_TRAP_LEVEL_FLUID ); + // Read the level after expiry of debouncing time + for( airTrapLevelSensor = AIR_TRAP_LEVEL_SENSOR_LOWER; airTrapLevelSensor < NUM_OF_AIR_TRAP_LEVEL_SENSORS; airTrapLevelSensor++ ) + { + // Check if the current level sensor status is not the same as the recorded data + if ( currentLevelStatus[ airTrapLevelSensor ] != (AIR_TRAP_LEVELS_T)airTrapLevels[ airTrapLevelSensor ].data ) + { + // If the debounce time is 0, start the timer + if ( 0 == airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] ) + { + airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] = getMSTimerCount(); + } + // If the debounce time has been elapsed, update the level sensor status to the new status + else if ( TRUE == didTimeout( airTrapLevelsDebounceStartTime[ airTrapLevelSensor ], AIR_TRAP_LEVEL_DEBOUNCE_TIME_MS ) ) + { + // reset the debounce time + airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] = 0; + // update recent level status + airTrapLevels[ airTrapLevelSensor ].data = (U32)currentLevelStatus[ airTrapLevelSensor ]; + } + } + else + { + airTrapLevelsDebounceStartTime[ airTrapLevelSensor ] = 0; + } + } + if ( STATE_OPEN == getSwitchStatus( PUMP_TRACK_SWITCH ) ) { // If the pump track on open, zero the persistent counter to not check the air trap illegal level alarm @@ -334,7 +368,8 @@ //Turn on air pump if fluid reaches upper level. else if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) { - if ( AIR_PUMP_STATE_OFF == getAirPumpState() ) + if ( ( AIR_PUMP_STATE_OFF == getAirPumpState() ) && + ( TRUE == didTimeout( airPumpOnDelayStartTime, AIR_PUMP_ON_DELAY_TIME_MS ) ) ) { setAirPumpState( AIR_PUMP_STATE_ON ); airPumpUpperLevelCtr = 0; @@ -352,13 +387,14 @@ if ( airPumpUpperLevelCtr >= AIR_PUMP_UPPER_LEVEL_PERSISTENCE ) { setAirPumpState( AIR_PUMP_STATE_OFF ); + airPumpOnDelayStartTime = getMSTimerCount(); } } } // Transition to open valve state when air detected at lower level else if ( ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) && - ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) + ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) ) { if ( AIR_PUMP_STATE_ON == getAirPumpState() ) { Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r134d96d197007eeafb2e8e41de941742f348f9db -r2fbfc45cea26e36bc8295d4c81c48bb597ca63d3 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 134d96d197007eeafb2e8e41de941742f348f9db) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 2fbfc45cea26e36bc8295d4c81c48bb597ca63d3) @@ -40,12 +40,15 @@ // ********** private definitions ********** /// Default publication interval for pressure and occlusion data. -#define PRES_OCCL_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_OCCL_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). +// Pressure Limit minimum stabilization time before short stabilization time activation +static const U32 PRES_LIMIT_MIN_STABILIZATION_TIME_IN_MS = ( PRES_LIMIT_STABILIZATION_TIME_MS - PRES_LIMIT_SHORT_STABILIZE_TIME_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 ( 30 * SEC_PER_MIN * MS_PER_SECOND ) ///< Duration of pressure limit re-stabilize period (in ms). - #define ARTERIAL_PRESSURE_CONVERSION_OFFSET 0x800000 ///< Arterial pressure conversion coefficient. #define ARTERIAL_PRESSURE_V_BIAS ( 3.0F ) ///< Bias voltage for arterial pressure sensor. #define ARTERIAL_PRESSURE_SENSITIVITY ( 0.000005F ) ///< Sensitivity for arterial pressure sensor is 5 uV / mmHg @@ -83,8 +86,13 @@ /// Venous pressure low exemption period (in task intervals) conversion factor (from Qb in mL/min) following an air trap fill. static const U32 VENOUS_PRES_AT_FILL_DELAY_FACTOR = (U32)( VENOUS_PRES_AT_FILL_DELAY_MAX_BLOOD_VOL_ML * (F32)SEC_PER_MIN * ( (F32)MS_PER_SECOND / (F32)TASK_GENERAL_INTERVAL ) ); +#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 + #define PSI_TO_MMHG ( 51.7149F ) ///< Conversion factor for converting PSI to mmHg. +// The new arterial pressure sensor is the same as the venous pressure sensor #define VENOUS_PRESSURE_NORMAL_OP 0 ///< Venous pressure status bits indicate normal operation. #define VENOUS_PRESSURE_CMD_MODE 1 ///< Venous pressure status bits indicate sensor in command mode. #define VENOUS_PRESSURE_STALE_DATA 2 ///< Venous pressure status bits indicate data is stale (no new data since last fpga read). @@ -152,6 +160,7 @@ static PRESSURE_STATE_T presOcclState; ///< Current state of pressure monitor state machine. static U32 presOcclDataPublicationTimerCounter = 0; ///< Used to schedule pressure data publication to CAN bus. static U32 venLowPresExemptAfterAirTrapFillTimerCtr; ///< Exempt low ven pressure limit alarm for a time following an air trap fill. +static U32 prevVenLowPresExemptAfterAirTrapFillTimerCtr; ///< previous venous low pressure exempt fill time counter /// Interval (in ms) at which to publish pressure/occlusion data to CAN bus. static OVERRIDE_U32_T presOcclDataPublishInterval = { PRES_OCCL_DATA_PUB_INTERVAL, PRES_OCCL_DATA_PUB_INTERVAL, 0, 0 }; @@ -173,7 +182,9 @@ static OVERRIDE_F32_T shortFilteredArterialPressure = { 0.0, 0.0, 0.0, 0 }; ///< Measured arterial pressure after short (1 s) filter. static F32 longFilteredVenousPressure; ///< Measured venous pressure after long (10 s) filter. static OVERRIDE_F32_T shortFilteredVenousPressure = { 0.0, 0.0, 0.0, 0 }; ///< Measured venous pressure after short (1 s) filter. -static BOOL useShortStabilizeTime; ///< Flag to use short stabilize time. +static STABILIZATION_PERIODS_T pressureStabilizeTime; ///< Pressure stabilization time based on system events such as airpump, treatment param changes etc., +static BOOL resetFillExemptPeriod; ///< Flag to reset the exempt period after defined time expire. +static BOOL lowVenousPressureExemptCheck; ///< low venous pressure exempt check flag based on the air trap valve status static U32 bloodPumpOcclusionAfterCartridgeInstall; ///< Measured blood pump occlusion reading taken after cartridge install. @@ -246,22 +257,25 @@ setPressureLimitsToOuterBounds(); - currPresLimitsState = PRESSURE_LIMITS_STATE_OFF; - pressureLimitsActive = FALSE; - stabilizationStartTimeMs = 0; - stableArterialPressure = 0; - stableVenousPressure = 0; - venLowPresExemptAfterAirTrapFillTimerCtr = 0; + currPresLimitsState = PRESSURE_LIMITS_STATE_OFF; + pressureLimitsActive = FALSE; + stabilizationStartTimeMs = 0; + stableArterialPressure = 0; + stableVenousPressure = 0; + venLowPresExemptAfterAirTrapFillTimerCtr = 0; + prevVenLowPresExemptAfterAirTrapFillTimerCtr = 0; resetArtVenPressureOffsets(); - longFilteredArterialPressure = 0.0F; - shortFilteredArterialPressure.data = 0.0F; - longFilteredVenousPressure = 0.0F; - shortFilteredVenousPressure.data = 0.0F; - presOcclDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - presOcclState = PRESSURE_WAIT_FOR_POST_STATE; - presOcclPostState = PRESSURE_SELF_TEST_STATE_START; - bloodPumpOcclusionAfterCartridgeInstall = 0; - useShortStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; + longFilteredArterialPressure = 0.0F; + shortFilteredArterialPressure.data = 0.0F; + longFilteredVenousPressure = 0.0F; + shortFilteredVenousPressure.data = 0.0F; + presOcclDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + presOcclState = PRESSURE_WAIT_FOR_POST_STATE; + presOcclPostState = PRESSURE_SELF_TEST_STATE_START; + bloodPumpOcclusionAfterCartridgeInstall = 0; + pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; + resetFillExemptPeriod = TRUE; + lowVenousPressureExemptCheck = TRUE; } /*********************************************************************//** @@ -406,7 +420,7 @@ * will be in effect immediately (next monitor pass). If treatment paused, * resume will start a new stabilization period ending in another set of * stable pressures before windowed limits recalculated. - * @details Inputs: useShortStabilizeTime + * @details Inputs: pressureStabilizeTime * @details Outputs: stableArterialPressure, stableVenousPressure * @return none *************************************************************************/ @@ -417,7 +431,7 @@ S32 curArtPres; S32 curVenPres; - if ( USE_SHORT_STABILIZATION_PERIOD == useShortStabilizeTime ) + if ( USE_SHORT_STABILIZATION_PERIOD == pressureStabilizeTime ) { filtArt = getFilteredArterialPressure(); filtVen = getFilteredVenousPressure(); @@ -444,22 +458,33 @@ * was stable, a rate change will kick us back to stabilization state. * Else reset stabilize counter. * @details Inputs: currPresLimitsState - * @details Outputs: currPresLimitsState, stabilizationStartTimeMs, useShortStabilizeTime - * @param useShort Flag to use short stabilization period. Use defines: - * USE_NORMAL_STABILIZATION_PERIOD, USE_SHORT_STABILIZATION_PERIOD + * @details Outputs: currPresLimitsState, stabilizationStartTimeMs, pressureStabilizeTime + * @param stabilizationPeriod stabilization periods. Use defines: + * STABILIZATION_PERIOD_OFF, USE_NORMAL_STABILIZATION_PERIOD, USE_SHORT_STABILIZATION_PERIOD * @return none *************************************************************************/ -void signalInitiatePressureStabilization( BOOL useShort ) +void signalInitiatePressureStabilization( STABILIZATION_PERIODS_T stabilizationPeriod ) { - useShortStabilizeTime = useShort; - // User update of blood/dialysate flow rate or UF rate or initiates/resets a stabilization period (if we were in stabilization or stable state) if ( PRESSURE_LIMITS_STATE_STABILIZATION == currPresLimitsState ) { - stabilizationStartTimeMs = getMSTimerCount(); + U32 currentTime = getMSTimerCount(); + U32 expiredTime = u32DiffWithWrap( stabilizationStartTimeMs, currentTime ); + + // if pressure is already stabilized enough, assign the short stabilize time for the recent event ( air pump on). + // else,allow the ongoing stabilization to complete. + // allow Normal stabilization on a case when user updates flow rate or UF rate etc., + if ( ( expiredTime > PRES_LIMIT_MIN_STABILIZATION_TIME_IN_MS ) || + ( stabilizationPeriod == USE_NORMAL_STABILIZATION_PERIOD ) ) + { + pressureStabilizeTime = stabilizationPeriod; + stabilizationStartTimeMs = getMSTimerCount(); + } } - else if ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) + else if ( ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) || + ( PRESSURE_LIMITS_STATE_STABILIZATION_2 == currPresLimitsState ) ) { + pressureStabilizeTime = stabilizationPeriod; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; stabilizationStartTimeMs = getMSTimerCount(); } @@ -476,8 +501,10 @@ *************************************************************************/ static void determineArtVenPressureLimits( void ) { - if ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) - { // apply pressure windows when stable + if ( ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) || + ( PRESSURE_LIMITS_STATE_STABILIZATION_2 == currPresLimitsState ) ) + { + // apply pressure windows when stable S32 artOffset = getTreatmentParameterS32( TREATMENT_PARAM_ART_PRES_LIMIT_WINDOW ) / 2; // Arterial is symmetric S32 venMinOffset = getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_ASYMMETRIC ); // Venous is asymmetric S32 venMaxOffset = getTreatmentParameterS32( TREATMENT_PARAM_VEN_PRES_LIMIT_WINDOW ) - venMinOffset; @@ -627,7 +654,7 @@ else if ( ( TREATMENT_DIALYSIS_STATE == currTxState ) || ( TREATMENT_STOP_STATE == currTxState ) ) { stabilizationStartTimeMs = getMSTimerCount(); - useShortStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; + pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; } else if ( currTxState == TREATMENT_RECIRC_STATE ) @@ -637,10 +664,16 @@ break; case PRESSURE_LIMITS_STATE_STABILIZATION: - if ( USE_SHORT_STABILIZATION_PERIOD == useShortStabilizeTime ) + // update stabilization time + if ( USE_SHORT_STABILIZATION_PERIOD == pressureStabilizeTime ) { stabilizeTime = PRES_LIMIT_SHORT_STABILIZE_TIME_MS; } + else if ( STABILIZATION_PERIOD_OFF == pressureStabilizeTime ) + { + stabilizeTime = PRES_LIMIT_STABILIZATION_OFF; + } + // Normal stabilization period else { stabilizeTime = PRES_LIMIT_STABILIZATION_TIME_MS; @@ -658,12 +691,39 @@ { updatePressureLimitWindows(); stabilizationStartTimeMs = getMSTimerCount(); - useShortStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; + // second stage stabilization is not required when returning from stable state on every 15 minutes once. + if ( pressureStabilizeTime == STABILIZATION_PERIOD_OFF ) + { + currPresLimitsState = PRESSURE_LIMITS_STATE_STABLE; + } + else + { + currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION_2; + } + pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; + } + break; + + case PRESSURE_LIMITS_STATE_STABILIZATION_2: + // 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_STOP_STATE ) ) + { + currPresLimitsState = PRESSURE_LIMITS_STATE_WIDE; + } + else if ( TRUE == didTimeout( stabilizationStartTimeMs, PRES_LIMIT_STABILIZATION_2_TIME_MS ) ) + { + updatePressureLimitWindows(); + stabilizationStartTimeMs = getMSTimerCount(); currPresLimitsState = PRESSURE_LIMITS_STATE_STABLE; } break; case PRESSURE_LIMITS_STATE_STABLE: + // Pressure is re determined after every 15 minutes once and be remain in limited pressure windows. if ( bpRunning != TRUE ) { currPresLimitsState = PRESSURE_LIMITS_STATE_IDLE; @@ -675,7 +735,7 @@ else if ( TRUE == didTimeout( stabilizationStartTimeMs, PRES_LIMIT_RESTABILIZE_TIME_MS ) ) { stabilizationStartTimeMs = getMSTimerCount(); - useShortStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; + pressureStabilizeTime = STABILIZATION_PERIOD_OFF; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; } break; @@ -810,9 +870,9 @@ * @brief * The checkVenousPressureInRange function checks that venous pressure is * within the set alarm limits. Alarm is triggered if not. - * @details Inputs: venousPressure, pressureLimitsActive, currentVenousMinLimit - * currentVenousMaxLimit, venLowPresExemptAfterAirTrapFillTimerCtr - * @details Outputs: venLowPresExemptAfterAirTrapFillTimerCtr, alarm if out of range + * @details Inputs: venousPressure, pressureLimitsActive, currentVenousMinLimit, resetFillExemptPeriod + * currentVenousMaxLimit, venLowPresExemptAfterAirTrapFillTimerCtr, prevVenLowPresExemptAfterAirTrapFillTimerCtr + * @details Outputs: venLowPresExemptAfterAirTrapFillTimerCtr,alarm if out of range * @return none *************************************************************************/ static void checkVenousPressureInRange( void ) @@ -821,13 +881,19 @@ OPN_CLS_STATE_T airTrapValveState = getValveAirTrapStatus(); // track time since last air trap fill - if ( STATE_OPEN == airTrapValveState ) + if ( ( STATE_OPEN == airTrapValveState ) && ( TRUE == resetFillExemptPeriod ) ) { venLowPresExemptAfterAirTrapFillTimerCtr = 0; + resetFillExemptPeriod = FALSE; + lowVenousPressureExemptCheck = FALSE; } else { - venLowPresExemptAfterAirTrapFillTimerCtr++; + // Increment counter on airtrap valve close state. Also, when next fill happens within exempt period, counter will be keep incremented irrespective of valve state. + if ( TRUE == lowVenousPressureExemptCheck ) + { + venLowPresExemptAfterAirTrapFillTimerCtr++; + } } #ifndef _RELEASE_ @@ -848,26 +914,40 @@ U32 qBx = ( 0 == qB ? MIN_SET_BLOOD_FLOW_RATE : (U32)qB ); // compute exemption period (in general task intervals) for low venous pressure alarms after air trap fills U32 exemptPeriod = VENOUS_PRES_AT_FILL_DELAY_FACTOR / qBx; + // minimumMonitoring Window helps to check and raise low venous pressure alarm on a case where repeated fill events occurrence. + // During this interval, if another airtrap fill occurs, there is no exemptions provided to stabilize the pressure and low venous pressure being raised when it goes below threshold value. + U32 minimumMonitoringWindow = exemptPeriod + MIN_TIME_BETWEEN_AIR_TRAP_FILL_EXEMPTIONS_WINDOW ; venPresLow = ( venPres < (F32)currentVenousMinLimit ? TRUE : FALSE ); venPresHigh = ( venPres > (F32)currentVenousMaxLimit ? TRUE : FALSE ); // Check venous pressure is within alarm limits - if ( ( airTrapValveState != STATE_OPEN ) && ( venLowPresExemptAfterAirTrapFillTimerCtr > exemptPeriod ) ) + // Low venous pressure is checked after exemption period and before end of reset period(minimum monitoring window) or until next air trap fill occurs + if ( ( venLowPresExemptAfterAirTrapFillTimerCtr > exemptPeriod ) && + ( ( venLowPresExemptAfterAirTrapFillTimerCtr <= minimumMonitoringWindow ) || + ( venLowPresExemptAfterAirTrapFillTimerCtr > prevVenLowPresExemptAfterAirTrapFillTimerCtr ) ) ) { if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_LOW, venPresLow ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_LOW, venPres, (F32)currentVenousMinLimit ); } } - else - { // clear persistence if air trap valve is open + // during reset period, if airTrapValve open, still alarm needs to be raised , hence persistence clearance should happen before or after reset period. + if ( ( airTrapValveState == STATE_OPEN ) && + ( ( venLowPresExemptAfterAirTrapFillTimerCtr < exemptPeriod ) || + ( venLowPresExemptAfterAirTrapFillTimerCtr > minimumMonitoringWindow ) ) ) + { isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_LOW, FALSE ); } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_HIGH, venPresHigh ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_HIGH, venPres, (F32)currentVenousMaxLimit ); } + + // Reset exempt flag only after exempt period for the last fill and after reset period (minimum monitoring window) + resetFillExemptPeriod = ( venLowPresExemptAfterAirTrapFillTimerCtr > minimumMonitoringWindow ? TRUE : FALSE ); + prevVenLowPresExemptAfterAirTrapFillTimerCtr = venLowPresExemptAfterAirTrapFillTimerCtr ; } else { // Reset persistence if limits inactive @@ -928,7 +1008,6 @@ } } } - // Check for occlusion in Treatment modes where pumps are moving else if ( MODE_TREA == hdMode ) { @@ -979,6 +1058,19 @@ /*********************************************************************//** * @brief + * The signalLowVenousPressureCheck function sets the low venous pressure Exempt check flag to increment the counter. + * @details Inputs: lowVenousPressureExemptCheck + * @details Outputs: lowVenousPressureExemptCheck + * @return none. + *************************************************************************/ +void signalLowVenousPressureCheck( void ) +{ + // When flag set, low venous pressure exempt counter increments. + lowVenousPressureExemptCheck = TRUE; +} + +/*********************************************************************//** + * @brief * The getMeasuredArterialPressure function gets the current arterial pressure. * @details Inputs: arterialPressure * @details Outputs: none