Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -ra4d23db9510f983eab3af863d6470263a59ea937 -rd37f31cff6c20085953ecb598558e4d91e42f0af --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision a4d23db9510f983eab3af863d6470263a59ea937) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision d37f31cff6c20085953ecb598558e4d91e42f0af) @@ -90,7 +90,7 @@ #define FIVE_PCT_OVER_ALLOWANCE 1.05 ///< Allow 5 percent over target before alarming on over travel. /// Expected position of empty in relation to home position. -#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) +#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) ///< get syringe volume from home to empty (11 mL is placeholder) /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) /// Minimum retract position. @@ -125,6 +125,8 @@ // Stepper motor toggle time for zero speed (stopped) #define SYRINGE_PUMP_MICROSTEP_TOGGLE_TIME_FOR_STOP 0xFFFFFFFF ///< Syringe pump microstep toggle time setting to indicate zero speed (stopped). +#define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. + /// Control bits to run syringe pump in reverse direction static const U08 SYRINGE_PUMP_CONTROL_RUN_REVERSE = SYRINGE_PUMP_CONTROL_SLEEP_OFF | SYRINGE_PUMP_CONTROL_NOT_RESET | @@ -198,10 +200,8 @@ static S32 syringePumpLastPositions[ SYRINGE_PUMP_SPEED_CALC_BUFFER_LEN ]; ///< Last encoder positions for the syringe pump. static U32 syringePumpMotorSpeedCalcIdx; ///< Index into 1 second buffer of syringe pump encoder positions. static U32 syringePumpSpeedCalcTimerCounter; ///< Used to calculate measured rate from change in position over time. -#ifndef DISABLE_SYRINGE_PUMP_ALARMS static MOTOR_DIR_T syringePumpControllerMeasuredDirection; ///< Measured direction of syringe pump per controller. static MOTOR_DIR_T syringePumpEncoderMeasuredDirection; ///< Measured direction of syringe pump per encoder position relative to previous. -#endif static BOOL syringePumpRetractRequested; ///< Flag indicates a retract operation is requested. static BOOL syringePumpSeekRequested; ///< Flag indicates a plunger seek operation is requested. @@ -259,7 +259,6 @@ static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static BOOL checkForStall( BOOL stopPump ); static void publishSyringePumpData( void ); -static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief @@ -281,12 +280,13 @@ syringePumpVolumeStartPosition = 0; syringePumpHomePositionOffset = 0; syringePumpLastPosition = 0; -#ifndef DISABLE_SYRINGE_PUMP_ALARMS - syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; - syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) + { + syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; + syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; + } - syringePumpDataPublicationTimerCounter = 0; + syringePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; @@ -480,15 +480,16 @@ *************************************************************************/ BOOL retractSyringePump( void ) { -#ifndef ALWAYS_ALLOW_SYRINGE_PUMP_CMDS - if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) -#else - heparinDeliveryState = HEPARIN_STATE_STOPPED; - if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) ) -#endif + if ( ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) || + ( getSoftwareConfigStatus( SW_CONFIG_ENABLE_SYRINGE_PUMP_CMDS ) ) == SW_CONFIG_ENABLE_VALUE ) { - syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; - syringePumpRetractRequested = TRUE; + heparinDeliveryState = HEPARIN_STATE_STOPPED; + if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) ) + { + syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; + syringePumpRetractRequested = TRUE; + } + } return syringePumpRetractRequested; @@ -570,9 +571,10 @@ } else { -#ifndef DISABLE_SYRINGE_PUMP - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_BOLUS_CMD, tgtRate ) -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP ) != SW_CONFIG_ENABLE_VALUE ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_BOLUS_CMD, syringePumpSetRate ) + } } return syringePumpBolusRequested; @@ -600,9 +602,10 @@ } else { -#ifndef DISABLE_SYRINGE_PUMP - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_CONT_CMD, flowRate ) -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP ) != SW_CONFIG_ENABLE_VALUE ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, (F32)SW_FAULT_ID_HD_SYRINGE_INVALID_CONT_CMD, flowRate ) + } } return syringePumpContinuousRequested; @@ -906,7 +909,8 @@ if ( TRUE == isNewCalibrationRecordAvailable() ) { // Get the new calibration data and check its validity - processCalibrationData(); + getNVRecord2Driver( GET_CAL_HEPARIN_FORCE_SENSOR, (U08*)&forceSensorCalRecord, sizeof( HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T ), + 0, ALARM_ID_HD_HEPARIN_FORCE_SENSOR_INVALID_CAL_RECORD ); } S32 encPosition = getFPGASyringePumpEncoderPosition(); @@ -941,12 +945,13 @@ calcSafetyVolumeDelivered(); // Calculate measured rate (mL/hr) calcMeasRate(); -#ifndef DISABLE_SYRINGE_PUMP_ALARMS - // Get measured direction - syringePumpControllerMeasuredDirection = ( ( getSyringePumpEncoderStatus() & SYRINGE_PUMP_ENCODER_DIRECTION_BIT ) != 0 ? MOTOR_DIR_REVERSE : MOTOR_DIR_FORWARD ); - // Calculate direction from encoder position relative to last - syringePumpEncoderMeasuredDirection = ( getSyringePumpPosition() - syringePumpLastPosition >= 0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) + { + // Get measured direction + syringePumpControllerMeasuredDirection = ( ( getSyringePumpEncoderStatus() & SYRINGE_PUMP_ENCODER_DIRECTION_BIT ) != 0 ? MOTOR_DIR_REVERSE : MOTOR_DIR_FORWARD ); + // Calculate direction from encoder position relative to last + syringePumpEncoderMeasuredDirection = ( getSyringePumpPosition() - syringePumpLastPosition >= 0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); + } // Check if syringe pump is on while BP is off { @@ -964,9 +969,10 @@ if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR, ( ( getCurrentOperationMode() > MODE_INIT ) && ( lastSyringePumpADCReadCtr == getSyringePumpADCReadCounter() ) ) ) ) { -#ifndef DISABLE_SYRINGE_PUMP_ALARMS - activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR ); -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) + { + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_ADC_ERROR ); + } } lastSyringePumpADCReadCtr = getSyringePumpADCReadCounter(); @@ -996,18 +1002,18 @@ { isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, FALSE ); } + + // Execute syringe pump control state machine + switch ( syringePumpState ) + { + case SYRINGE_PUMP_INIT_STATE: + syringePumpState = handleSyringePumpInitState(); + break; + + case SYRINGE_PUMP_OFF_STATE: + syringePumpState = handleSyringePumpOffState(); + break; - // Execute syringe pump control state machine - switch ( syringePumpState ) - { - case SYRINGE_PUMP_INIT_STATE: - syringePumpState = handleSyringePumpInitState(); - break; - - case SYRINGE_PUMP_OFF_STATE: - syringePumpState = handleSyringePumpOffState(); - break; - case SYRINGE_PUMP_RETRACT_STATE: syringePumpState = handleSyringePumpRetractState(); break; @@ -1055,7 +1061,8 @@ { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - BOOL calStatus = processCalibrationData(); + BOOL calStatus = getNVRecord2Driver( GET_CAL_HEPARIN_FORCE_SENSOR, (U08*)&forceSensorCalRecord, sizeof( HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T ), + 0, ALARM_ID_HD_HEPARIN_FORCE_SENSOR_INVALID_CAL_RECORD ); if ( TRUE == calStatus ) { @@ -1106,14 +1113,13 @@ { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; -#ifndef DISABLE_SYRINGE_PUMP_ALARMS // Check position is not changing while stopped - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, ( syringePumpLastPosition != getSyringePumpPosition() ) ) ) + if ( ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, ( syringePumpLastPosition != getSyringePumpPosition() ) ) ) && + ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) ) { activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR ); activateSafetyShutdown(); } -#endif // Check for request flags if ( TRUE == syringePumpRetractRequested ) @@ -1271,9 +1277,10 @@ } else { -#ifndef DISABLE_SYRINGE_PUMP_ALARMS - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM, syringeVol, txVolume ); -#endif + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM, syringeVol, txVolume ); + } } } @@ -1481,18 +1488,19 @@ { BOOL result = stopPump; -#ifndef DISABLE_SYRINGE_PUMP_ALARMS - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, ( syringePumpEncoderMeasuredDirection != expDir ) ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) { - result = TRUE; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, (U32)syringePumpEncoderMeasuredDirection, (U32)syringePumpState ); + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, ( syringePumpEncoderMeasuredDirection != expDir ) ) ) + { + result = TRUE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, (U32)syringePumpEncoderMeasuredDirection, (U32)syringePumpState ); + } + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, ( syringePumpControllerMeasuredDirection != expDir ) ) ) + { + result = TRUE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, (U32)syringePumpControllerMeasuredDirection, (U32)syringePumpState ); + } } - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, ( syringePumpControllerMeasuredDirection != expDir ) ) ) - { - result = TRUE; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, (U32)syringePumpControllerMeasuredDirection, (U32)syringePumpState ); - } -#endif return result; } @@ -1619,20 +1627,22 @@ static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ) { BOOL result = stopPump; -#ifndef DISABLE_SYRINGE_PUMP_ALARMS - F32 rate = getSyringePumpMeasRate(); - F32 max = MAX( rate, syringePumpSetRate ); - F32 min = MIN( rate, syringePumpSetRate ); - F32 error = ( max > 0.0 ? ( 1.0 - fabs( min / max ) ) : 0.0 ); - F32 delta = max - min; - // Alarm on rate if off by more than 5% or 0.1 mL/hr, whichever is greater - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, ( ( error > pctMargin ) && ( delta > SYRINGE_PUMP_MAX_RATE_ERROR_ML_HR ) ) ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) { - result = TRUE; - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, syringePumpSetRate, rate ) + F32 rate = getSyringePumpMeasRate(); + F32 max = MAX( rate, syringePumpSetRate ); + F32 min = MIN( rate, syringePumpSetRate ); + F32 error = ( max > 0.0 ? ( 1.0 - fabs( min / max ) ) : 0.0 ); + F32 delta = max - min; + + // Alarm on rate if off by more than 5% or 0.1 mL/hr, whichever is greater + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, ( ( error > pctMargin ) && ( delta > SYRINGE_PUMP_MAX_RATE_ERROR_ML_HR ) ) ) ) + { + result = TRUE; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, syringePumpSetRate, rate ) + } } -#endif return result; } @@ -1840,45 +1850,8 @@ syringePumpDataPublicationTimerCounter = 0; } } + -/*********************************************************************//** - * @brief - * The processCalibrationData function gets the calibration data and makes - * sure it is valid by checking the calibration date. The calibration date - * should not be 0. - * @details Inputs: none - * @details Outputs: forceSensorCalRecord - * @return TRUE if the calibration record is valid, otherwise FALSE - *************************************************************************/ -static BOOL processCalibrationData( void ) -{ - BOOL status = TRUE; - - // Get the calibration record from NVDataMgmt - HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T calData = getHDHeparinForceSensorCalibrationRecord(); - - // Check if the calibration data that was received from NVDataMgmt is legitimate - // The calibration date item should not be zero. If the calibration date is 0, - // then the heparin force sensors data is not stored in the NV memory or it was corrupted. - if ( 0 == calData.hdHeparinForceSensor.calibrationTime ) - { -#ifndef SKIP_CAL_CHECK - activateAlarmNoData( ALARM_ID_HD_HEPARIN_FORCE_SENSOR_INVALID_CAL_RECORD ); - status = FALSE; -#endif - } - - // The calibration data was valid, update the local copy - forceSensorCalRecord.hdHeparinForceSensor.fourthOrderCoeff = calData.hdHeparinForceSensor.fourthOrderCoeff; - forceSensorCalRecord.hdHeparinForceSensor.thirdOrderCoeff = calData.hdHeparinForceSensor.thirdOrderCoeff; - forceSensorCalRecord.hdHeparinForceSensor.secondOrderCoeff = calData.hdHeparinForceSensor.secondOrderCoeff; - forceSensorCalRecord.hdHeparinForceSensor.gain = calData.hdHeparinForceSensor.gain; - forceSensorCalRecord.hdHeparinForceSensor.offset = calData.hdHeparinForceSensor.offset; - - return status; -} - - /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/