Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -rfa0ab419491364c1d2a28caf216e20175181372d -r74a3506d935a18d4174f94d8c0fdbc750105904f --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision fa0ab419491364c1d2a28caf216e20175181372d) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 74a3506d935a18d4174f94d8c0fdbc750105904f) @@ -50,15 +50,16 @@ #define VENOUS_PRESSURE_SELF_TEST_MIN ( -100.0 ) ///< Minimum self-test value for venous pressure sensor reading (in mmHg). #define VENOUS_PRESSURE_SELF_TEST_MAX ( 600.0 ) ///< Maximum self-test value for venous pressure sensor reading (in mmHg). +#define VENOUS_PRESSURE_MIN_TEMP ( 0.0 ) ///< Minimum venous pressure sensor temperature. TODO - get from Systems +#define VENOUS_PRESSURE_MAX_TEMP ( 50.0 ) ///< Maximum venous pressure sensor temperature. TODO - get from Systems + #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). -static const U32 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. @@ -101,8 +102,12 @@ 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 U32 staleVenousPressureCtr = 0; ///< Timer counter for stale venous pressure reading. static U32 emptySalineBagCtr = 0; ///< Timer counter for empty bag detection. + +static U08 lastVenousPressureReadCtr; ///< Previous venous pressure read counter. +static U08 lastBPOcclReadCtr; ///< Previous BP occlusion read counter. +static U08 lastDPiOcclReadCtr; ///< Previous DPi occlusion read counter. +static U08 lastDPoOcclReadCtr; ///< Previous DPo occlusion read counter. // ********** private function prototypes ********** @@ -130,6 +135,16 @@ initPersistentAlarm( ALARM_ID_ARTERIAL_PRESSURE_HIGH, PRES_ALARM_PERSISTENCE, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_VENOUS_PRESSURE_LOW, PRES_ALARM_PERSISTENCE, PRES_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_VENOUS_PRESSURE_HIGH, PRES_ALARM_PERSISTENCE, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_VENOUS_PRESSURE_READ_TIMEOUT_ERROR, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_VENOUS_PRESSURE_SENSOR_TEMP_OUT_OF_RANGE, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_DPI_OCCLUSON_READ_TIMEOUT_ERROR, 0, PRES_ALARM_PERSISTENCE ); + initPersistentAlarm( ALARM_ID_HD_DPO_OCCLUSION_READ_TIMEOUT_ERROR, 0, PRES_ALARM_PERSISTENCE ); + + lastVenousPressureReadCtr = 0; + lastBPOcclReadCtr = 0; + lastDPiOcclReadCtr = 0; + lastDPoOcclReadCtr = 0; } /*********************************************************************//** @@ -275,10 +290,12 @@ U16 venPres = fpgaVenPres & 0x3FFF; // 14-bit data U08 venPresStatus = (U08)( fpgaVenPres >> 14 ); // High 2 bits is status code for venous pressure F32 venPresPSI; + F32 venTemp = getFPGAVenousPressureTemperature(); + U08 venReadCtr = getFPGAVenousPressureReadCounter(); // TODO - any filtering required??? - // Convert arterial pressure to mmHg if no alarm + // Convert arterial pressure to mmHg if no fault if ( 0 == artPresAlarm ) { arterialPressure.data = ARTERIAL_PRESSURE_V_PER_BIT * ( (F32)(artPres) / ( ARTERIAL_PRESSURE_SENSITIVITY * ARTERIAL_PRESSURE_V_BIAS ) ); @@ -290,31 +307,33 @@ #endif } - // Convert venous pressure to PSI + // Check for stale venous pressure reading + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_READ_TIMEOUT_ERROR, ( lastVenousPressureReadCtr == venReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_VENOUS_PRESSURE_READ_TIMEOUT_ERROR ); + } + // Record venous read counter for next time around + lastVenousPressureReadCtr = venReadCtr; + // Convert venous pressure to PSI and then mmHg venPresPSI = ( (F32)(venPres - VENOUS_PRESSURE_OFFSET) * (VENOUS_PRESSURE_MAX - VENOUS_PRESSURE_MIN) / (F32)VENOUS_PRESSURE_SCALE ) + VENOUS_PRESSURE_MIN; // Convert venous pressure from PSI to mmHg if sensor status is normal if ( VENOUS_PRESSURE_NORMAL_OP == venPresStatus ) { venousPressure.data = venPresPSI * PSI_TO_MMHG; - staleVenousPressureCtr = 0; } - // If venous pressure sensor status is not normal or reading is stale for too long, fault + // If venous pressure sensor status is not normal, fault 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 ) + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, (U32)venPresStatus ) // TODO - persistence? #endif - } } - // Check for venous pressure sensor alarm or in wrong (cmd) mode - if ( ( VENOUS_PRESSURE_DIAG_CONDITION == venPresStatus ) || ( VENOUS_PRESSURE_CMD_MODE == venPresStatus ) ) + // Check venous pressure sensor temperature + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_VENOUS_PRESSURE_SENSOR_TEMP_OUT_OF_RANGE, + ( venTemp > VENOUS_PRESSURE_MAX_TEMP || venTemp < VENOUS_PRESSURE_MIN_TEMP ) ) ) { -#ifndef DISABLE_PRESSURE_CHECKS - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, (U32)venPresStatus ) -#endif + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_VENOUS_PRESSURE_SENSOR_FAULT, venTemp ) } } @@ -327,10 +346,50 @@ *************************************************************************/ static void convertOcclusionPressures( void ) { - // Occlusion sensor values have no unit - take as is + U08 bpReadCtr = getFPGABloodPumpOcclusionReadCounter(); + U08 dpiReadCtr = getFPGADialInPumpOcclusionReadCounter(); + U08 dpoReadCtr = getFPGADialOutPumpOcclusionReadCounter(); + U08 bpErrorCtr = getFPGABloodPumpOcclusionErrorCounter(); + U08 dpiErrorCtr = getFPGADialInPumpOcclusionErrorCounter(); + U08 dpoErrorCtr = getFPGADialOutPumpOcclusionErrorCounter(); + + // Check for sensor errors + if ( bpErrorCtr > 0 ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_OCCLUSION_SENSOR_ERROR, (U32)bpErrorCtr ) + } + if ( dpiErrorCtr > 0 ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DPI_OCCLUSION_SENSOR_ERROR, (U32)dpiErrorCtr ) + } + if ( dpoErrorCtr > 0 ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DPO_OCCLUSION_SENSOR_ERROR, (U32)dpoErrorCtr ) + } + + // Check for stale occlusion reads + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR, ( bpReadCtr == lastBPOcclReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR, ( dpiReadCtr == lastDPiOcclReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_DPI_OCCLUSON_READ_TIMEOUT_ERROR ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_OCCLUSION_READ_TIMEOUT_ERROR, ( dpoReadCtr == lastDPoOcclReadCtr ) ) ) + { + activateAlarmNoData( ALARM_ID_HD_DPO_OCCLUSION_READ_TIMEOUT_ERROR ); + } + + // Record occlusion sensor readings bloodPumpOcclusion.data = (U32)getFPGABloodPumpOcclusion(); dialInPumpOcclusion.data = (U32)getFPGADialInPumpOcclusion(); dialOutPumpOcclusion.data = (U32)getFPGADialOutPumpOcclusion(); + + // Record occlusion read counters for next time around + lastBPOcclReadCtr = bpReadCtr; + lastDPiOcclReadCtr = dpiReadCtr; + lastDPoOcclReadCtr = dpoReadCtr; } /*********************************************************************//** Index: firmware/App/Services/FPGA.c =================================================================== diff -u -rfa0ab419491364c1d2a28caf216e20175181372d -r74a3506d935a18d4174f94d8c0fdbc750105904f --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision fa0ab419491364c1d2a28caf216e20175181372d) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 74a3506d935a18d4174f94d8c0fdbc750105904f) @@ -86,6 +86,10 @@ #define FPGA_ADV_INPUT_STATUS_MASK 0x0002 ///< Bit mask for venous air bubble detector input status. #define FPGA_BLOOD_LEAK_STATUS_MASK 0x1000 ///< Bit mask for blood leak detector status. +#define FPGA_PBO_TEMP_DIVISOR 2047.0 ///< Used in conversion of PBo temperature reading to deg C. +#define FPGA_PBO_TEMP_GAIN 200.0 ///< Used in conversion of PBo temperature reading to deg C. +#define FPGA_PBO_TEMP_OFFSET 50.0 ///< Used in conversion of PBo temperature reading to deg C. + // FPGA Sensors Record #pragma pack(push,1) /// Record structure for FPGA header read. @@ -1305,6 +1309,84 @@ /*********************************************************************//** * @brief + * The getFPGABloodPumpOcclusionReadCounter function gets the latest blood + * pump occlusion read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last blood pump occlusion read counter + *************************************************************************/ +U08 getFPGABloodPumpOcclusionReadCounter( void ) +{ + return fpgaSensorReadings.bloodOcclusionReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialInPumpOcclusionReadCounter function gets the latest dialysate + * inlet pump occlusion read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate inlet pump occlusion read counter + *************************************************************************/ +U08 getFPGADialInPumpOcclusionReadCounter( void ) +{ + return fpgaSensorReadings.dialysateInOcclusionReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialOutPumpOcclusionReadCounter function gets the latest dialysate + * outlet pump occlusion read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate outlet pump occlusion read counter + *************************************************************************/ +U08 getFPGADialOutPumpOcclusionReadCounter( void ) +{ + return fpgaSensorReadings.dialysateOutOcclusionReadCount; +} + +/*********************************************************************//** + * @brief + * The getFPGABloodPumpOcclusionErrorCounter function gets the latest blood + * pump occlusion error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last blood pump occlusion error counter + *************************************************************************/ +U08 getFPGABloodPumpOcclusionErrorCounter( void ) +{ + return fpgaSensorReadings.bloodOcclusionErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialInPumpOcclusionErrorCounter function gets the latest dialysate + * inlet pump occlusion error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate inlet pump occlusion error counter + *************************************************************************/ +U08 getFPGADialInPumpOcclusionErrorCounter( void ) +{ + return fpgaSensorReadings.dialysateInOcclusionErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialOutPumpOcclusionErrorCounter function gets the latest dialysate + * outlet pump occlusion error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate outlet pump occlusion error counter + *************************************************************************/ +U08 getFPGADialOutPumpOcclusionErrorCounter( void ) +{ + return fpgaSensorReadings.dialysateOutOcclusionErrorCount; +} + +/*********************************************************************//** + * @brief * The getFPGAArterialPressure function gets the latest arterial pressure reading. * High byte indicates alarm status for ADC channel. * Low 24-bits are channel reading. Subtract 2^23 from low 24 bits to get @@ -1320,7 +1402,7 @@ /*********************************************************************//** * @brief - * The getFPGAVenousPressure function gets the venous arterial pressure reading. + * The getFPGAVenousPressure function gets the latest venous pressure reading. * The high 2 bits are status bits: 00=ok, 01=cmd mode, 10=stale data, 11=diag * The low 14 bits are data. Zero is at 1638. Values above are positive, * below are negative. @@ -1335,6 +1417,34 @@ /*********************************************************************//** * @brief + * The getFPGAVenousPressureTemperature function gets the latest venous pressure + * sensor temperature reading. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last venous pressure sensor temperature reading + *************************************************************************/ +F32 getFPGAVenousPressureTemperature( void ) +{ + F32 result = ( (F32)fpgaSensorReadings.venousTemperature / FPGA_PBO_TEMP_DIVISOR ) * FPGA_PBO_TEMP_GAIN - FPGA_PBO_TEMP_OFFSET; + + return result; +} + +/*********************************************************************//** + * @brief + * The getFPGAVenousPressureReadCounter function gets the latest venous pressure + * sensor read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last venous pressure sensor read counter + *************************************************************************/ +U08 getFPGAVenousPressureReadCounter( void ) +{ + return fpgaSensorReadings.venousReadCounter; +} + +/*********************************************************************//** + * @brief * The setFPGASyringePumpControlFlags function sets the syringe pump control * register per given bit flags. * @details Inputs: none Index: firmware/App/Services/FPGA.h =================================================================== diff -u -rb01c6571b1ffade6de3e0bf6890de918f4d8b47d -r74a3506d935a18d4174f94d8c0fdbc750105904f --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision b01c6571b1ffade6de3e0bf6890de918f4d8b47d) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 74a3506d935a18d4174f94d8c0fdbc750105904f) @@ -72,9 +72,17 @@ U32 getFPGAArterialPressure( void ); U16 getFPGAVenousPressure( void ); +F32 getFPGAVenousPressureTemperature( void ); +U08 getFPGAVenousPressureReadCounter( void ); U16 getFPGABloodPumpOcclusion( void ); U16 getFPGADialInPumpOcclusion( void ); U16 getFPGADialOutPumpOcclusion( void ); +U08 getFPGABloodPumpOcclusionReadCounter( void ); +U08 getFPGADialInPumpOcclusionReadCounter( void ); +U08 getFPGADialOutPumpOcclusionReadCounter( void ); +U08 getFPGABloodPumpOcclusionErrorCounter( void ); +U08 getFPGADialInPumpOcclusionErrorCounter( void ); +U08 getFPGADialOutPumpOcclusionErrorCounter( void ); void setFPGASyringePumpControlFlags( U08 bitFlags ); void setFPGASyringePumpADCandDACControlFlags( U08 bitFlags );