/************************************************************************** * * Copyright (c) 2020-2024 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 * * @author (last) Vinayakam Mani * @date (last) 06-May-2024 * * @author (original) Sean * @date (original) 15-Jan-2020 * ***************************************************************************/ #include "AirPump.h" #include "AlarmMgmtTD.h" //#include "BloodFlow.h" #include "DDInterface.h" #include "FpgaTD.h" #include "Messaging.h" //#include "ModeTreatment.h" //#include "ModeTreatmentParams.h" //#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "Pressures.h" //#include "SelfTests.h" #include "TaskGeneral.h" //#include "Temperatures.h" #include "Timers.h" #include "Utilities.h" //#include "Valves.h" /** * @addtogroup Pressures * @{ */ // ********** private definitions ********** #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). /// 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 VENOUS_PRESSURE_MIN_PSI ( -30.0F ) ///< Minimum of scale for venous pressure sensor reading (in PSI). #define VENOUS_PRESSURE_MAX_PSI ( 30.0F ) ///< Maximum of scale for venous pressure sensor reading (in PSI). #define MIN_VENOUS_PRESSURE_FOR_RAMP_MMHG ( 0.0F ) ///< Minimum venous pressure during blood pump ramp up (in mmHg). #define VENOUS_OFFSET_WITH_AIRPUMP_MMHG ( 150.0F ) ///< Value to increase venous pressure high limit alarm when air pump is operating. #define ARTERIAL_PRESSURE_MIN_PSI ( -30.0F ) ///< Minimum of scale for arterial pressure sensor reading (in PSI). #define ARTERIAL_PRESSURE_MAX_PSI ( 30.0F ) ///< Maximum of scale for arterial pressure sensor reading (in PSI). #define ARTERIAL_PRESSURE_SELF_TEST_MIN ( -100.0F ) ///< Minimum self-test value for arterial pressure sensor reading (in mmHg). #define ARTERIAL_PRESSURE_SELF_TEST_MAX ( 100.0F ) ///< Maximum self-test value for arterial pressure sensor reading (in mmHg). #define ARTERIAL_PRESSURE_MAX_MMHG ( 2000.0F ) ///< Maximum arterial pressure reading (in mmHg) for range check. #define ARTERIAL_PRESSURE_MIN_MMHG ( -1500.0F ) ///< Minimum arterial pressure reading (in mmHg) for range check. #define ARTERIAL_PRESSURE_LIMIT_MAX_MMHG ( 100.0F ) ///< Maximum arterial pressure limit (in mmHg). #define ARTERIAL_PRESSURE_LIMIT_MIN_MMHG ( -300.0F ) ///< Minimum arterial pressure limit (in mmHg). #define VENOUS_PRESSURE_SELF_TEST_MIN ( -100.0F ) ///< Minimum self-test value for venous pressure sensor reading (in mmHg). #define VENOUS_PRESSURE_SELF_TEST_MAX ( 100.0F ) ///< Maximum self-test value for venous pressure sensor reading (in mmHg). #define VENOUS_PRESSURE_MAX_MMHG ( 2000.0F ) ///< Maximum venous pressure reading (in mmHg) for range check. #define VENOUS_PRESSURE_MIN_MMHG ( -1500.0F ) ///< Minimum venous pressure reading (in mmHg) for range check. #define VENOUS_PRESSURE_LIMIT_MAX_MMHG ( 400.0F ) ///< Maximum venous pressure limit (in mmHg). #define VENOUS_PRESSURE_LIMIT_MIN_MMHG ( 20.0F ) ///< Minimum venous pressure limit (in mmHg). #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 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 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). static const U32 EMPTY_SALINE_BAG_PERSISTENCE = ( 250 / TASK_GENERAL_INTERVAL ); ///< Time that saline bag looks empty before saying it is empty. #define PRES_ALARM_PERSISTENCE ( 1 * MS_PER_SECOND ) ///< Alarm persistence period for pressure alarms. #define HIGH_VEN_PRES_ALARM_PERSISTENCE 500 ///< Alarm persistence period for high venous pressure alarm #define PRES_OCCL_ALARM_PERSISTENCE ( 3 * MS_PER_SECOND ) ///< Alarm persistence period for occlusion alarms #define VEN_OCCL_ALARM_PERSISTENCE 100 ///< Alarm persistence period for venous occlusion alarm. #define AIR_PUMP_TOLERANCE_TIMEOUT_MS (1 * MS_PER_SECOND ) ///< Time to allow increased maximum venous high limit /// Measured arterial pressure is filtered w/ 10 second moving average for pressure compensation of flow. #define SIZE_OF_LONG_ART_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 10 ) /// Measured arterial pressure is filtered w/ 1 second moving average for inline pressure. #define SIZE_OF_SHORT_ART_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 1 ) /// Measured arterial pressure is filtered w/ 10 second moving average for pressure compensation of flow. #define SIZE_OF_LONG_VEN_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 10 ) /// Measured venous pressure is filtered w/ 1 second moving average for inline pressure and unfiltered for occlusion detection. #define SIZE_OF_SHORT_VEN_ROLLING_AVG ( ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) * 1 ) #define DATA_PUBLISH_COUNTER_START_COUNT 5 ///< Data publish counter start count. /// Defined states for the pressure monitor state machine. typedef enum Pressure_States { PRESSURE_WAIT_FOR_POST_STATE = 0, ///< Wait for POST state. PRESSURE_CONTINUOUS_READ_STATE, ///< Continuous read sensors state. NUM_OF_PRESSURE_STATES ///< Number of pressure monitor states. } PRESSURE_STATE_T; /// Defined states for the pressure self-test state machine. typedef enum Pressure_Self_Test_States { PRESSURE_SELF_TEST_STATE_START = 0, ///< Self test start state. PRESSURE_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. PRESSURE_TEST_STATE_COMPLETE, ///< Self test completed state. NUM_OF_PRESSURE_SELF_TEST_STATES ///< Number of pressure/occlusion self-test states. } PRESSURE_SELF_TEST_STATE_T; // ********** private data ********** static PRESSURE_STATE_T pressureState; ///< Current state of pressure monitor state machine. static U32 pressureDataPublicationTimerCounter; ///< 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 static OVERRIDE_U32_T pressuresDataPublishInterval; ///< Interval (in ms) at which to publish pressure/occlusion data to CAN bus. 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 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 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). static OVERRIDE_F32_T shortFilteredArterialPressure; ///< Measured arterial pressure after short (1 s) filter (in mmHg). static F32 longFilteredVenousPressure; ///< Measured venous pressure after long (10 s) filter (in mmHg). static OVERRIDE_F32_T shortFilteredVenousPressure; ///< Measured venous pressure after short (1 s) filter (in mmHg). static OVERRIDE_F32_T tmpPressure; ///< Calculated trans-membrane pressure (in mmHg). 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 F32 arterialPressureOffset; ///< Arterial pressure sensor offset (in mmHg). static F32 venousPressureOffset; ///< Venous pressure sensor offset (in mmHg). static U32 emptySalineBagCtr; ///< Timer counter for empty bag detection. static F32 artPressureReadingsLong[ SIZE_OF_LONG_ART_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. static U32 artPressureReadingsLongIdx; ///< Index for next sample in rolling average array. static F32 artPressureReadingsLongTotal; ///< Rolling total - used to calc average. static U32 artPressureReadingsLongCount; ///< Number of samples in flow rolling average buffer. static F32 artPressureReadingsShort[ SIZE_OF_SHORT_ART_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. static U32 artPressureReadingsShortIdx; ///< Index for next sample in rolling average array. static F32 artPressureReadingsShortTotal; ///< Rolling total - used to calc average. static U32 artPressureReadingsShortCount; ///< Number of samples in flow rolling average buffer. static F32 venPressureReadingsLong[ SIZE_OF_LONG_VEN_ROLLING_AVG ]; ///< Holds flow samples for long venous pressure rolling average. static U32 venPressureReadingsLongIdx; ///< Index for next sample in rolling average array. static F32 venPressureReadingsLongTotal; ///< Rolling total - used to calc average. static U32 venPressureReadingsLongCount; ///< Number of samples in flow rolling average buffer. static F32 venPressureReadingsShort[ SIZE_OF_SHORT_VEN_ROLLING_AVG ]; ///< Holds flow samples for long arterial pressure rolling average. static U32 venPressureReadingsShortIdx; ///< Index for next sample in rolling average array. static F32 venPressureReadingsShortTotal; ///< Rolling total - used to calc average. static U32 venPressureReadingsShortCount; ///< Number of samples in flow rolling average buffer. static PRESSURE_SELF_TEST_STATE_T pressurePostState; ///< Pressure self test post state. //static HD_PRESSURE_SENSORS_CAL_RECORD_T pressureSensorsCalRecord; ///< Pressure sensors calibration record. // ********** private function prototypes ********** static PRESSURE_STATE_T handlePressureWaitForPOSTState( void ); static PRESSURE_STATE_T handlePressureContReadState( void ); static void execPressureLimits( void ); static void checkArterialPressureInRange( void ); static void checkVenousPressureInRange( void ); static void publishPressureData( void ); static void determineArtVenPressureLimits( void ); static void filterInlinePressureReadings( F32 artPres, F32 venPres ); /*********************************************************************//** * @brief * The initPressure function initializes the Pressure unit. * @details \b Inputs: none * @details \b Outputs: Pressure unit initialized. * @return none *************************************************************************/ void initPressure( void ) { // Initialize pressure sensors driver initPressureSensor(); // Initialize persistent pressure alarms initPersistentAlarm( ALARM_ID_TD_ARTERIAL_PRESSURE_LOW, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_TD_ARTERIAL_PRESSURE_HIGH, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_TD_VENOUS_PRESSURE_LOW, 0, PRES_ALARM_PERSISTENCE ); 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 ); setPressureLimitsToOuterBounds(); resetArtVenPressureOffsets(); currPresLimitsState = PRESSURE_LIMITS_STATE_OFF; pressureLimitsActive = FALSE; stabilizationStartTimeMs = 0; stableArterialPressure = 0; stableVenousPressure = 0; venLowPresExemptAfterAirTrapFillTimerCtr = 0; prevVenLowPresExemptAfterAirTrapFillTimerCtr = 0; emptySalineBagCtr = 0; longFilteredArterialPressure = 0.0F; shortFilteredArterialPressure.data = 0.0F; shortFilteredArterialPressure.ovData = 0.0F; shortFilteredArterialPressure.ovInitData = 0.0F; shortFilteredArterialPressure.override = OVERRIDE_RESET; longFilteredVenousPressure = 0.0F; shortFilteredVenousPressure.data = 0.0F; shortFilteredVenousPressure.ovData = 0.0F; shortFilteredVenousPressure.ovInitData = 0.0F; shortFilteredVenousPressure.override = OVERRIDE_RESET; tmpPressure.data = 0.0F; tmpPressure.ovData = 0.0F; tmpPressure.ovInitData = 0.0F; tmpPressure.override = OVERRIDE_RESET; pressureDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; pressureState = PRESSURE_WAIT_FOR_POST_STATE; pressurePostState = PRESSURE_SELF_TEST_STATE_START; pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; resetFillExemptPeriod = TRUE; lowVenousPressureExemptCheck = TRUE; pressuresDataPublishInterval.data = PRESSURE_DATA_PUB_INTERVAL; pressuresDataPublishInterval.ovData = PRESSURE_DATA_PUB_INTERVAL; pressuresDataPublishInterval.ovInitData = PRESSURE_DATA_PUB_INTERVAL; pressuresDataPublishInterval.override = OVERRIDE_RESET; artPressureReadingsLongIdx = 0; artPressureReadingsLongTotal = 0.0F; artPressureReadingsLongCount = 0; artPressureReadingsShortIdx = 0; artPressureReadingsShortTotal = 0.0F; artPressureReadingsShortCount = 0; venPressureReadingsLongIdx = 0; venPressureReadingsLongTotal = 0.0F; venPressureReadingsLongCount = 0; venPressureReadingsShortIdx = 0; venPressureReadingsShortTotal = 0.0F; venPressureReadingsShortCount = 0; } /*********************************************************************//** * @brief * The resetArtVenPressureOffsets function resets the arterial and venous * offsets to zero. * @details \b Inputs: none * @details \b Outputs: arterialPressureOffset, venousPressureOffset * @return none *************************************************************************/ void resetArtVenPressureOffsets( void ) { arterialPressureOffset = 0.0F; venousPressureOffset = 0.0F; } /*********************************************************************//** * @brief * The setArtVenPressureOffsets function sets the arterial and venous * offsets to current readings. * @note It is assumed that the caller will have reset the offsets prior * to calling this function. * @note The 1 second filtered readings are used so the caller should allow * at least 2 seconds for pressure to settle (after changing a pump speed * or valve position) and the filter to fill before calling this function. * @details \b Alarm: ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE if * offsets exceed maximums. * @details \b Inputs: none * @details \b Outputs: arterialPressureOffset, venousPressureOffset * @return none *************************************************************************/ void setArtVenPressureOffsets( void ) { // load latest readings into offsets arterialPressureOffset = getFilteredArterialPressure(); venousPressureOffset = getFilteredVenousPressure(); if ( ( fabs( arterialPressureOffset ) > MAX_ART_VEN_OFFSET_MMHG ) || ( fabs( venousPressureOffset ) > MAX_ART_VEN_OFFSET_MMHG ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_PRE_TREATMENT_DRY_PRESSURE_TEST_FAILURE, arterialPressureOffset, venousPressureOffset ); } } /*********************************************************************//** * @brief * The isSalineBagEmpty function determines whether the saline bag is empty. * It is assumed that this function will only be called from mode handling * (General Task) when pumping (BP) from the saline bag. * Determination is based on pressure going below a negative threshold. * @details \b Inputs: arterial line pressure * @details \b Outputs: none * @return TRUE if empty saline bag detected, FALSE if not. *************************************************************************/ BOOL isSalineBagEmpty( void ) { BOOL result = FALSE; if ( getFilteredArterialPressure() < EMPTY_SALINE_BAG_THRESHOLD_MMHG ) { if ( ++emptySalineBagCtr >= EMPTY_SALINE_BAG_PERSISTENCE ) { result = TRUE; } } else { emptySalineBagCtr = 0; } return result; } /*********************************************************************//** * @brief * The setPressureLimitsToOuterBounds function sets the min/max pressure * limits for arterial and venous pressure to their outer boundaries. * @details \b Inputs: none * @details \b Outputs: currentArterialMaxLimit, currentArterialMinLimit, * currentVenousMaxLimit, currentVenousMinLimit * @return none *************************************************************************/ void setPressureLimitsToOuterBounds( void ) { currentArterialMaxLimit = (S32)ARTERIAL_PRESSURE_LIMIT_MAX_MMHG; currentArterialMinLimit = (S32)ARTERIAL_PRESSURE_LIMIT_MIN_MMHG; currentVenousMaxLimit = (S32)VENOUS_PRESSURE_LIMIT_MAX_MMHG; currentVenousMinLimit = (S32)VENOUS_PRESSURE_LIMIT_MIN_MMHG; } /*********************************************************************//** * @brief * The updatePressureLimitWindows function updates the pressure limit * stable pressure levels when windows set/changed by user. * If treatment in progress, windowed limits around new stable pressures * 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 \b Inputs: pressureStabilizeTime * @details \b Outputs: stableArterialPressure, stableVenousPressure * @return none *************************************************************************/ void updatePressureLimitWindows( void ) { F32 filtArt; F32 filtVen; S32 curArtPres; S32 curVenPres; if ( USE_SHORT_STABILIZATION_PERIOD == pressureStabilizeTime ) { filtArt = getFilteredArterialPressure(); filtVen = getFilteredVenousPressure(); } else { filtArt = getLongFilteredArterialPressure(); filtVen = getLongFilteredVenousPressure(); } curArtPres = FLOAT_TO_INT_WITH_ROUND( filtArt ); curVenPres = FLOAT_TO_INT_WITH_ROUND( filtVen ); stableArterialPressure = curArtPres; stableVenousPressure = curVenPres; // want to broadcast new limits right away so UI can update tx screen pressureDataPublicationTimerCounter = getU32OverrideValue( &pressuresDataPublishInterval ); } /*********************************************************************//** * @brief * The signalInitiatePressureStabilization function signals that user has * changed the blood and/or dialysate flow rate. If pressure limits state * was stable, a rate change will kick us back to stabilization state. * Else reset stabilize counter. * @details \b Inputs: currPresLimitsState * @details \b 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( STABILIZATION_PERIODS_T stabilizationPeriod ) { // 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 ) { 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 ) || ( PRESSURE_LIMITS_STATE_STABILIZATION_2 == currPresLimitsState ) ) { pressureStabilizeTime = stabilizationPeriod; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; stabilizationStartTimeMs = getMSTimerCount(); } } /*********************************************************************//** * @brief * The determineArtVenPressureLimits function determines current pressure * limits based on whether we are in stabilization or stable situation. * @details \b Inputs: currPresLimitsState * @details \b Outputs: currentArterialMaxLimit, currentArterialMinLimit, * currentVenousMaxLimit, currentVenousMinLimit * @return none *************************************************************************/ static void determineArtVenPressureLimits( void ) { if ( ( PRESSURE_LIMITS_STATE_STABLE == currPresLimitsState ) || ( PRESSURE_LIMITS_STATE_STABILIZATION_2 == 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; currentArterialMinLimit = stableArterialPressure - artOffset; currentArterialMinLimit = MAX( currentArterialMinLimit, ARTERIAL_PRESSURE_LIMIT_MIN_MMHG ); currentArterialMaxLimit = stableArterialPressure + artOffset; currentArterialMaxLimit = MIN( currentArterialMaxLimit, ARTERIAL_PRESSURE_LIMIT_MAX_MMHG ); currentVenousMinLimit = stableVenousPressure - venMinOffset; currentVenousMinLimit = MAX( currentVenousMinLimit, VENOUS_PRESSURE_LIMIT_MIN_MMHG ); currentVenousMaxLimit = stableVenousPressure + venMaxOffset; currentVenousMaxLimit = MIN( currentVenousMaxLimit, VENOUS_PRESSURE_LIMIT_MAX_MMHG ); } else { // apply outer limits when not stable setPressureLimitsToOuterBounds(); } // set flag indicating whether pressure limits are active based on current current limits state pressureLimitsActive = ( currPresLimitsState > PRESSURE_LIMITS_STATE_IDLE ? TRUE : FALSE ); } /*********************************************************************//** * @brief * The execPressure function executes the pressure monitor state machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if pressure state is invalid. * @details \b Inputs: pressureState * @details \b Outputs: pressureState * @return none *************************************************************************/ void execPressure( void ) { // Update pressure readings readPressureSensors(); // State machine switch ( pressureState ) { case PRESSURE_WAIT_FOR_POST_STATE: pressureState = handlePressureWaitForPOSTState(); break; case PRESSURE_CONTINUOUS_READ_STATE: pressureState = handlePressureContReadState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_PRES_OCCL_INVALID_STATE, pressureState ) break; } // Publish pressure/occlusion data on interval publishPressureData(); } /*********************************************************************//** * @brief * The handlePressureWaitForPOSTState function handles the wait for POST * state. * @details \b Inputs: pressurePostState * @details \b Outputs: none * @return next state *************************************************************************/ static PRESSURE_STATE_T handlePressureWaitForPOSTState( void ) { PRESSURE_STATE_T result = PRESSURE_WAIT_FOR_POST_STATE; // if ( PRESSURE_TEST_STATE_COMPLETE == pressurePostState ) // TODO - restore later { result = PRESSURE_CONTINUOUS_READ_STATE; } return result; } /*********************************************************************//** * @brief * The handlePressureContReadState function handles the continuous read state * of the pressure monitor state machine. * @details \b Inputs: FPGA pressure readings * @details \b Outputs: pressure sensor values updated * @return next state *************************************************************************/ static PRESSURE_STATE_T handlePressureContReadState( void ) { PRESSURE_STATE_T result = PRESSURE_CONTINUOUS_READ_STATE; F32 fpgaArtPres = getPressure( H2_PRES ) - arterialPressureOffset; F32 fpgaVenPres = getPressure( H14_PRES ) - venousPressureOffset; // Filter inline pressure readings filterInlinePressureReadings( fpgaArtPres, fpgaVenPres ); // Get latest dialysate pressure so we can calculate TMP tmpPressure.data = getLongFilteredVenousPressure() - getDialysatePressure(); // Handle pressure limits state machine execPressureLimits(); // Set arterial/venous pressure limits according to current pressure limits state determineArtVenPressureLimits(); // Check in-line pressures are in range #ifndef TEST_NO_PRESSURE_CHECKS checkArterialPressureInRange(); checkVenousPressureInRange(); #endif return result; } /*********************************************************************//** * @brief * The execPressureLimits function executes the pressure limits state machine. * @details \b Alarm: ALARM_ID_TD_SOFTWARE_FAULT if presure limits state is invalid. * @details \b Inputs: currPresLimitsState, stabilizationStartTimeMs * @details \b Outputs: currPresLimitsState, stabilizationStartTimeMs * @return next pressure limits state *************************************************************************/ static void execPressureLimits( void ) { BOOL bpRunning = TRUE; //isBloodPumpRunning(); BOOL bpRampComplete = TRUE; //isBloodPumpRampComplete(); TD_OP_MODE_T currMode = getCurrentOperationMode(); TREATMENT_STATE_T currTxState = TREATMENT_DIALYSIS_STATE; //getTreatmentState(); U32 stabilizeTime = PRES_LIMIT_STABILIZATION_TIME_MS; if ( currMode != MODE_TREA ) { currPresLimitsState = PRESSURE_LIMITS_STATE_OFF; } switch ( currPresLimitsState ) { case PRESSURE_LIMITS_STATE_OFF: if ( ( MODE_TREA == currMode ) && ( currTxState != TREATMENT_RECIRC_STATE ) ) { // Tx mode starts in blood prime - want wide limits in that state currPresLimitsState = PRESSURE_LIMITS_STATE_WIDE; } break; case PRESSURE_LIMITS_STATE_IDLE: if ( TRUE == bpRampComplete ) { currPresLimitsState = PRESSURE_LIMITS_STATE_WIDE; } break; case PRESSURE_LIMITS_STATE_WIDE: if ( bpRunning != TRUE ) { currPresLimitsState = PRESSURE_LIMITS_STATE_IDLE; } else if ( ( TREATMENT_DIALYSIS_STATE == currTxState ) || ( TREATMENT_PAUSED_STATE == currTxState ) ) { stabilizationStartTimeMs = getMSTimerCount(); pressureStabilizeTime = USE_NORMAL_STABILIZATION_PERIOD; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION; } else if ( currTxState == TREATMENT_RECIRC_STATE ) { currPresLimitsState = PRESSURE_LIMITS_STATE_OFF; } break; case PRESSURE_LIMITS_STATE_STABILIZATION: // update stabilization time if ( USE_SHORT_STABILIZATION_PERIOD == pressureStabilizeTime ) { stabilizeTime = PRES_LIMIT_SHORT_STABILIZE_TIME_MS; } // Normal stabilization period else { stabilizeTime = PRES_LIMIT_STABILIZATION_TIME_MS; } 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_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; 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; } else if ( ( currTxState != TREATMENT_DIALYSIS_STATE ) && ( currTxState != TREATMENT_PAUSED_STATE ) ) { currPresLimitsState = PRESSURE_LIMITS_STATE_WIDE; } else if ( TRUE == didTimeout( stabilizationStartTimeMs, PRES_LIMIT_RESTABILIZE_TIME_MS ) ) { stabilizationStartTimeMs = getMSTimerCount(); pressureStabilizeTime = STABILIZATION_PERIOD_OFF; currPresLimitsState = PRESSURE_LIMITS_STATE_STABILIZATION_2; } break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_TD_SOFTWARE_FAULT, SW_FAULT_ID_PRES_LIMITS_INVALID_STATE, currPresLimitsState ) break; } } /*********************************************************************//** * @brief * The checkArterialPressureInRange function checks that artieral pressure is * within the set alarm limits. * @details \b Alarm: ALARM_ID_TD_ARTERIAL_PRESSURE_LOW if arterial pressure is low. * @details \b Alarm: ALARM_ID_TD_ARTERIAL_PRESSURE_HIGH if arterial pressure is high. * @details \b Alarm: ALARM_ID_TD_ARTERIAL_PRESSURE_OUT_OF_RANGE if arterial * pressure is out of range. * @details \b Inputs: arterialPressure, pressureLimitsActive, currentArterialMinLimit, * currentArterialMaxLimit * @details \b Outputs: none * @return none *************************************************************************/ static void checkArterialPressureInRange( void ) { F32 artPres = getFilteredArterialPressure(); #ifndef _RELEASE_ // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_ARTERIAL_PRESSURE_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { // Check arterial pressure is in absolute max range if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_ARTERIAL_PRESSURE_OUT_OF_RANGE, ( artPres > ARTERIAL_PRESSURE_MAX_MMHG || artPres < ARTERIAL_PRESSURE_MIN_MMHG ) ) ) { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_OUT_OF_RANGE, artPres ); } // Check arterial pressure when limits active if ( pressureLimitsActive != FALSE ) { BOOL artPresLow, artPresHigh; artPresLow = ( artPres < (F32)currentArterialMinLimit ? TRUE : FALSE ); artPresHigh = ( artPres > (F32)currentArterialMaxLimit ? TRUE : FALSE ); // Check arterial pressure is within alarm limits if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_ARTERIAL_PRESSURE_LOW, artPresLow ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_LOW, artPres, (F32)currentArterialMinLimit ); } if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_ARTERIAL_PRESSURE_HIGH, artPresHigh ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_HIGH, artPres, (F32)currentArterialMaxLimit ); } } else { // Reset persistence if limits inactive isPersistentAlarmTriggered( ALARM_ID_TD_ARTERIAL_PRESSURE_LOW, FALSE ); isPersistentAlarmTriggered( ALARM_ID_TD_ARTERIAL_PRESSURE_HIGH, FALSE ); } } } /*********************************************************************//** * @brief * The checkVenousPressureInRange function checks that venous pressure is * within the set alarm limits. * @details \b Alarm: ALARM_ID_TD_VENOUS_PRESSURE_LOW if venous pressure is low. * @details \b Alarm: ALARM_ID_TD_VENOUS_PRESSURE_HIGH if venous pressure is high. * @details \b Alarm: ALARM_ID_TD_VENOUS_PRESSURE_OUT_OF_RANGE if venous pressure * is out of range. * @details \b Inputs: venousPressure, pressureLimitsActive, currentVenousMinLimit, resetFillExemptPeriod * currentVenousMaxLimit, venLowPresExemptAfterAirTrapFillTimerCtr, prevVenLowPresExemptAfterAirTrapFillTimerCtr * @details \b Outputs: venLowPresExemptAfterAirTrapFillTimerCtr * @return none *************************************************************************/ static void checkVenousPressureInRange( void ) { F32 venPres = getFilteredVenousPressure(); VALVE_3WAY_STATE_T airTrapValveState = VALVE_3WAY_COMMON_TO_CLOSED_STATE; //getValveAirTrapStatus(); // track time since last air trap fill if ( ( VALVE_3WAY_COMMON_TO_OPEN_STATE == airTrapValveState ) && ( TRUE == resetFillExemptPeriod ) ) { venLowPresExemptAfterAirTrapFillTimerCtr = 0; resetFillExemptPeriod = FALSE; lowVenousPressureExemptCheck = FALSE; } else { // 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_ // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_VENOUS_PRESSURE_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { // Check venous pressure is in absolute max range if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_VENOUS_PRESSURE_OUT_OF_RANGE, ( venPres > VENOUS_PRESSURE_MAX_MMHG || venPres < VENOUS_PRESSURE_MIN_MMHG ) ) ) { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_TD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres ); } // Check venous pressure when limits active if ( pressureLimitsActive != FALSE ) { BOOL venPresLow, venPresHigh; // Fixed exemption period (in general task intervals) for low venous pressure alarms after air trap fills U32 exemptPeriod = VENOUS_PRESSURE_EXEMPTION_PERIOD; // 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 // 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_TD_VENOUS_PRESSURE_LOW, venPresLow ) ) { #ifndef TEST_UI_ONLY SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_VENOUS_PRESSURE_LOW, venPres, (F32)currentVenousMinLimit ); #endif } } // during reset period, if airTrapValve open, still alarm needs to be raised , hence persistence clearance should happen before or after reset period. if ( ( airTrapValveState == VALVE_3WAY_COMMON_TO_OPEN_STATE ) && ( ( venLowPresExemptAfterAirTrapFillTimerCtr < exemptPeriod ) || ( venLowPresExemptAfterAirTrapFillTimerCtr > minimumMonitoringWindow ) ) ) { isPersistentAlarmTriggered( ALARM_ID_TD_VENOUS_PRESSURE_LOW, FALSE ); } if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_TD_VENOUS_PRESSURE_HIGH, venPresHigh ) ) { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_TD_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 isPersistentAlarmTriggered( ALARM_ID_TD_VENOUS_PRESSURE_LOW, FALSE ); isPersistentAlarmTriggered( ALARM_ID_TD_VENOUS_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 * @return none. *************************************************************************/ void signalLowVenousPressureCheck( void ) { // When flag set, low venous pressure exempt counter increments. lowVenousPressureExemptCheck = TRUE; } /*********************************************************************//** * @brief * The getFilteredArterialPressure function gets the current filtered arterial pressure. * @details \b Inputs: shortFilteredArterialPressure * @details \b Outputs: none * @return the current filtered arterial pressure (in mmHg). *************************************************************************/ F32 getFilteredArterialPressure( void ) { return getF32OverrideValue( &shortFilteredArterialPressure ); } /*********************************************************************//** * @brief * The getLongFilteredArterialPressure function gets the current long filtered arterial pressure. * @details \b Inputs: longFilteredArterialPressure * @details \b Outputs: none * @return the current long filtered arterial pressure (in mmHg). *************************************************************************/ F32 getLongFilteredArterialPressure( void ) { return longFilteredArterialPressure; } /*********************************************************************//** * @brief * The getFilteredVenousPressure function gets the measured filtered venous pressure. * @details \b Inputs: shortFilteredVenousPressure * @details \b Outputs: none * @return the current filtered venous pressure (in mmHg). *************************************************************************/ F32 getFilteredVenousPressure( void ) { return getF32OverrideValue( &shortFilteredVenousPressure ); } /*********************************************************************//** * @brief * The getLongFilteredVenousPressure function gets the current long filtered * venous pressure. * @details \b Inputs: longFilteredVenousPressure * @details \b Outputs: none * @return the current long filtered venous pressure (in mmHg). *************************************************************************/ F32 getLongFilteredVenousPressure( void ) { return longFilteredVenousPressure; } /*********************************************************************//** * @brief * The getTMPPressure function gets the calculated trans-membrane pressure. * @details \b Inputs: tmpPressure * @details \b Outputs: none * @return the current calculated TMP (in mmHg). *************************************************************************/ F32 getTMPPressure( void ) { return getF32OverrideValue( &tmpPressure ); } /*********************************************************************//** * @brief * The filterInlinePressureReadings function adds a new arterial and venous * pressure sample to the filters. * @details \b Inputs: none * @details \b Outputs: artPressureReadingsLong[], artPressureReadingsLongIdx, artPressureReadingsLongTotal, artPressureReadingsLongCount, * artPressureReadingsShort, artPressureReadingsShortIdx, artPressureReadingsShortTotal, artPressureReadingsShortCount, * venPressureReadingsShort, venPressureReadingsShortIdx, venPressureReadingsShortTotal, venPressureReadingsShortCount, * longFilteredArterialPressure, shortFilteredArterialPressure, shortFilteredVenousPressure * @param artPres newest arterial pressure sample to add to filters * @param venPres newest venous pressure sample to add to filter * @return none *************************************************************************/ static void filterInlinePressureReadings( F32 artPres, F32 venPres ) { // Long filter for arterial pressure. if ( artPressureReadingsLongCount >= SIZE_OF_LONG_ART_ROLLING_AVG ) { artPressureReadingsLongTotal -= artPressureReadingsLong[ artPressureReadingsLongIdx ]; } artPressureReadingsLong[ artPressureReadingsLongIdx ] = artPres; artPressureReadingsLongTotal += artPres; artPressureReadingsLongIdx = INC_WRAP( artPressureReadingsLongIdx, 0, SIZE_OF_LONG_ART_ROLLING_AVG - 1 ); artPressureReadingsLongCount = INC_CAP( artPressureReadingsLongCount, SIZE_OF_LONG_ART_ROLLING_AVG ); longFilteredArterialPressure = artPressureReadingsLongTotal / (F32)artPressureReadingsLongCount; // Short filter for arterial pressure. if ( artPressureReadingsShortCount >= SIZE_OF_SHORT_ART_ROLLING_AVG ) { artPressureReadingsShortTotal -= artPressureReadingsShort[ artPressureReadingsShortIdx ]; } artPressureReadingsShort[ artPressureReadingsShortIdx ] = artPres; artPressureReadingsShortTotal += artPres; artPressureReadingsShortIdx = INC_WRAP( artPressureReadingsShortIdx, 0, SIZE_OF_SHORT_ART_ROLLING_AVG - 1 ); artPressureReadingsShortCount = INC_CAP( artPressureReadingsShortCount, SIZE_OF_SHORT_ART_ROLLING_AVG ); shortFilteredArterialPressure.data = artPressureReadingsShortTotal / (F32)artPressureReadingsShortCount; // Long filter for venous pressure. if ( venPressureReadingsLongCount >= SIZE_OF_LONG_VEN_ROLLING_AVG ) { venPressureReadingsLongTotal -= venPressureReadingsLong[ venPressureReadingsLongIdx ]; } venPressureReadingsLong[ venPressureReadingsLongIdx ] = venPres; venPressureReadingsLongTotal += venPres; venPressureReadingsLongIdx = INC_WRAP( venPressureReadingsLongIdx, 0, SIZE_OF_LONG_VEN_ROLLING_AVG - 1 ); venPressureReadingsLongCount = INC_CAP( venPressureReadingsLongCount, SIZE_OF_LONG_VEN_ROLLING_AVG ); longFilteredVenousPressure = venPressureReadingsLongTotal / (F32)venPressureReadingsLongCount; // Short filter for venous pressure. if ( venPressureReadingsShortCount >= SIZE_OF_SHORT_VEN_ROLLING_AVG ) { venPressureReadingsShortTotal -= venPressureReadingsShort[ venPressureReadingsShortIdx ]; } venPressureReadingsShort[ venPressureReadingsShortIdx ] = venPres; venPressureReadingsShortTotal += venPres; venPressureReadingsShortIdx = INC_WRAP( venPressureReadingsShortIdx, 0, SIZE_OF_SHORT_VEN_ROLLING_AVG - 1 ); venPressureReadingsShortCount = INC_CAP( artPressureReadingsShortCount, SIZE_OF_SHORT_VEN_ROLLING_AVG ); shortFilteredVenousPressure.data = venPressureReadingsShortTotal / (F32)venPressureReadingsShortCount; } /*********************************************************************//** * @brief * The publishPressureData function publishes pressure data at the set * interval. * @details \b Message \b Sent: MSG_ID_TD_PRESSURE_DATA * @details \b Inputs: pressureDataPublicationTimerCounter, currPresLimitsState, * currentArterialMinLimit, currentArterialMaxLimit, currentVenousMinLimit, * currentVenousMaxLimit, longFilteredArterialPressure, longFilteredVenousPressure, * shortFilteredArterialPressure, shortFilteredVenousPressure * @details \b Outputs: Pressure data are published to CAN bus. * @return none *************************************************************************/ static void publishPressureData( void ) { // Publish pressure/occlusion data on interval if ( ++pressureDataPublicationTimerCounter >= getU32OverrideValue( &pressuresDataPublishInterval ) ) { PRESSURE_DATA_T data; data.h2Pressure = getFilteredArterialPressure(); data.h14Pressure = getFilteredVenousPressure(); data.presLimitState = currPresLimitsState; data.h2MinLimit = currentArterialMinLimit; data.h2MaxLimit = currentArterialMaxLimit; data.h14MinLimit = currentVenousMinLimit; data.h14MaxLimit = currentVenousMaxLimit; 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; broadcastData( MSG_ID_TD_PRESSURE_DATA, COMM_BUFFER_OUT_CAN_TD_BROADCAST, (U08*)&data, sizeof( PRESSURE_DATA_T ) ); pressureDataPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The execPressureTest function executes the Pressure self-test. Arterial * and venous pressures must be within range while sensors are open to atmosphere. * @details \b Alarm: ALARM_ID_TD_ARTERIAL_PRESSURE_SELF_TEST_FAILURE if * arterial pressure is out of range during test. * @details \b Alarm: ALARM_ID_TD_VENOUS_PRESSURE_SELF_TEST_FAILURE if * venous pressure is out of range during test. * @details \b Inputs: none * @details \b Outputs: Triggers fault when test case fails * @return none *************************************************************************/ void execPressureTest( void ) { #ifndef _RELEASE_ // if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif { F32 arterialPressure = getFilteredArterialPressure(); F32 venousPressure = getFilteredVenousPressure(); if ( ( arterialPressure < ARTERIAL_PRESSURE_SELF_TEST_MIN ) || ( arterialPressure > ARTERIAL_PRESSURE_SELF_TEST_MAX ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TD_ARTERIAL_PRESSURE_SELF_TEST_FAILURE, arterialPressure ); } if ( ( venousPressure < VENOUS_PRESSURE_SELF_TEST_MIN ) || ( venousPressure > VENOUS_PRESSURE_SELF_TEST_MAX ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_TD_VENOUS_PRESSURE_SELF_TEST_FAILURE, venousPressure ); } } } /*********************************************************************//** * @brief * The execPressurePOSTSelfTest function executes the pressure self-test to * be run during power-on self-test on startup. Calibration constants are * read in and their CRC is checked. * @details \b Inputs: none * @details \b Outputs: pressureSensorsCalRecord, occlusionSensorsCalRecord * @return PASSED if self-test passes, FAILED if not. *************************************************************************/ SELF_TEST_STATUS_T execPressurePOSTSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; 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_OCCLUSION_SESNSORS, (U08*)&occlusionSensorsCalRecord, sizeof( HD_OCCLUSION_SENSORS_CAL_RECORD_T ), // NUM_OF_CAL_DATA_OCCLUSION_SENSORS, ALARM_ID_NO_ALARM ); pressurePostState = PRESSURE_TEST_STATE_COMPLETE; if ( TRUE == calStatus ) { result = SELF_TEST_STATUS_PASSED; } else { result = SELF_TEST_STATUS_FAILED; } return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testPressuresDataPublishIntervalOverride function overrides the interval * at which the TD pressure data is published. * @details \b \b Inputs: none * @details \b \b Outputs: pressuresDataPublishInterval * @param message Override message from Dialin which includes the interval * (in ms) to override the pressure broadcast interval to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testPressuresDataPublishIntervalOverride( MESSAGE_T *message ) { BOOL result = u32BroadcastIntervalOverride( message, &pressuresDataPublishInterval, TASK_GENERAL_INTERVAL ); return result; } /*********************************************************************//** * @brief * The testTMPOverride function overrides the TMP pressure reported by this * unit. * @details \b Inputs: none * @details \b Outputs: tmpPressure * @param message Override message from Dialin which includes the value to * override the TMP pressure to. * @return TRUE if override request is successful, FALSE if not *************************************************************************/ BOOL testTMPOverride( MESSAGE_T *message ) { BOOL result = f32Override( message, &tmpPressure ); return result; } /**@}*/