Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r0237b2fc49d60b6602bac35ce43831b37f294c81 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 0237b2fc49d60b6602bac35ce43831b37f294c81) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -66,12 +66,14 @@ #define BP_MAX_FLOW_RATE 1320.0 ///< Maximum measured BP flow rate allowed. #define BP_MIN_FLOW_RATE -1320.0 ///< Minimum measured BP flow rate allowed. -#define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. #define BP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< Maximum motor speed (RPM) while motor is commanded off. #define BP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define BP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< Maximum difference in speed between measured and commanded RPM. +#ifdef USE_FMB_FLOW_SENSOR +#define BP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured speed and speed implied by measured flow. /// Persist time (task intervals) for flow vs. motor speed error condition. static const U32 BP_FLOW_VS_SPEED_PERSIST = ( 5 * MS_PER_SECOND ); +#endif /// Persist time (task intervals) for motor off error condition. static const U32 BP_OFF_ERROR_PERSIST = ( 5 * MS_PER_SECOND ); /// Persist time (task intervals) motor speed error condition. @@ -106,7 +108,12 @@ #define BLOODPUMP_ADC_ZERO 1998 ///< Blood pump ADC channel zero offset. /// Macro converts 12 bit ADC value to signed 16-bit value. #define SIGN_FROM_12_BIT_VALUE(v) ( (S16)(v) - (S16)BLOODPUMP_ADC_ZERO ) + +#ifndef USE_FMB_FLOW_SENSOR /// Measured blood flow is filtered w/ moving average +#define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 1 ) +#else +/// Measured blood flow is filtered w/ moving average #define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * 10 ) /// Blood flow sensor signal strength low alarm persistence. @@ -122,6 +129,7 @@ #define BFM_SENSOR_CONNECTED_STATUS 0x00 ///< Blood flow meter connected status. #define BFM_SENSOR_PARAM_CORRUPT_STATUS 0x07 ///< Blood flow meter NVM parameter status. +#endif #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. @@ -186,9 +194,26 @@ static OVERRIDE_F32_T bloodPumpRotorSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump rotor speed. static OVERRIDE_F32_T bloodPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor speed. static OVERRIDE_F32_T adcBloodPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller speed. -static OVERRIDE_F32_T adcBloodPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller current. +static OVERRIDE_F32_T adcBloodPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood pump motor controller current. + +#ifdef USE_FMB_FLOW_SENSOR static OVERRIDE_F32_T bloodFlowSignalStrength = { 0.0, 0.0, 0.0, 0 }; ///< Measured blood flow signal strength (%). + +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. +#ifndef DISABLE_PUMP_FLOW_CHECKS +static U08 lastBloodFlowCommErrorCount = 0; ///< Previous BP flow sensor comm error count. +#endif +static HD_FLOW_SENSORS_CAL_RECORD_T bloodFlowCalRecord; ///< Blood flow sensor calibration record. +#endif + +static U08 lastBloodPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. +static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< Holds flow samples for a rolling average. +static U32 flowReadingsIdx = 0; ///< Index for next sample in rolling average array. +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 bpControlTimerCounter = 0; ///< Determines when to perform control on blood flow static U32 bpRotorRevStartTime = 0; ///< Blood pump rotor rotation start time (in ms) @@ -201,26 +226,13 @@ static U32 bpMotorSpeedCalcIdx = 0; ///< Index into 1 second buffer of motor speed hall sensor counts static U32 bpMotorSpeedCalcTimerCtr = 0; ///< Counter determines interval for calculating blood pump motor speed from hall sensor count. -static F32 flowReadings[ SIZE_OF_ROLLING_AVG ]; ///< Holds flow samples for a rolling average. -static U32 flowReadingsIdx = 0; ///< Index for next sample in rolling average array. -static F32 flowReadingsTotal = 0.0; ///< Rolling total - used to calc average. -static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. - -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 lastBloodPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. -#ifndef DISABLE_PUMP_FLOW_CHECKS -static U08 lastBloodFlowCommErrorCount = 0; ///< Previous BP flow sensor comm error count. -#endif #ifndef USE_FMB_FLOW_SENSOR static F32 bloodPCSV; ///< Calculated pressure corrected blood pump stroke volume. static F32 bloodSCSV; ///< Calculated speed corrected blood pump stroke volume. static F32 bloodPSCSV; ///< Calculated additional pressure corrected blood pump stroke volume. static F32 bloodHSWF; ///< High speed weighting factor for blood pump stroke volume calculation. static F32 bloodLSWF; ///< Low speed weighting factor for blood pump stroke volume calculation. static F32 bloodPSCSVT; ///< Pressure corrected, speed corrected blood pump stroke volume with weighted transition. -#else -static HD_FLOW_SENSORS_CAL_RECORD_T bloodFlowCalRecord; ///< Blood flow sensor calibration record. #endif // ********** private function prototypes ********** @@ -240,10 +252,11 @@ static void checkBloodPumpRotor( void ); static void checkBloodPumpDirection( void ); static void checkBloodPumpSpeeds( void ); -static void checkBloodPumpFlowAgainstSpeed( void ); static void checkBloodPumpMCCurrent( void ); -static void checkBloodFlowSensorSignalStrength( void ); +static void checkBloodPumpFlowRate( void ); + #ifdef USE_FMB_FLOW_SENSOR +static void checkBloodFlowSensorSignalStrength( void ); static BOOL processCalibrationData( void ); #else static F32 calcBloodFlow( void ); @@ -260,7 +273,7 @@ { F32 artPres = getLongFilteredArterialPressure(); F32 artPres_2 = pow( artPres, 2.0 ); - F32 motSpd = BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); // TODO - should we use measured speed? getMeasuredBloodPumpSpeed() + F32 motSpd = getMeasuredBloodPumpMCSpeed(); //BP_PWM_TO_MOTOR_SPEED_RPM( bloodPumpPWMDutyCyclePctSet ); F32 motSpd_2 = pow( motSpd, 2.0 ); F32 rotSpd = motSpd / BP_GEAR_RATIO; F32 strokeSpd = rotSpd * 2.0; // 1 rotor revolution = 2 strokes @@ -308,17 +321,19 @@ MIN_BLOOD_PUMP_PWM_DUTY_CYCLE, MAX_BLOOD_PUMP_PWM_DUTY_CYCLE ); // Initialize persistent alarm for flow sensor - initPersistentAlarm( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, 0, BP_FLOW_VS_SPEED_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_OFF_CHECK, 0, BP_OFF_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MOTOR_SPEED_CHECK, 0, BP_MOTOR_SPEED_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_CHECK, 0, BP_ROTOR_SPEED_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MC_DIRECTION_CHECK, 0, BP_DIRECTION_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_ROTOR_SPEED_TOO_HIGH, 0, BP_MAX_ROTOR_SPEED_ERROR_PERSIST ); initPersistentAlarm( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, 0, BP_MAX_CURR_ERROR_DURATION_MS ); - initPersistentAlarm( ALARM_ID_BLOOD_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); +#ifdef USE_FMB_FLOW_SENSOR + initPersistentAlarm( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, 0, BP_FLOW_VS_SPEED_PERSIST ); + 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_FAST_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BP_FLOW_SLOW_READ_TIMEOUT_ERROR, 0, BLOOD_FLOW_SLOW_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, 0, BLOOD_FLOW_COMM_ERROR_PERSIST ); +#endif initPersistentAlarm( ALARM_ID_HD_BLOOD_FLOW_OUT_OF_RANGE, 0, BP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); } @@ -526,8 +541,6 @@ // Get the new calibration data and check its validity processCalibrationData(); } -#endif - #ifndef DISABLE_PUMP_FLOW_CHECKS if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_SENSOR_ERROR, ( flowErrorCtr != lastBloodFlowCommErrorCount ) ) ) { @@ -539,7 +552,6 @@ } lastBloodFlowCommErrorCount = flowErrorCtr; #endif - #ifndef DISABLE_FPGA_COUNTER_CHECKS // Check for stale flow reading if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_BP_FLOW_READ_TIMEOUT_ERROR, ( fpReadCtr == lastBloodFlowFastPacketReadCtr ) ) ) @@ -555,14 +567,15 @@ // Record flow read counters for next time around lastBloodFlowFastPacketReadCtr = fpReadCtr; lastBloodFlowSlowPacketReadCtr = spReadCtr; +#endif 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(); #ifndef USE_FMB_FLOW_SENSOR bpFlow = calcBloodFlow(); #else + bloodFlowSignalStrength.data = getFPGABloodFlowSignalStrength(); bpFlow = pow(fpgaBloodFlow, 4) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].fourthOrderCoeff + pow(fpgaBloodFlow, 3) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].thirdOrderCoeff + pow(fpgaBloodFlow, 2) * bloodFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_BLOOD_FLOW_SENSOR ].secondOrderCoeff + @@ -583,11 +596,13 @@ checkBloodPumpMCCurrent(); // Check pump speeds and flow checkBloodPumpSpeeds(); - checkBloodPumpFlowAgainstSpeed(); + checkBloodPumpFlowRate(); // Check for home position, zero/low speed checkBloodPumpRotor(); +#ifdef USE_FMB_FLOW_SENSOR // Check flow sensor signal strength - checkBloodFlowSensorSignalStrength(); + checkBloodFlowSensorSignalStrength(); +#endif } // Publish blood flow data on interval @@ -856,6 +871,7 @@ return result; } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The getMeasuredBloodFlowSignalStrength function gets the measured blood flow @@ -875,6 +891,7 @@ return result; } +#endif /*********************************************************************//** * @brief @@ -979,7 +996,11 @@ payload.measMCSpd = getMeasuredBloodPumpMCSpeed(); payload.measMCCurr = getMeasuredBloodPumpMCCurrent(); payload.pwmDC = bloodPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; +#ifdef USE_FMB_FLOW_SENSOR payload.flowSigStrength = getMeasuredBloodFlowSignalStrength() * FRACTION_TO_PERCENT_FACTOR; +#else + payload.flowSigStrength = 0.0; +#endif broadcastData( MSG_ID_BLOOD_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( BLOOD_PUMP_STATUS_PAYLOAD_T ) ); bloodFlowDataPublicationTimerCounter = 0; } @@ -1214,16 +1235,38 @@ /*********************************************************************//** * @brief - * The checkBloodPumpFlowAgainstSpeed function checks the measured blood flow - * against the implied flow of the measured pump speed when in treatment mode - * and controlling to target flow. If a sufficient difference persists, a - * flow vs. motor speed check error is triggered. - * @details Inputs: measuredBloodFlowRate, bloodPumpSpeedRPM - * @details Outputs: alarm may be triggered + * The checkBloodPumpMCCurrent function checks the measured MC current vs. + * the set state of the blood pump (stopped or running). + * @details Inputs: + * @details Outputs: * @return none *************************************************************************/ -static void checkBloodPumpFlowAgainstSpeed( void ) +static void checkBloodPumpMCCurrent( void ) { + F32 const bpCurr = fabs( getMeasuredBloodPumpMCCurrent() ); + // Check blood pump current during off state + BOOL const isOffMCCurrentBad = ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_STOPPED_MA ); + // Check blood pump current during running state + BOOL const isRunningMCCurrentBad = ( BLOOD_PUMP_OFF_STATE != bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ); + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, isOffMCCurrentBad || isRunningMCCurrentBad ) ) + { +#ifndef DISABLE_MOTOR_CURRENT_CHECKS + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, bpCurr ); +#endif + } +} + +/*********************************************************************//** + * @brief + * The checkBloodPumpFlowRate function checks the measured blood flow rate + * is in range. + * @details Inputs: measuredBloodFlowRate + * @details Outputs: alarm may be triggered + * @return none + *************************************************************************/ +static void checkBloodPumpFlowRate( void ) +{ F32 flow = getMeasuredBloodFlowRate(); // Range check on measure BP flow rate. @@ -1234,50 +1277,29 @@ } #endif - // Flow vs. speed check only performed while in treatment mode and while we are in control to target state - if ( ( MODE_TREA == getCurrentOperationMode() ) && ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) ) - { +#ifdef USE_FMB_FLOW_SENSOR + // Flow vs. speed check only performed while in treatment mode and while we are in control to target state + if ( ( MODE_TREA == getCurrentOperationMode() ) && ( BLOOD_PUMP_CONTROL_TO_TARGET_STATE == bloodPumpState ) ) + { F32 speed = getMeasuredBloodPumpSpeed(); - F32 impliedSpeed = ( flow / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; - F32 delta = fabs( speed - impliedSpeed ); + F32 impliedSpeed = ( flow / (F32)ML_PER_LITER ) * BP_REV_PER_LITER * BP_GEAR_RATIO; + F32 delta = fabs( speed - impliedSpeed ); if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, delta > BP_MAX_FLOW_VS_SPEED_DIFF_RPM ) ) { #ifndef DISABLE_PUMP_SPEED_CHECKS SET_ALARM_WITH_2_F32_DATA( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, flow, speed ); #endif - } + } } else { - resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK ); - } -} - -/*********************************************************************//** - * @brief - * The checkBloodPumpMCCurrent function checks the measured MC current vs. - * the set state of the blood pump (stopped or running). - * @details Inputs: - * @details Outputs: - * @return none - *************************************************************************/ -static void checkBloodPumpMCCurrent( void ) -{ - F32 const bpCurr = fabs( getMeasuredBloodPumpMCCurrent() ); - // Check blood pump current during off state - BOOL const isOffMCCurrentBad = ( BLOOD_PUMP_OFF_STATE == bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_STOPPED_MA ); - // Check blood pump current during running state - BOOL const isRunningMCCurrentBad = ( BLOOD_PUMP_OFF_STATE != bloodPumpState ) && ( bpCurr > BP_MAX_CURR_WHEN_RUNNING_MA ); - - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK, isOffMCCurrentBad || isRunningMCCurrentBad ) ) - { -#ifndef DISABLE_MOTOR_CURRENT_CHECKS - SET_ALARM_WITH_1_F32_DATA( ALARM_ID_BLOOD_PUMP_MC_CURRENT_CHECK, bpCurr ); + resetPersistentAlarmTimer( ALARM_ID_BLOOD_PUMP_FLOW_VS_MOTOR_SPEED_CHECK ); + } #endif - } } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The checkBloodFlowSensorSignalStrength function checks the measured blood @@ -1305,7 +1327,6 @@ #endif } -#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The processCalibrationData function gets the calibration data and makes @@ -1351,7 +1372,8 @@ return status; } -#endif +#endif + /*********************************************************************//** * @brief * The execBloodFlowTest function executes the state machine for the @@ -1705,6 +1727,7 @@ return result; } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The testSetMeasuredBloodFlowSignalStrengthOverride function overrides the measured @@ -1749,5 +1772,6 @@ return result; } +#endif /**@}*/ Index: firmware/App/Controllers/BloodFlow.h =================================================================== diff -u -rd80c4a21ab700d8197e292f34c86dad61828c45a -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision d80c4a21ab700d8197e292f34c86dad61828c45a) +++ firmware/App/Controllers/BloodFlow.h (.../BloodFlow.h) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -68,7 +68,9 @@ SELF_TEST_STATUS_T execBloodFlowTest( void ); F32 getMeasuredBloodFlowRate( void ); +#ifdef USE_FMB_FLOW_SENSOR F32 getMeasuredBloodFlowSignalStrength( void); +#endif F32 getMeasuredBloodPumpRotorSpeed( void ); F32 getMeasuredBloodPumpSpeed( void ); F32 getMeasuredBloodPumpMCSpeed( void ); @@ -87,8 +89,10 @@ BOOL testResetMeasuredBloodPumpMCSpeedOverride( void ); BOOL testSetMeasuredBloodPumpMCCurrentOverride( F32 value ); BOOL testResetMeasuredBloodPumpMCCurrentOverride( void ); +#ifdef USE_FMB_FLOW_SENSOR BOOL testSetMeasuredBloodFlowSignalStrengthOverride( F32 value ); BOOL testResetMeasuredBloodFlowSignalStrengthOverride( void ); +#endif /**@}*/ Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -re4cc37257141c5227186ac6d8ca3d6c87d009042 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision e4cc37257141c5227186ac6d8ca3d6c87d009042) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -65,7 +65,9 @@ #define DIP_MAX_FLOW_RATE 1320.0 ///< Maximum measured BP flow rate allowed. #define DIP_MIN_FLOW_RATE -1320.0 ///< Minimum measured BP flow rate allowed. -#define DIP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured motor speed and speed implied by measured flow. +#ifdef USE_FMD_FLOW_SENSOR +#define DIP_MAX_FLOW_VS_SPEED_DIFF_RPM 200.0 ///< Maximum difference between measured motor speed and speed implied by measured flow. +#endif #define DIP_MAX_MOTOR_SPEED_WHILE_OFF_RPM 100.0 ///< Maximum motor speed (RPM) while motor is commanded off. #define DIP_MAX_ROTOR_VS_MOTOR_DIFF_RPM 5.0 ///< Maximum difference in speed between motor and rotor (in rotor RPM). #define DIP_MAX_MOTOR_SPEED_ERROR_RPM 300.0 ///< Maximum difference in speed between measured and commanded RPM. @@ -109,6 +111,7 @@ /// Measured dialIn flow is filtered w/ moving average. #define SIZE_OF_ROLLING_AVG ( ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) * DIP_CONTROL_INTERVAL_SEC ) +#ifdef USE_FMD_FLOW_SENSOR /// Dialysate flow sensor signal strength low alarm persistence. #define FLOW_SIG_STRGTH_ALARM_PERSIST ( 5 * MS_PER_SECOND ) #define MIN_FLOW_SIG_STRENGTH 0.9 ///< Minimum flow sensor signal strength (90%). @@ -122,6 +125,7 @@ #define DFM_SENSOR_CONNECTED_STATUS 0x00 ///< Dialysate flow meter connected status. #define DFM_SENSOR_PARAM_CORRUPT_STATUS 0x07 ///< Dialysate flow meter NVM parameter corrupt status. +#endif #define PUMP_DIR_ERROR_COUNT_MASK 0x3F ///< Bit mask for pump direction error counter. @@ -173,7 +177,18 @@ static OVERRIDE_F32_T dialInPumpSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor speed static OVERRIDE_F32_T adcDialInPumpMCSpeedRPM = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor controller speed static OVERRIDE_F32_T adcDialInPumpMCCurrentmA = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate inlet pump motor controller current +#ifdef USE_FMD_FLOW_SENSOR static OVERRIDE_F32_T dialInFlowSignalStrength = { 0.0, 0.0, 0.0, 0 }; ///< Measured dialysate flow signal strength (%) + +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. +#ifndef DISABLE_PUMP_FLOW_CHECKS +static U08 lastDialysateFlowCommErrorCount = 0; ///< Previous DPi flow sensor comm error count. +#endif +static HD_FLOW_SENSORS_CAL_RECORD_T dialysateFlowCalRecord; ///< Dialysate flow sensor calibration record. +#endif + +static U08 lastDialInPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. static U32 dipControlTimerCounter = 0; ///< Determines when to perform control on dialIn flow @@ -197,14 +212,6 @@ static U32 flowReadingsCount = 0; ///< Number of samples in flow rolling average buffer. 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 lastDialInPumpDirectionCount = 0; ///< Previous pump direction error count reported by FPGA. -#ifndef DISABLE_PUMP_FLOW_CHECKS -static U08 lastDialysateFlowCommErrorCount = 0; ///< Previous DPi flow sensor comm error count. -#endif -static HD_FLOW_SENSORS_CAL_RECORD_T dialysateFlowCalRecord; ///< Dialysate flow sensor calibration record. // ********** private function prototypes ********** @@ -223,10 +230,12 @@ static void checkDialInPumpRotor( void ); static void checkDialInPumpDirection( void ); static void checkDialInPumpSpeeds( void ); -static void checkDialInPumpFlowAgainstSpeed( void ); static void checkDialInPumpMCCurrent( void ); +static void checkDialInPumpFlowRate( void ); +#ifdef USE_FMD_FLOW_SENSOR static void checkDialInFlowSensorSignalStrength( void ); static BOOL processCalibrationData( void ); +#endif /*********************************************************************//** * @brief @@ -258,10 +267,12 @@ MIN_DIAL_IN_PUMP_PWM_DUTY_CYCLE, MAX_DIAL_IN_PUMP_PWM_DUTY_CYCLE ); // Initialize persistent alarm for flow sensor signal strength too low +#ifdef USE_FMD_FLOW_SENSOR initPersistentAlarm( ALARM_ID_DIALYSATE_FLOW_SIGNAL_STRENGTH_TOO_LOW, FLOW_SIG_STRGTH_ALARM_PERSIST, FLOW_SIG_STRGTH_ALARM_PERSIST ); initPersistentAlarm( ALARM_ID_HD_DP_FLOW_READ_TIMEOUT_ERROR, 0, DIALYSATE_FLOW_FAST_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_DP_FLOW_SLOW_READ_TIMEOUT_ERROR, 0, DIALYSATE_FLOW_SLOW_READ_TO_PERSIST ); initPersistentAlarm( ALARM_ID_HD_DP_FLOW_SENSOR_ERROR, 0, DIALYSATE_FLOW_COMM_ERROR_PERSIST ); +#endif initPersistentAlarm( ALARM_ID_HD_DIAL_IN_FLOW_OUT_OF_RANGE, 0, DIP_MAX_FLOW_RATE_OUT_OF_RANGE_PERSIST ); } @@ -422,27 +433,28 @@ *************************************************************************/ void execDialInFlowMonitor( void ) { - // Check if a new calibration is available - if ( TRUE == isNewCalibrationRecordAvailable() ) - { - // Get the new calibration data and check its validity - processCalibrationData(); - } - 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 ); U08 fpReadCtr = getFPGADialysateFlowFastPacketReadCounter(); U08 spReadCtr = getFPGADialysateFlowSlowPacketReadCounter(); U08 flowErrorCtr = getFPGADialysateFlowErrorCounter(); U08 flowStatus = getFPGADialysateFlowMeterStatus(); + F32 dipFlow; +#ifdef USE_FMD_FLOW_SENSOR + F32 dpFlow = getFPGADialysateFlow(); - F32 fpgaDialysateFlow = getFPGADialysateFlow(); - F32 dipFlow = pow(fpgaDialysateFlow, 4) * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].fourthOrderCoeff + - pow(fpgaDialysateFlow, 3) * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].thirdOrderCoeff + - pow(fpgaDialysateFlow, 2) * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].secondOrderCoeff + - fpgaDialysateFlow * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].gain + - dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].offset; + // Check if a new calibration is available + if ( TRUE == isNewCalibrationRecordAvailable() ) + { + // Get the new calibration data and check its validity + processCalibrationData(); + } + dipFlow = pow(dpFlow, 4) * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].fourthOrderCoeff + + pow(dpFlow, 3) * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].thirdOrderCoeff + + pow(dpFlow, 2) * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].secondOrderCoeff + + dpFlow * dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].gain + + dialysateFlowCalRecord.hdFlowSensors[ CAL_DATA_HD_DIALYSATE_FLOW_SENSOR ].offset; #ifndef DISABLE_PUMP_FLOW_CHECKS if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_DP_FLOW_SENSOR_ERROR, ( flowErrorCtr != lastDialysateFlowCommErrorCount ) ) ) @@ -471,10 +483,14 @@ // Record flow read counters for next time around lastDialysateFlowFastPacketReadCtr = fpReadCtr; lastDialysateFlowSlowPacketReadCtr = spReadCtr; + + dialInFlowSignalStrength.data = getFPGADialysateFlowSignalStrength(); +#else + dipFlow = 0.0; // TODO - get dialysate flow from DG +#endif 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; - dialInFlowSignalStrength.data = getFPGADialysateFlowSignalStrength(); filterDialInFlowReadings( dipFlow ); @@ -490,11 +506,12 @@ checkDialInPumpMCCurrent(); // Check pump speeds and flow checkDialInPumpSpeeds(); - checkDialInPumpFlowAgainstSpeed(); + checkDialInPumpFlowRate(); +#ifdef USE_FMD_FLOW_SENSOR + checkDialInFlowSensorSignalStrength(); +#endif // Check for home position, zero/low speed checkDialInPumpRotor(); - // Check flow sensor signal strength - checkDialInFlowSensorSignalStrength(); } // Publish dialIn flow data on interval @@ -743,6 +760,7 @@ } } +#ifdef USE_FMD_FLOW_SENSOR /*********************************************************************//** * @brief * The processCalibrationData function gets the calibration data and makes @@ -788,6 +806,7 @@ return status; } +#endif /*********************************************************************//** * @brief @@ -822,6 +841,7 @@ return result; } +#ifdef USE_FMD_FLOW_SENSOR /*********************************************************************//** * @brief * The getMeasuredDialInFlowSignalStrength function gets the measured dialIn flow @@ -841,6 +861,7 @@ return result; } +#endif /*********************************************************************//** * @brief @@ -966,7 +987,11 @@ payload.measMCSpd = getMeasuredDialInPumpMCSpeed(); payload.measMCCurr = getMeasuredDialInPumpMCCurrent(); payload.pwmDC = dialInPumpPWMDutyCyclePctSet * FRACTION_TO_PERCENT_FACTOR; +#ifdef USE_FMD_FLOW_SENSOR payload.flowSigStrength = getMeasuredDialInFlowSignalStrength() * FRACTION_TO_PERCENT_FACTOR; +#else + payload.flowSigStrength = 0.0; +#endif broadcastData( MSG_ID_DIALYSATE_FLOW_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&payload, sizeof( DIALIN_PUMP_STATUS_PAYLOAD_T ) ); dialInFlowDataPublicationTimerCounter = 0; } @@ -1224,15 +1249,13 @@ /*********************************************************************//** * @brief - * The checkDialInPumpFlowAgainstSpeed function checks the measured dialysate flow - * against the implied flow of the measured pump speed when in treatment mode - * and controlling to target flow. If a sufficient difference persists, a - * flow vs. motor speed check error is triggered. - * @details Inputs: measuredDialInFlowRate, dialInPumpSpeedRPM, errorDialInFlowVsMotorSpeedPersistTimerCtr + * The checkDialInPumpFlowRate function checks the measured dialysate flow + * rate is in range. + * @details Inputs: measuredDialInFlowRate * @details Outputs: alarm may be triggered * @return none *************************************************************************/ -static void checkDialInPumpFlowAgainstSpeed( void ) +static void checkDialInPumpFlowRate( void ) { F32 flow = getMeasuredDialInFlowRate(); @@ -1244,6 +1267,7 @@ } #endif +#ifdef USE_FMD_FLOW_SENSOR // Check only performed while in treatment mode and while we are in control to target state if ( ( MODE_TREA == getCurrentOperationMode() ) && ( DIAL_IN_PUMP_CONTROL_TO_TARGET_STATE == dialInPumpState ) ) { @@ -1269,7 +1293,8 @@ else { errorDialInFlowVsMotorSpeedPersistTimerCtr = 0; - } + } +#endif } /*********************************************************************//** @@ -1324,6 +1349,7 @@ } } +#ifdef USE_FMD_FLOW_SENSOR /*********************************************************************//** * @brief * The checkDialInFlowSensorSignalStrength function checks the measured @@ -1350,6 +1376,7 @@ } #endif } +#endif /*********************************************************************//** * @brief @@ -1361,6 +1388,7 @@ *************************************************************************/ SELF_TEST_STATUS_T execDialInFlowTest( void ) { +#ifdef USE_FMD_FLOW_SENSOR SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; U08 const dfmStatus = getFPGADialysateFlowMeterStatus(); @@ -1381,6 +1409,9 @@ { SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_DIALYSATE_FLOW_STATUS_SELF_TEST_FAILURE, (U32)dfmStatus ); } +#else + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_PASSED; +#endif return result; } @@ -1699,6 +1730,7 @@ return result; } +#ifdef USE_FMD_FLOW_SENSOR /*********************************************************************//** * @brief * The testSetMeasuredDialInFlowSignalStrengthOverride function overrides the measured @@ -1743,5 +1775,6 @@ return result; } +#endif /**@}*/ Index: firmware/App/Controllers/DialInFlow.h =================================================================== diff -u -r50fc6ca962c381ac98c9f032115973a5fff2a761 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 50fc6ca962c381ac98c9f032115973a5fff2a761) +++ firmware/App/Controllers/DialInFlow.h (.../DialInFlow.h) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -63,8 +63,10 @@ SELF_TEST_STATUS_T execDialInFlowTest( void ); S32 getTargetDialInFlowRate( void ); -F32 getMeasuredDialInFlowRate( void ); +F32 getMeasuredDialInFlowRate( void ); +#ifdef USE_FMD_FLOW_SENSOR F32 getMeasuredDialInFlowSignalStrength( void ); +#endif F32 getMeasuredDialInPumpRotorSpeed( void ); F32 getMeasuredDialInPumpSpeed( void ); F32 getMeasuredDialInPumpMCSpeed( void ); @@ -84,8 +86,10 @@ BOOL testResetMeasuredDialInPumpMCSpeedOverride( void ); BOOL testSetMeasuredDialInPumpMCCurrentOverride( F32 value ); BOOL testResetMeasuredDialInPumpMCCurrentOverride( void ); +#ifdef USE_FMD_FLOW_SENSOR BOOL testSetMeasuredDialInFlowSignalStrengthOverride( F32 value ); BOOL testResetMeasuredDialInFlowSignalStrengthOverride( void ); +#endif /**@}*/ Index: firmware/App/HDCommon.h =================================================================== diff -u -r0237b2fc49d60b6602bac35ce43831b37f294c81 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 0237b2fc49d60b6602bac35ce43831b37f294c81) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -46,8 +46,9 @@ // #define DISABLE_ACCELS 1 // Disable accelerometer POST and monitoring // #define DISABLE_CRC_ERROR 1 // Do not error on bad CRC for CAN messages #define DISABLE_ACK_ERRORS 1 // Do not error on failure of other node(s) to ACK a message - #define USE_FMB_FLOW_SENSOR 1 // Use FMB flow sensor instead of flow estimation from pump speed/pressure/wearing - #define RUN_BP_OPEN_LOOP 1 // Run blood pump in open loop mode +// #define USE_FMD_FLOW_SENSOR 1 // Use FMD flow sensor (on HD) instead of FMD on DG +// #define USE_FMB_FLOW_SENSOR 1 // Use FMB flow sensor instead of flow estimation from pump speed/pressure/wearing +// #define RUN_BP_OPEN_LOOP 1 // Run blood pump in open loop mode #define DISABLE_MOTOR_CURRENT_CHECKS 1 // Do not error on HD pump current checks #define DISABLE_PUMP_FLOW_CHECKS 1 // Do not error on HD pump flow checks #define DISABLE_PUMP_SPEED_CHECKS 1 // Do not error on HD pump speed checks Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r0237b2fc49d60b6602bac35ce43831b37f294c81 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 0237b2fc49d60b6602bac35ce43831b37f294c81) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -1515,14 +1515,16 @@ handleHDSoftwareResetRequest( message ); break; +#ifdef USE_FMB_FLOW_SENSOR case MSG_ID_BLOOD_FLOW_SIG_STRENGTH_OVERRIDE: handleTestBloodFlowSignalStrengthOverrideRequest( message ); break; - +#endif +#ifdef USE_FMD_FLOW_SENSOR case MSG_ID_DIAL_IN_FLOW_SIG_STRENGTH_OVERRIDE: handleTestDialInFlowSignalStrengthOverrideRequest( message ); break; - +#endif case MSG_ID_BLOOD_PUMP_HOME_CMD: handleTestBloodPumpHomeRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r0237b2fc49d60b6602bac35ce43831b37f294c81 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 0237b2fc49d60b6602bac35ce43831b37f294c81) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -383,7 +383,7 @@ memcpy( payloadPtr, &dat2, sizeof( EVENT_DATA_T ) ); // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer - result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_REQUIRED ); + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_HD_2_UI, ACK_NOT_REQUIRED ); return result; } @@ -3556,6 +3556,7 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +#ifdef USE_FMB_FLOW_SENSOR /*********************************************************************//** * @brief * The handleTestBloodFlowSignalStrengthOverrideRequest function handles a @@ -3587,6 +3588,7 @@ // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +#endif /*********************************************************************//** * @brief @@ -3830,6 +3832,7 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +#ifdef USE_FMD_FLOW_SENSOR /*********************************************************************//** * @brief * The handleTestDialInFlowSignalStrengthOverrideRequest function handles a @@ -3861,6 +3864,7 @@ // Respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +#endif /*********************************************************************//** * @brief Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r0237b2fc49d60b6602bac35ce43831b37f294c81 -r5070f8552a200e15dcc2ca0532db10fba9dc8c6b --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 0237b2fc49d60b6602bac35ce43831b37f294c81) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 5070f8552a200e15dcc2ca0532db10fba9dc8c6b) @@ -436,8 +436,10 @@ // MSG_ID_BLOOD_FLOW_MEAS_OVERRIDE void handleTestBloodFlowMeasuredOverrideRequest( MESSAGE_T *message ); +#ifdef USE_FMB_FLOW_SENSOR // MSG_ID_BLOOD_FLOW_SIG_STRENGTH_OVERRIDE void handleTestBloodFlowSignalStrengthOverrideRequest( MESSAGE_T *message ); +#endif // MSG_ID_BLOOD_PUMP_MC_MEAS_SPEED_OVERRIDE void handleTestBloodPumpMCMeasuredSpeedOverrideRequest( MESSAGE_T *message ); @@ -463,8 +465,10 @@ // MSG_ID_DIAL_IN_FLOW_MEAS_OVERRIDE void handleTestDialInFlowMeasuredOverrideRequest( MESSAGE_T *message ); +#ifdef USE_FMD_FLOW_SENSOR // MSG_ID_DIAL_IN_FLOW_SIG_STRENGTH_OVERRIDE void handleTestDialInFlowSignalStrengthOverrideRequest( MESSAGE_T *message ); +#endif // MSG_ID_DIAL_IN_PUMP_MC_MEAS_SPEED_OVERRIDE void handleTestDialInPumpMCMeasuredSpeedOverrideRequest( MESSAGE_T *message );