Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r0e457429d65039d16cd631c3aaa06b5409de67c4 -rd24f785838637d84dcc45f531570d6263cabf1c8 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 0e457429d65039d16cd631c3aaa06b5409de67c4) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision d24f785838637d84dcc45f531570d6263cabf1c8) @@ -68,6 +68,8 @@ #define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. #define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. #define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. +#define SYRINGE_PUMP_OFF_ERROR_MAX_CNT 5 ///< Maximum number of syringe pump not stopped errors within time window before alarm triggered. Do not exceed MAX_TIME_WINDOWED_COUNT. +#define SYRINGE_PUMP_OFF_ERROR_TIME_WIN_MS (1 * MS_PER_SECOND) ///< Time window for Syringe Pump not stopped error. #define STEPS_TO_MICROSTEPS( s ) ( (s) * 32.0F ) ///< Macro conversion from steps to microsteps. #define MICROSTEPS_TO_STEPS( m ) ( (m) / 32.0F ) ///< Macro conversion from microsteps to steps. @@ -160,10 +162,12 @@ #define SYRINGE_PUMP_STALL_SPEED_THRESHOLD 0.05F ///< Minimum syringe pump speed to be considered not stalled. #define SYRINGE_PUMP_ADC_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Syringe pump ADC FPGA error timeout in milliseconds. + #define SYRINGE_PUMP_DAC_MAX_RETRIES 5 ///< Syringe pump DAC retries to write. #define SYRINGE_PUMP_DAC_TIMER ( 200 / TASK_PRIORITY_INTERVAL ) ///< Syringe pump DAC timer between retries. #define SYRINGE_PUMP_OCCLUSION_PERSISTENCE 50 ///< Syringe pump occlusion persistence timer. #define SYRINGE_PUMP_EMPTY_FORCE_COUNT 5 ///< Syringe pump empty force voltage count persistence. + /// Defined states for the syringe pump control state machine. typedef enum SyringePump_States { @@ -202,6 +206,7 @@ static OVERRIDE_U32_T syringePumpADCReadCtr = {0, 0, 0, 0}; ///< Syringe pump ADC read counter reported by FPGA. static BOOL requireSyringeDetection; ///< Flag indicating whether syringe detection is required in the current state. +static BOOL prevSyringeDetected; ///< Flag saving last state of syringe detection static F32 syringePumpSetRate; ///< Set rate for syringe pump (in mL/hr). static F32 forceAtEndOfSeek; ///< Force sensor reading in Volts at the end of seek. @@ -297,6 +302,7 @@ syringePumpState = SYRINGE_PUMP_INIT_STATE; heparinDeliveryState = HEPARIN_STATE_OFF; requireSyringeDetection = FALSE; + prevSyringeDetected = FALSE; syringePumpSetRate = 0.0; syringePumpSetToggleTime = 0; syringePumpSafetyVolumeDelivered = 0.0; @@ -334,9 +340,10 @@ initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, 0, SYRINGE_PUMP_DIR_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, 0, SYRINGE_PUMP_DIR_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_RUNNING_WHILE_BP_OFF_ERROR, 0, SYRINGE_PUMP_OFF_ALARM_PERSISTENCE ); - initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, 0, SYRINGE_PUMP_OFF_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_SPEED_ERROR, 0, SYRINGE_PUMP_RATE_ALARM_PERSISTENCE ); initPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, 0, SYRINGE_PUMP_OCCLUSION_PERSISTENCE); + initTimeWindowedCount( TIME_WINDOWED_COUNT_SYRINGE_PUMP_OFF_ERROR, SYRINGE_PUMP_OFF_ERROR_MAX_CNT, SYRINGE_PUMP_OFF_ERROR_TIME_WIN_MS ); + initFPGAPersistentAlarm( FPGA_PERS_ERROR_SYRINGE_PUMP_ADC, ALARM_ID_HD_SYRINGE_PUMP_FPGA_ADC_FAULT, SYRINGE_PUMP_ADC_FPGA_ERROR_TIMEOUT_MS, SYRINGE_PUMP_ADC_FPGA_ERROR_TIMEOUT_MS ); @@ -1030,8 +1037,6 @@ *************************************************************************/ static void execSyringePumpMonitor( void ) { - BOOL prevSyringeDetected = isSyringeDetected(); - // Check if a new calibration is available if ( TRUE == isNewCalibrationRecordAvailable() ) { @@ -1108,7 +1113,6 @@ syringePumpMeasForce.data = ( (F32)getFPGASyringePumpADCChannel0() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; // Apply home offset to encoder position - syringePumpLastPosition = getSyringePumpPosition(); syringePumpPosition.data = encPosition - syringePumpHomePositionOffset; // Calculate volume delivered from position syringePumpVolumeDelivered.data = (F32)( syringePumpPosition.data - syringePumpVolumeStartPosition ) / SYRINGE_ENCODER_COUNTS_PER_ML; @@ -1166,12 +1170,6 @@ // Execute syringe pump monitor execSyringePumpMonitor(); - // Clear pump running while off alarm persistence if not in off state - if ( syringePumpState != SYRINGE_PUMP_OFF_STATE ) - { - isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, FALSE ); - } - if ( syringePumpDACRetryCount > 0 ) { syringePumpDACRetryTimer++; @@ -1228,6 +1226,10 @@ resetSyringePumpRequestFlags(); + // Save syringe pump info for next time + syringePumpLastPosition = getSyringePumpPosition(); + prevSyringeDetected = isSyringeDetected(); + // Publish syringe pump data on interval publishSyringePumpData(); } @@ -1301,7 +1303,7 @@ SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; // Check position is not changing while stopped - if ( ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR, ( syringePumpLastPosition != getSyringePumpPosition() ) ) ) ) + if ( ( syringePumpLastPosition != getSyringePumpPosition() ) && ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_SYRINGE_PUMP_OFF_ERROR ) ) ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE )