Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -rc9e1a93ccd8cfbdc9737c8ffc9e6a3dbe9ba7c44 -rf8feb10a7e19e17148e4ce8b247316c9772d1753 --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision c9e1a93ccd8cfbdc9737c8ffc9e6a3dbe9ba7c44) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision f8feb10a7e19e17148e4ce8b247316c9772d1753) @@ -42,7 +42,17 @@ #define VENOUS_PRESSURE_MIN ( -30.0 ) ///< Minimum of scale for venous pressure sensor reading (in PSI). #define VENOUS_PRESSURE_MAX ( 30.0 ) ///< Maximum of scale for venous pressure sensor reading (in PSI). -#define PSI_TO_MMHG ( 51.7149 ) ///< Conversion factor for converting PSI to mmHg. +#define PSI_TO_MMHG ( 51.7149 ) ///< Conversion factor for converting PSI to mmHg. + +#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). +#define VENOUS_PRESSURE_DIAG_CONDITION 3 ///< Venous pressure status bits diagnostic condition (alarm). + +#define MAX_TIME_BETWEEN_VENOUS_READINGS ( 500 / TASK_GENERAL_INTERVAL ) ///< Maximum time without fresh inline venous pressure reading. + +#define OCCLUSION_THRESHOLD 25000 ///< Threshold above which an occlusion is detected. +#define CARTRIDGE_LOADED_THRESHOLD 5000 ///< Threshold above which a cartridge is considered loaded. /// Defined states for the pressure and occlusion monitor state machine. typedef enum PresOccl_States @@ -68,20 +78,19 @@ static OVERRIDE_F32_T measuredBloodFlowRate = { 0.0, 0.0, 0.0, 0 }; ///< measured blood flow rate -static OVERRIDE_U32_T presOcclDataPublishInterval = { PRES_OCCL_DATA_PUB_INTERVAL, PRES_OCCL_DATA_PUB_INTERVAL, 0, 0 }; ///< interval (in ms) at which to publish pressure/occlusion data to CAN bus. +/// 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 venousPressure = {0.0, 0.0, 0.0, 0 }; ///< measured venous pressure. -static OVERRIDE_F32_T bloodPumpOcclusion = {0.0, 0.0, 0.0, 0 }; ///< measured blood pump occlusion pressure. -static OVERRIDE_F32_T dialInPumpOcclusion = {0.0, 0.0, 0.0, 0 }; ///< measured dialysate inlet pump occlusion pressure. -static OVERRIDE_F32_T dialOutPumpOcclusion = {0.0, 0.0, 0.0, 0 }; ///< measured dialysate outlet pump occlusion pressure. +static OVERRIDE_U32_T bloodPumpOcclusion = {0, 0, 0, 0 }; ///< measured blood pump occlusion pressure. +static OVERRIDE_U32_T dialInPumpOcclusion = {0, 0, 0, 0 }; ///< measured dialysate inlet pump occlusion pressure. +static OVERRIDE_U32_T dialOutPumpOcclusion = {0, 0, 0, 0 }; ///< measured dialysate outlet pump occlusion pressure. -static PRESSURE_SELF_TEST_STATE_T presOcclSelfTestState = PRESSURE_SELF_TEST_STATE_START; ///< current pressure self-test state. +/// current pressure self-test state. +static PRESSURE_SELF_TEST_STATE_T presOcclSelfTestState = PRESSURE_SELF_TEST_STATE_START; static U32 bloodPumpSelfTestTimerCount = 0; ///< timer counter for pressure self-test. -// TODO - set thresholds for occlusions -static F32 bloodPumpOcclusionPressureThresholdmmHG = 50.0; ///< pressure threshold for blood pump occlusion. -static F32 dialInPumpOcclusionPressureThresholdmmHG = 50.0; ///< pressure threshold for dialysate inlet pump occlusion. -static F32 dialOutPumpOcclusionPressureThresholdmmHG = 50.0; ///< pressure threshold for dialysate outlet pump occlusion. +static U32 staleVenousPressureCtr = 0; ///< timer counter for stale venous pressure reading. // ********** private function prototypes ********** @@ -106,39 +115,6 @@ /*********************************************************************//** * @brief - * The setOcclusionThreshold function sets the occlusion pressure threshold - * for a given occlusion sensor. - * @details - * Inputs : none - * Outputs : pressure threshold - * @param sensor occlusion sensor we are setting threshold for - * @param threshold pressure threshold above which indicates an occlusion (mmHg) - * @return none - *************************************************************************/ -void setOcclusionThreshold( OCCLUSION_SENSORS_T sensor, F32 threshold ) -{ - switch ( sensor ) // TODO - will threshold be range checked by caller or should we do it here? what is valid range? - { - case OCCLUSION_SENSOR_BLOOD_PUMP: - bloodPumpOcclusionPressureThresholdmmHG = threshold; - break; - - case OCCLUSION_SENSOR_DIAL_IN_PUMP: - dialInPumpOcclusionPressureThresholdmmHG = threshold; - break; - - case OCCLUSION_SENSOR_DIAL_OUT_PUMP: - dialOutPumpOcclusionPressureThresholdmmHG = threshold; - break; - - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_PRES_OCCL_INVALID_OCCL_SENSOR, sensor ) - break; - } -} - -/*********************************************************************//** - * @brief * The execPresOccl function executes the pressure and occlusion monitor. * @details * Inputs : presOcclState @@ -202,7 +178,7 @@ U16 fpgaVenPres = getFPGAVenousPressure(); U16 venPres = fpgaVenPres & 0x3FFF; // 14-bit data U08 venPresStatus = (U08)( fpgaVenPres >> 14 ); // high 2 bits is status code for venous pressure - F32 venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX - VENOUS_PRESSURE_MIN) / (F32)VENOUS_PRESSURE_SCALE ) - VENOUS_PRESSURE_MIN; + F32 venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX - VENOUS_PRESSURE_MIN) / (F32)VENOUS_PRESSURE_SCALE ) + VENOUS_PRESSURE_MIN; U16 bldOccl = getFPGABloodPumpOcclusion(); U16 dliOccl = getFPGADialInPumpOcclusion(); U16 dloOccl = getFPGADialOutPumpOcclusion(); @@ -211,20 +187,73 @@ // convert arterial pressure to mmHg arterialPressure.data = ARTERIAL_PRESSURE_V_PER_BIT * ( (F32)(artPres) / ( ARTERIAL_PRESSURE_SENSITIVITY * ARTERIAL_PRESSURE_V_BIAS ) ); - // convert venous pressure from PSI to mmHg - venousPressure.data = venPresPSI * PSI_TO_MMHG; + // convert venous pressure from PSI to mmHg + if ( VENOUS_PRESSURE_NORMAL_OP == venPresStatus ) + { + venousPressure.data = venPresPSI * PSI_TO_MMHG; + staleVenousPressureCtr = 0; + } + else + { + if ( ++staleVenousPressureCtr > MAX_TIME_BETWEEN_VENOUS_READINGS ) + { +#ifndef DISABLE_PRESSURE_CHECKS + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, VENOUS_PRESSURE_STALE_DATA ) +#endif + } + } + // occlusion sensor values have no unit - take as is - bloodPumpOcclusion.data = (F32)bldOccl; - dialInPumpOcclusion.data = (F32)dliOccl; - dialOutPumpOcclusion.data = (F32)dloOccl; + bloodPumpOcclusion.data = (U32)bldOccl; + dialInPumpOcclusion.data = (U32)dliOccl; + dialOutPumpOcclusion.data = (U32)dloOccl; // check for occlusions - checkOcclusions(); - - // TODO - any other checks - + checkOcclusions(); + + // check for arterial pressure alarm + if ( artPresAlarm != 0 ) + { +#ifndef DISABLE_PRESSURE_CHECKS + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_ARTERIAL_PRESSURE_SENSOR_FAULT, (U32)artPresAlarm ) +#endif + } + + // check for venous pressure alarm + if ( ( VENOUS_PRESSURE_DIAG_CONDITION == venPresStatus ) || ( VENOUS_PRESSURE_CMD_MODE == venPresStatus ) ) + { +#ifndef DISABLE_PRESSURE_CHECKS + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, (U32)venPresStatus ) +#endif + } + return result; } + +/*********************************************************************//** + * @brief + * The isCartridgeLoaded function determines whether a cartridge has been + * properly loaded by looking at the 3 occlusion pressure sensors. + * @details Inputs: occlusion pressures for the pumps + * @details Outputs: none + * @return TRUE if all 3 occlusion sensors read above loaded threshold, FALSE if not. + *************************************************************************/ +BOOL isCartridgeLoaded( void ) +{ + BOOL result = FALSE; + U32 bpOccl = getMeasuredBloodPumpOcclusion(); + U32 diOccl = getMeasuredDialInPumpOcclusion(); + U32 doOccl = getMeasuredDialOutPumpOcclusion(); + + if ( ( bpOccl >= CARTRIDGE_LOADED_THRESHOLD ) && + ( diOccl >= CARTRIDGE_LOADED_THRESHOLD ) && + ( doOccl >= CARTRIDGE_LOADED_THRESHOLD ) ) + { + result = TRUE; + } + + return result; +} /*********************************************************************//** * @brief @@ -237,24 +266,24 @@ *************************************************************************/ static void checkOcclusions( void ) { - F32 bpOccl = getMeasuredBloodPumpOcclusion(); - F32 diOccl = getMeasuredDialInPumpOcclusion(); - F32 doOccl = getMeasuredDialOutPumpOcclusion(); + U32 bpOccl = getMeasuredBloodPumpOcclusion(); + U32 diOccl = getMeasuredDialInPumpOcclusion(); + U32 doOccl = getMeasuredDialOutPumpOcclusion(); #ifndef DISABLE_PRESSURE_CHECKS - if ( bpOccl > bloodPumpOcclusionPressureThresholdmmHG ) + if ( bpOccl > OCCLUSION_THRESHOLD ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) // TODO - stop blood pump immediately, ... } - if ( diOccl > dialInPumpOcclusionPressureThresholdmmHG ) + if ( diOccl > OCCLUSION_THRESHOLD ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_OCCLUSION_DIAL_IN_PUMP, diOccl ) + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_DIAL_IN_PUMP, diOccl ) // TODO - stop dialysate inlet pump immediately, ... } - if ( doOccl > dialOutPumpOcclusionPressureThresholdmmHG ) + if ( doOccl > OCCLUSION_THRESHOLD ) { - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_OCCLUSION_DIAL_OUT_PUMP, doOccl ) + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_DIAL_OUT_PUMP, doOccl ) // TODO - stop dialysate outlet pump immediately, ... } #endif @@ -269,7 +298,17 @@ * Outputs : none * @return the current pressure/occlusion data publication interval (in task intervals). *************************************************************************/ -DATA_GET( U32, getPublishPresOcclDataInterval, presOcclDataPublishInterval ) +U32 getPublishPresOcclDataInterval( void ) +{ + U32 result = presOcclDataPublishInterval.data; + + if ( OVERRIDE_KEY == presOcclDataPublishInterval.override ) + { + result = presOcclDataPublishInterval.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -279,7 +318,17 @@ * Outputs : none * @return the current arterial pressure (in mmHg). *************************************************************************/ -DATA_GET( F32, getMeasuredArterialPressure, arterialPressure ) +F32 getMeasuredArterialPressure( void ) +{ + F32 result = arterialPressure.data; + + if ( OVERRIDE_KEY == arterialPressure.override ) + { + result = arterialPressure.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -289,7 +338,17 @@ * Outputs : none * @return the current venous pressure (in mmHg). *************************************************************************/ -DATA_GET( F32, getMeasuredVenousPressure, venousPressure ) +F32 getMeasuredVenousPressure( void ) +{ + F32 result = venousPressure.data; + + if ( OVERRIDE_KEY == venousPressure.override ) + { + result = venousPressure.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -300,7 +359,17 @@ * Outputs : none * @return the current blood pump occlusion pressure (in mmHg). *************************************************************************/ -DATA_GET( F32, getMeasuredBloodPumpOcclusion, bloodPumpOcclusion ) +U32 getMeasuredBloodPumpOcclusion( void ) +{ + U32 result = bloodPumpOcclusion.data; + + if ( OVERRIDE_KEY == bloodPumpOcclusion.override ) + { + result = bloodPumpOcclusion.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -311,7 +380,17 @@ * Outputs : none * @return the current dialysis inlet pump occlusion pressure (in mmHg). *************************************************************************/ -DATA_GET( F32, getMeasuredDialInPumpOcclusion, dialInPumpOcclusion ) +U32 getMeasuredDialInPumpOcclusion( void ) +{ + U32 result = dialInPumpOcclusion.data; + + if ( OVERRIDE_KEY == dialInPumpOcclusion.override ) + { + result = dialInPumpOcclusion.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -322,7 +401,17 @@ * Outputs : none * @return the current dialysis outlet pump occlusion pressure (in mmHg). *************************************************************************/ -DATA_GET( F32, getMeasuredDialOutPumpOcclusion, dialOutPumpOcclusion ) +U32 getMeasuredDialOutPumpOcclusion( void ) +{ + U32 result = dialOutPumpOcclusion.data; + + if ( 0xCCC33C33 == dialOutPumpOcclusion.override ) + { + result = dialOutPumpOcclusion.ovData; + } + + return result; +} /*********************************************************************//** * @brief @@ -337,14 +426,16 @@ { // publish pressure/occlusion data on interval if ( ++presOcclDataPublicationTimerCounter >= getPublishPresOcclDataInterval() ) - { - F32 artPres = getMeasuredArterialPressure(); - F32 venPres = getMeasuredVenousPressure(); - F32 bpOccl = getMeasuredBloodPumpOcclusion(); - F32 diOccl = getMeasuredDialInPumpOcclusion(); - F32 doOccl = getMeasuredDialOutPumpOcclusion(); + { + PRESSURE_OCCLUSION_DATA_T data; - broadcastPresOcclData( artPres, venPres, bpOccl, diOccl, doOccl ); + data.artPres = getMeasuredArterialPressure(); + data.venPres = getMeasuredVenousPressure(); + data.bpOccl = getMeasuredBloodPumpOcclusion(); + data.diOccl = getMeasuredDialInPumpOcclusion(); + data.doOccl = getMeasuredDialOutPumpOcclusion(); + + broadcastPresOcclData( data ); presOcclDataPublicationTimerCounter = 0; } } @@ -519,14 +610,14 @@ /*********************************************************************//** * @brief * The testSetBloodPumpOcclusionOverride function overrides the measured - * blood pump occlusion pressure.n + * blood pump occlusion pressure. * @details * Inputs : none * Outputs : bloodPumpOcclusion - * @param value override measured blood pump occlusion pressure with (in mmHg) + * @param value override measured blood pump occlusion pressure with * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testSetBloodPumpOcclusionOverride( F32 value ) +BOOL testSetBloodPumpOcclusionOverride( U32 value ) { BOOL result = FALSE; @@ -570,10 +661,10 @@ * @details * Inputs : none * Outputs : dialInPumpOcclusion - * @param value override measured dialysate inlet pump occlusion pressure (in mmHg) + * @param value override measured dialysate inlet pump occlusion pressure * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testSetDialInPumpOcclusionOverride( F32 value ) +BOOL testSetDialInPumpOcclusionOverride( U32 value ) { BOOL result = FALSE; @@ -617,10 +708,10 @@ * @details * Inputs : none * Outputs : dialOutPumpOcclusion - * @param value override measured dialysate outlet pump occlusion pressure (in mmHg) + * @param value override measured dialysate outlet pump occlusion pressure * @return TRUE if override successful, FALSE if not *************************************************************************/ -BOOL testSetDialOutPumpOcclusionOverride( F32 value ) +BOOL testSetDialOutPumpOcclusionOverride( U32 value ) { BOOL result = FALSE;