Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r6fcdec8a308be986e5a64b4222918e718622a19d -r794f0aea88a5a860448e54e99db6e2e881b22900 --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 6fcdec8a308be986e5a64b4222918e718622a19d) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 794f0aea88a5a860448e54e99db6e2e881b22900) @@ -110,27 +110,39 @@ #define FLOW_SIG_STRGTH_ALARM_PERSIST ( 5 * MS_PER_SECOND ) #define MIN_FLOW_SIG_STRENGTH 0.9 ///< Minimum flow sensor signal strength (90%). +/// Blood flow read timeout alarm persistence. +#define BLOOD_FLOW_READ_TIMEOUT_PERSIST ( MS_PER_SECOND ) + #define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x7 ///< Blood flow meter NVM parameter status. /// Enumeration of blood pump controller states. typedef enum BloodPump_States { - BLOOD_PUMP_OFF_STATE = 0, ///< Blood pump off state. - BLOOD_PUMP_RAMPING_UP_STATE, ///< Blood pump ramping up state. - BLOOD_PUMP_RAMPING_DOWN_STATE, ///< Blood pump ramping down state. - BLOOD_PUMP_CONTROL_TO_TARGET_STATE, ///< Blood pump controlling to target state. - NUM_OF_BLOOD_PUMP_STATES ///< Number of blood pump states. + BLOOD_PUMP_OFF_STATE = 0, ///< Blood pump off state + BLOOD_PUMP_RAMPING_UP_STATE, ///< Blood pump ramping up state + BLOOD_PUMP_RAMPING_DOWN_STATE, ///< Blood pump ramping down state + BLOOD_PUMP_CONTROL_TO_TARGET_STATE, ///< Blood pump controlling to target state + NUM_OF_BLOOD_PUMP_STATES ///< Number of blood pump states } BLOOD_PUMP_STATE_T; /// Enumeration of blood pump self-test states. typedef enum BloodFlow_Self_Test_States { - BLOOD_FLOW_SELF_TEST_STATE_START = 0, ///< Blood pump self-test start state. - BLOOD_FLOW_TEST_STATE_IN_PROGRESS, ///< Blood pump self-test in progress state. - BLOOD_FLOW_TEST_STATE_COMPLETE, ///< Blood pump self-test completed state. - NUM_OF_BLOOD_FLOW_SELF_TEST_STATES ///< Number of blood pump self-test states. + BLOOD_FLOW_SELF_TEST_STATE_START = 0, ///< Blood pump self-test start state + BLOOD_FLOW_TEST_STATE_IN_PROGRESS, ///< Blood pump self-test in progress state + BLOOD_FLOW_TEST_STATE_COMPLETE, ///< Blood pump self-test completed state + NUM_OF_BLOOD_FLOW_SELF_TEST_STATES ///< Number of blood pump self-test states } BLOOD_FLOW_SELF_TEST_STATE_T; +/// Enumeration of blood flow read counters. +typedef enum BloodFlow_Read_Counters +{ + BLOOD_FLOW_READ_CTR_FAST_PACKET = 0, ///< Blood flow fast packet read counter + BLOOD_FLOW_READ_CTR_SLOW_PACKET, ///< Blood flow slow packet read counter + BLOOD_FLOW_READ_CTR_STATUS_PACKET, ///< Blood flow status packet read counter + NUM_OF_BLOOD_FLOW_READ_COUNTERS ///< Number of blood pump read counters. +} BLOOD_FLOW_READ_COUNTER_T; + // Pin assignments for pump stop and direction outputs #define STOP_CAN3_PORT_MASK 0x00000002 // (Tx - re-purposed as output GPIO for blood pump stop signal) #define DIR_CAN3_PORT_MASK 0x00000002 // (Rx - re-purposed as output GPIO for blood pump direction signal) @@ -188,7 +200,11 @@ static F32 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer -static U32 bpCurrErrorDurationCtr = 0; ///< Used for tracking persistence of bp current errors +static U32 bpCurrErrorDurationCtr = 0; ///< Used for tracking persistence of bp current errors + +static U08 lastBloodFlowFastPacketReadCtr = 0; ///< Previous read counter for the blood flow fast packets +static U08 lastBloodFlowSlowPacketReadCtr = 0; ///< Previous read counter for the blood flow slow packets +static U08 lastBloodFlowStatusPacketReadCtr = 0; ///< Previous read counter for the blood flow status packets // ********** private function prototypes ********** @@ -243,6 +259,7 @@ // Initialize persistent alarm for flow sensor signal strength too low initPersistentAlarm( ALARM_ID_BLOOD_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); + initPersistentAlarm( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_READ_TIMEOUT_PERSIST ); } /*********************************************************************//** @@ -430,13 +447,35 @@ HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 bpRPM = getIntADCReading( INT_ADC_BLOOD_PUMP_SPEED ); U16 bpmA = getIntADCReading( INT_ADC_BLOOD_PUMP_MOTOR_CURRENT ); - #ifndef V1_5_SYSTEM F32 bpFlow = ( getFPGABloodFlow() * bloodFlowCalGain ) + bloodFlowCalOffset; #else - F32 bpFlow = ( ( getFPGABloodFlow() * -1.0 ) * bloodFlowCalGain ) + bloodFlowCalOffset; // Blood flow sensor installed backwards on HD + F32 bpFlow = ( ( getFPGABloodFlow() * -1.0 ) * bloodFlowCalGain ) + bloodFlowCalOffset; // Blood flow sensor installed backwards on HD #endif - + U08 fpReadCtr = getFPGABloodFlowFastPacketReadCounter(); + U08 spReadCtr = getFPGABloodFlowSlowPacketReadCounter(); + U08 stpReadCtr = getFPGABloodFlowStatusPacketReadCounter(); + U08 flowErrorCtr = getFPGABloodFlowErrorCounter(); + + // Check for stale flow reading + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( fpReadCtr == lastBloodFlowFastPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, (U32)BLOOD_FLOW_READ_CTR_FAST_PACKET ) + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( spReadCtr == lastBloodFlowSlowPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, (U32)BLOOD_FLOW_READ_CTR_SLOW_PACKET ) + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( stpReadCtr == lastBloodFlowStatusPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, (U32)BLOOD_FLOW_READ_CTR_STATUS_PACKET ) + } + + // Record flow read counters for next time around + lastBloodFlowFastPacketReadCtr = fpReadCtr; + lastBloodFlowSlowPacketReadCtr = spReadCtr; + lastBloodFlowStatusPacketReadCtr = stpReadCtr; + adcBloodPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpRPM)) * BP_SPEED_ADC_TO_RPM_FACTOR; adcBloodPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(bpmA)) * BP_CURRENT_ADC_TO_MA_FACTOR; bloodFlowSignalStrength.data = getFPGABloodFlowSignalStrength(); @@ -465,6 +504,7 @@ // Publish blood flow data on interval publishBloodFlowData(); } +//ALARM_ID_HD_BP_FLOW_SENSOR_ERROR = 208, ///< HD blood flow sensor error /*********************************************************************//** * @brief Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r6fcdec8a308be986e5a64b4222918e718622a19d -r794f0aea88a5a860448e54e99db6e2e881b22900 --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 6fcdec8a308be986e5a64b4222918e718622a19d) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 794f0aea88a5a860448e54e99db6e2e881b22900) @@ -112,6 +112,9 @@ #define FLOW_SIG_STRGTH_ALARM_PERSIST ( 5 * MS_PER_SECOND ) #define MIN_FLOW_SIG_STRENGTH 0.9 ///< Minimum flow sensor signal strength (90%). +/// Dialysate flow read timeout alarm persistence. +#define DIALYSATE_FLOW_READ_TIMEOUT_PERSIST ( MS_PER_SECOND ) + #define DFM_SENSOR_PARAM_CORRUPT_STATUS 0x7 ///< Dialysate flow meter NVM parameter corrupt status. /// Enumeration of dialysate inlet pump states. @@ -133,6 +136,15 @@ NUM_OF_DIAL_IN_FLOW_SELF_TEST_STATES ///< Number of dialysate inlet pump self-test states. } DIAL_IN_FLOW_SELF_TEST_STATE_T; +/// Enumeration of dialysate flow read counters. +typedef enum DialysateFlow_Read_Counters +{ + DIALYSATE_FLOW_READ_CTR_FAST_PACKET = 0, ///< Dialysate flow fast packet read counter + DIALYSATE_FLOW_READ_CTR_SLOW_PACKET, ///< Dialysate flow slow packet read counter + DIALYSATE_FLOW_READ_CTR_STATUS_PACKET, ///< Dialysate flow status packet read counter + NUM_OF_DIALYSATE_FLOW_READ_COUNTERS ///< Number of dialysate flow read counters. +} DIALYSATE_FLOW_READ_COUNTER_T; + // Pin assignments for pump stop and direction outputs #define STOP_DI_PUMP_GIO_PORT_PIN 2U ///< Pin # on GIO A for stopping the dialysate inlet pump. #define DIR_DI_PUMP_SPI5_PORT_MASK 0x00000100 ///< Pin on unused SPI5 peripheral (ENA) - re-purposed as output GPIO to set dialysate inlet pump direction. @@ -189,6 +201,10 @@ static U32 dipCurrErrorDurationCtr = 0; ///< Used for tracking persistence of dip current errors +static U08 lastDialysateFlowFastPacketReadCtr = 0; ///< Previous read counter for the dialysate flow fast packets +static U08 lastDialysateFlowSlowPacketReadCtr = 0; ///< Previous read counter for the dialysate flow slow packets +static U08 lastDialysateFlowStatusPacketReadCtr = 0; ///< Previous read counter for the dialysate flow status packets + // ********** private function prototypes ********** static DIAL_IN_PUMP_STATE_T handleDialInPumpOffState( void ); @@ -242,6 +258,7 @@ // Initialize persistent alarm for flow sensor signal strength too low initPersistentAlarm( ALARM_ID_DIALYSATE_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); + initPersistentAlarm( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, 0, DIALYSATE_FLOW_READ_TIMEOUT_PERSIST ); } /*********************************************************************//** @@ -400,7 +417,30 @@ HD_OP_MODE_T opMode = getCurrentOperationMode(); U16 dipRPM = getIntADCReading( INT_ADC_DIAL_IN_PUMP_SPEED ); U16 dipmA = getIntADCReading( INT_ADC_DIAL_IN_PUMP_MOTOR_CURRENT ); - F32 dipFlow = ( getFPGADialysateFlow() * dialInFlowCalGain ) + dialInFlowCalOffset; + F32 dipFlow = ( getFPGADialysateFlow() * dialInFlowCalGain ) + dialInFlowCalOffset; + U08 fpReadCtr = getFPGADialysateFlowFastPacketReadCounter(); + U08 spReadCtr = getFPGADialysateFlowSlowPacketReadCounter(); + U08 stpReadCtr = getFPGADialysateFlowStatusPacketReadCounter(); + U08 flowErrorCtr = getFPGADialysateFlowErrorCounter(); + + // Check for stale flow reading + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, ( fpReadCtr == lastDialysateFlowFastPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, (U32)DIALYSATE_FLOW_READ_CTR_FAST_PACKET ) + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, ( spReadCtr == lastDialysateFlowSlowPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, (U32)DIALYSATE_FLOW_READ_CTR_SLOW_PACKET ) + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, ( stpReadCtr == lastDialysateFlowStatusPacketReadCtr ) ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, (U32)DIALYSATE_FLOW_READ_CTR_STATUS_PACKET ) + } + + // Record flow read counters for next time around + lastDialysateFlowFastPacketReadCtr = fpReadCtr; + lastDialysateFlowSlowPacketReadCtr = spReadCtr; + lastDialysateFlowStatusPacketReadCtr = stpReadCtr; adcDialInPumpMCSpeedRPM.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipRPM)) * DIP_SPEED_ADC_TO_RPM_FACTOR; adcDialInPumpMCCurrentmA.data = (F32)(SIGN_FROM_12_BIT_VALUE(dipmA)) * DIP_CURRENT_ADC_TO_MA_FACTOR; @@ -430,6 +470,7 @@ // Publish dialIn flow data on interval publishDialInFlowData(); } +//ALARM_ID_HD_DP_FLOW_SENSOR_ERROR = 210, ///< HD dialysate flow sensor error /*********************************************************************//** * @brief @@ -1235,7 +1276,7 @@ // Get the flow sensors calibration record HD_FLOW_SENSORS_CAL_RECORD_T cal = getHDFlowSensorsCalibrationRecord(); - if ( DFM_SENSOR_PARAM_CORRUPT_STATUS != dfmStatus ) + if ( DFM_SENSOR_PARAM_CORRUPT_STATUS != dfmStatus ) { dialInFlowCalGain = cal.hdFlowSensors[ CAL_DATA_HD_DIALYZER_FLOW_SENSOR ].gain; dialInFlowCalOffset = cal.hdFlowSensors[ CAL_DATA_HD_DIALYZER_FLOW_SENSOR ].offset; Index: firmware/App/Services/FPGA.c =================================================================== diff -u -r74a3506d935a18d4174f94d8c0fdbc750105904f -r794f0aea88a5a860448e54e99db6e2e881b22900 --- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 74a3506d935a18d4174f94d8c0fdbc750105904f) +++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision 794f0aea88a5a860448e54e99db6e2e881b22900) @@ -1139,30 +1139,82 @@ /*********************************************************************//** * @brief - * The getFPGADialysateFlow function gets the latest dialysate flow reading. + * The getFPGABloodFlowMeterStatus function gets the blood flow meter status. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return last dialysate flow reading + * @return current blood flow meter status *************************************************************************/ -F32 getFPGADialysateFlow( void ) +U08 getFPGABloodFlowMeterStatus( void ) { - return fpgaSensorReadings.dialysateFlowLast; + return fpgaSensorReadings.bloodFlowMeterDeviceStatus; } /*********************************************************************//** * @brief - * The getFPGABloodFlowMeterStatus function gets the blood flow meter status. + * The getFPGABloodFlowFastPacketReadCounter function gets the blood + * flow meter fast packet read counter. * @details Inputs: fpgaSensorReadings * @details Outputs: none - * @return current blood flow meter status + * @return current blood flow meter fast packet read counter *************************************************************************/ -U08 getFPGABloodFlowMeterStatus( void ) +U08 getFPGABloodFlowFastPacketReadCounter( void ) { - return fpgaSensorReadings.bloodFlowMeterDeviceStatus; + return fpgaSensorReadings.bloodFlowMeterDataPktCount; } /*********************************************************************//** * @brief + * The getFPGABloodFlowSlowPacketReadCounter function gets the blood + * flow meter slow packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current blood flow meter slow packet read counter + *************************************************************************/ +U08 getFPGABloodFlowSlowPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.bloodFlowMeterSlowPktCounts & MASK_OFF_NIBBLE_LSB ) >> SHIFT_BITS_BY_4; +} + +/*********************************************************************//** + * @brief + * The getFPGABloodFlowStatusPacketReadCounter function gets the blood + * flow meter status packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current blood flow meter status packet read counter + *************************************************************************/ +U08 getFPGABloodFlowStatusPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.bloodFlowMeterSlowPktCounts & MASK_OFF_NIBBLE_MSB ); +} + +/*********************************************************************//** + * @brief + * The getFPGABloodFlowErrorCounter function gets the blood flow meter + * error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current blood flow meter error counter + *************************************************************************/ +U08 getFPGABloodFlowErrorCounter( void ) +{ + return fpgaSensorReadings.bloodFlowMeterErrorCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlow function gets the latest dialysate flow reading. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return last dialysate flow reading + *************************************************************************/ +F32 getFPGADialysateFlow( void ) +{ + return fpgaSensorReadings.dialysateFlowLast; +} + +/*********************************************************************//** + * @brief * The getFPGADialysateFlowMeterStatus function gets the dialysate flow meter status. * @details Inputs: fpgaSensorReadings * @details Outputs: none @@ -1175,6 +1227,58 @@ /*********************************************************************//** * @brief + * The getFPGADialysateFlowFastPacketReadCounter function gets the dialysate + * flow meter fast packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter fast packet read counter + *************************************************************************/ +U08 getFPGADialysateFlowFastPacketReadCounter( void ) +{ + return fpgaSensorReadings.dialysateFlowMeterDataPktCount; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowSlowPacketReadCounter function gets the dialysate + * flow meter slow packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter slow packet read counter + *************************************************************************/ +U08 getFPGADialysateFlowSlowPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.dialysateFlowMeterSlowPckCounts & MASK_OFF_NIBBLE_LSB ) >> SHIFT_BITS_BY_4; +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowStatusPacketReadCounter function gets the dialysate + * flow meter status packet read counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter status packet read counter + *************************************************************************/ +U08 getFPGADialysateFlowStatusPacketReadCounter( void ) +{ + return ( fpgaSensorReadings.dialysateFlowMeterSlowPckCounts & MASK_OFF_NIBBLE_MSB ); +} + +/*********************************************************************//** + * @brief + * The getFPGADialysateFlowErrorCounter function gets the dialysate flow meter + * error counter. + * @details Inputs: fpgaSensorReadings + * @details Outputs: none + * @return current dialysate flow meter error counter + *************************************************************************/ +U08 getFPGADialysateFlowErrorCounter( void ) +{ + return fpgaSensorReadings.dialysateFlowMeterErrorCount; +} + +/*********************************************************************//** + * @brief * The getFPGABloodPumpHallSensorCount function gets the latest blood pump * hall sensor count. Count is a 16 bit free running counter. If counter is * counting up, indicates motor is running in forward direction. If counter is Index: firmware/App/Services/FPGA.h =================================================================== diff -u -r74a3506d935a18d4174f94d8c0fdbc750105904f -r794f0aea88a5a860448e54e99db6e2e881b22900 --- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 74a3506d935a18d4174f94d8c0fdbc750105904f) +++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision 794f0aea88a5a860448e54e99db6e2e881b22900) @@ -58,10 +58,18 @@ F32 getFPGADialysateFlowSignalStrength( void ); F32 getFPGABloodFlow( void ); -F32 getFPGADialysateFlow( void ); - U08 getFPGABloodFlowMeterStatus( void ); +U08 getFPGABloodFlowFastPacketReadCounter( void ); +U08 getFPGABloodFlowSlowPacketReadCounter( void ); +U08 getFPGABloodFlowStatusPacketReadCounter( void ); +U08 getFPGABloodFlowErrorCounter( void ); + +F32 getFPGADialysateFlow( void ); U08 getFPGADialysateFlowMeterStatus( void ); +U08 getFPGADialysateFlowFastPacketReadCounter( void ); +U08 getFPGADialysateFlowSlowPacketReadCounter( void ); +U08 getFPGADialysateFlowStatusPacketReadCounter( void ); +U08 getFPGADialysateFlowErrorCounter( void ); U16 getFPGABloodPumpHallSensorCount( void ); U08 getFPGABloodPumpHallSensorStatus( void );