Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r7499a42cc0f906f9a4a947c82c5b4615217ce7e5 -rfb1673d2282822995ed233f3e9ea5dfb0567780d --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 7499a42cc0f906f9a4a947c82c5b4615217ce7e5) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision fb1673d2282822995ed233f3e9ea5dfb0567780d) @@ -7,8 +7,8 @@ * * @file PresOccl.c * -* @author (last) Dara Navaei -* @date (last) 13-Jul-2022 +* @author (last) Michael Garthwaite +* @date (last) 26-Aug-2022 * * @author (original) Sean * @date (original) 15-Jan-2020 @@ -22,7 +22,8 @@ #include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" -#include "SystemCommMessages.h" +#include "SystemCommMessages.h" +#include "SelfTests.h" #include "TaskGeneral.h" #include "Temperatures.h" #include "Timers.h" @@ -66,6 +67,7 @@ #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_ND_MAX_MMHG ( 300.0F ) ///< Maximum venous pressure reading (in mmHg) when not dialyzing. +#define VENOUS_PRESSURE_OCCL_OFFSET_MMHG ( 50.0F ) ///< Venous pressure occlusion threshold offset from max alarm limit (in mmHg). #define PSI_TO_MMHG ( 51.7149F ) ///< Conversion factor for converting PSI to mmHg. @@ -91,7 +93,8 @@ #define EMPTY_SALINE_BAG_THRESHOLD_MMHG -300.0F ///< Threshold below which the saline bag is considered empty (in mmHg). TODO - get real threshold from Systems 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 PRES_ALARM_PERSISTENCE ( 1 * MS_PER_SECOND ) ///< Alarm persistence period for pressure alarms. +#define VEN_OCCL_ALARM_PERSISTENCE 100 ///< Alarm persistence period for venous occlusion alarm. /// 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 ) @@ -128,7 +131,6 @@ /// 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 }; static OVERRIDE_F32_T arterialPressure = {0.0, 0.0, 0.0, 0 }; ///< Measured arterial pressure. -static OVERRIDE_F32_T arterialPressureOffset = {0.0, 0.0, 0.0, 0 }; ///< Calculated arterial pressure offset. static OVERRIDE_F32_T venousPressure = {0.0, 0.0, 0.0, 0 }; ///< Measured venous pressure. static OVERRIDE_U32_T bloodPumpOcclusion = {0, 0, 0, 0 }; ///< Measured blood pump occlusion pressure. static F32 longFilteredArterialPressure; ///< Measured arterial pressure after long (10 s) filter. @@ -197,6 +199,7 @@ initPersistentAlarm( ALARM_ID_HD_ARTERIAL_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_VENOUS_LINE_OCCLUSION, 0, VEN_OCCL_ALARM_PERSISTENCE ); lastArterialPressureReadCtr = 0; lastVenousPressureReadCtr = 0; @@ -396,95 +399,44 @@ static void convertInlinePressures( void ) { F32 rawArterialPres = 0.0; - U08 artPresAlarm = 0; U08 artPresStatus = 0; F32 venPresPSI = 0.0; U16 fpgaVenPres = getFPGAVenousPressure(); U16 venPres = fpgaVenPres & 0x3FFF; // 14-bit data U08 venPresStatus = (U08)( fpgaVenPres >> SHIFT_14_BITS ); // High 2 bits is status code for venous pressure U08 venReadCtr = getFPGAVenousPressureReadCounter(); + U16 fpgaArtPres = getFPGADVTArterialPressure(); + U16 artPres = fpgaArtPres & 0x3FFF; + rawArterialPres = (F32)artPres; + artPresStatus = (U08)( fpgaArtPres >> SHIFT_14_BITS ); -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) - { - U16 fpgaArtPres = getFPGADVTArterialPressure(); - U16 artPres = fpgaArtPres & 0x3FFF; - rawArterialPres = (F32)artPres; - artPresStatus = (U08)( fpgaArtPres >> SHIFT_14_BITS ); - } - else -#endif - { - U32 fpgaArtPres = getFPGAArterialPressure(); - S32 artPres = (S32)( fpgaArtPres & MASK_OFF_U32_MSB ) - ARTERIAL_PRESSURE_CONVERSION_OFFSET; // Subtract 2^23 from low 24 bits to get signed reading - rawArterialPres = (F32)artPres; - artPresAlarm = (U08)( fpgaArtPres >> SHIFT_24_BITS ); // High byte is alarm code for arterial pressure - } -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) ) -#endif + if ( ARTERIAL_PRESSURE_NORMAL_OP == artPresStatus ) { - if ( ARTERIAL_PRESSURE_NORMAL_OP == artPresStatus ) - { - U08 artReadCtr = getFPGADVTArterialPressureReadCounter(); + U08 artReadCtr = getFPGADVTArterialPressureReadCounter(); - // Check for stale venous pressure reading - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR, ( lastArterialPressureReadCtr == artReadCtr ) ) ) - { - activateAlarmNoData( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR ); - } - // Record arterial pressure sensor read counter for next time around - lastArterialPressureReadCtr = artReadCtr; - - arterialPressure.data = ( (F32)(rawArterialPres - ARTERIAL_PRESSURE_OFFSET) * - (ARTERIAL_PRESSURE_MAX_PSI - ARTERIAL_PRESSURE_MIN_PSI) / (F32)ARTERIAL_PRESSURE_SCALE ) + ARTERIAL_PRESSURE_MIN_PSI; - arterialPressure.data = arterialPressure.data * PSI_TO_MMHG; - } - else if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, TRUE ) ) + // Check for stale venous pressure reading + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR, ( lastArterialPressureReadCtr == artReadCtr ) ) ) { - activateAlarmNoData( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT ); + activateAlarmNoData( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR ); } - else - { - resetPersistentAlarmTimer( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT ); - } - } + // Record arterial pressure sensor read counter for next time around + lastArterialPressureReadCtr = artReadCtr; -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_DVT_ARTERIAL_PRESSURE_SENSOR ) != SW_CONFIG_ENABLE_VALUE ) -#endif + arterialPressure.data = ( (F32)(rawArterialPres - ARTERIAL_PRESSURE_OFFSET) * + (ARTERIAL_PRESSURE_MAX_PSI - ARTERIAL_PRESSURE_MIN_PSI) / (F32)ARTERIAL_PRESSURE_SCALE ) + ARTERIAL_PRESSURE_MIN_PSI; + arterialPressure.data = arterialPressure.data * PSI_TO_MMHG; + } + else if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, TRUE ) ) { - if ( 0 == artPresAlarm ) - { - U08 artReadCtr = getFPGAArterialPressureReadCounter(); - U08 artErrorCtr = getFPGAArterialPressureErrorCounter(); - - // Check for stale arterial pressure reading - // TODO I think we should check the change of the error count not if it is greater than 0? - if ( FALSE == isPersistentAlarmTriggered( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR, ( lastArterialPressureReadCtr == artReadCtr || artErrorCtr > 0 ) ) ) - { - arterialPressure.data = ARTERIAL_PRESSURE_V_PER_BIT * ( rawArterialPres / ( ARTERIAL_PRESSURE_SENSITIVITY * ARTERIAL_PRESSURE_V_BIAS ) ) + - getF32OverrideValue( &arterialPressureOffset ); - } - else - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_ARTERIAL_PRESSURE_READ_TIMEOUT_ERROR, (U32)artErrorCtr ); - } - // Record arterial pressure sensor read counter for next time around - lastArterialPressureReadCtr = artReadCtr; - } - else - { -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) -#endif - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, (U32)artPresAlarm ) - } - } + activateAlarmNoData( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT ); } + else + { + resetPersistentAlarmTimer( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT ); + } + // Check for stale venous pressure reading if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_READ_TIMEOUT_ERROR, ( lastVenousPressureReadCtr == venReadCtr ) ) ) { @@ -494,7 +446,7 @@ lastVenousPressureReadCtr = venReadCtr; // Convert venous pressure to PSI and then mmHg - venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX_PSI - VENOUS_PRESSURE_MIN_PSI) / (F32)VENOUS_PRESSURE_SCALE ) + + venPresPSI = ( (F32)( venPres - VENOUS_PRESSURE_OFFSET ) * ( VENOUS_PRESSURE_MAX_PSI - VENOUS_PRESSURE_MIN_PSI ) / (F32)VENOUS_PRESSURE_SCALE ) + VENOUS_PRESSURE_MIN_PSI; // Convert venous pressure from PSI to mmHg if sensor status is normal @@ -644,8 +596,7 @@ #endif { // Check venous pressure is in range - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres > VENOUS_PRESSURE_MAX_MMHG ) || - TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres < VENOUS_PRESSURE_MIN_MMHG ) ) + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, ( venPres > VENOUS_PRESSURE_MAX_MMHG || venPres < VENOUS_PRESSURE_MIN_MMHG ) ) ) { SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_VENOUS_PRESSURE_OUT_OF_RANGE, venPres ); } @@ -689,6 +640,7 @@ { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_VENOUS_PRESSURE_HIGH, venPres, VENOUS_PRESSURE_ND_MAX_MMHG ); } + isPersistentAlarmTriggered( ALARM_ID_VENOUS_PRESSURE_LOW, FALSE ); } else { // Reset persistence if alarm is out of scope @@ -709,28 +661,73 @@ static void checkOcclusions( void ) { U32 bpOccl = getMeasuredBloodPumpOcclusion(); - BOOL outOfRange = ( bpOccl < MIN_OCCLUSION_COUNTS || bpOccl > MAX_OCCLUSION_COUNTS ? TRUE : FALSE ); + BOOL outOfRange = ( bpOccl < MIN_OCCLUSION_COUNTS || bpOccl > MAX_OCCLUSION_COUNTS ? TRUE : FALSE ); #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PRESSURE_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) #endif { - // Range check occlusion sensor + F32 venPres = getMeasuredVenousPressure(); + HD_OP_MODE_T hdMode = getCurrentOperationMode(); + U32 hdSubMode = getCurrentSubMode(); + BOOL txMode = ( MODE_TREA == hdMode ? TRUE : FALSE ); + BOOL ptxMode = ( MODE_PRET == hdMode && hdSubMode > HD_PRE_TREATMENT_CART_INSTALL_STATE ? TRUE : FALSE ); + + // Range check occlusion sensor (OB) if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, outOfRange ) ) { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_OUT_OF_RANGE, bpOccl ); } - // Check for occlusion - if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + // Check for occlusion in PreTreatment modes when the cartridge is installed + // and setOcclusionInstallLevel has been called. + if ( MODE_PRET == getCurrentOperationMode() ) { - signalBloodPumpHardStop(); // Stop pump immediately - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + if ( getPreTreatmentSubState() > HD_PRE_TREATMENT_CART_INSTALL_STATE && getDrySelfTestsState() > DRY_SELF_TESTS_START_STATE ) + { + // Check for occlusion + if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { + signalBloodPumpHardStop(); // Stop pump immediately + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + } + } } - else + + // Check for occlusion in Treatment modes where pumps are moving + else if ( MODE_TREA == getCurrentOperationMode() ) { + if ( TREATMENT_STOP_STATE != getTreatmentState() ) + { + // Check for occlusion + if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { + signalBloodPumpHardStop(); // Stop pump immediately + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + } + } + } + + // Clear alarm regardless of op mode once conditions are met. + if ( bpOccl <= ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); } + + // Check for venous occlusion + if ( ( TRUE == txMode || TRUE == ptxMode ) && + ( venPres > getS32TreatmentParamUpperRangeLimit( TREATMENT_PARAM_VEN_PRESSURE_HIGH_LIMIT ) + VENOUS_PRESSURE_OCCL_OFFSET_MMHG ) ) + { + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_LINE_OCCLUSION, TRUE ) ) + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_HD_VENOUS_LINE_OCCLUSION, venPres ); + } + } + else + { + clearAlarmCondition( ALARM_ID_HD_VENOUS_LINE_OCCLUSION ); + isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_LINE_OCCLUSION, FALSE ); + } } } @@ -1184,49 +1181,4 @@ return result; } -/*********************************************************************//** - * @brief - * The testSetBloodPumpOcclusionOverride function overrides the arterial - * pressure offset. - * @details Inputs: none - * @details Outputs: arterialPressureOffset - * @param value override arterial pressure offset with - * @return TRUE if override successful, FALSE if not - *************************************************************************/ -BOOL testSetArterialPressureOffsetOverride( F32 value ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - arterialPressureOffset.ovData = value; - arterialPressureOffset.override = OVERRIDE_KEY; - } - - return result; -} - -/*********************************************************************//** - * @brief - * The testResetArterialPressureOffsetOverride function resets the override of the - * arterial pressure offset. - * @details Inputs: none - * @details Outputs: arterialPressureOffset - * @return TRUE if reset successful, FALSE if not - *************************************************************************/ -BOOL testResetArterialPressureOffsetOverride( void ) -{ - BOOL result = FALSE; - - if ( TRUE == isTestingActivated() ) - { - result = TRUE; - arterialPressureOffset.override = OVERRIDE_RESET; - arterialPressureOffset.ovData = arterialPressureOffset.ovInitData; - } - - return result; -} - /**@}*/