Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r33e855270275c6a5601ca0ee7fee39dcfb56eee5 -r95a792887b08b72bd99ec7ca8beda4e93ac2f7a8 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 33e855270275c6a5601ca0ee7fee39dcfb56eee5) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 95a792887b08b72bd99ec7ca8beda4e93ac2f7a8) @@ -69,7 +69,7 @@ #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 10 ///< 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_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 SYRINGE_PUMP_PRIMING_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Timeout for syringe pump prime operation. @@ -156,6 +156,8 @@ /// Interval (ms/task time) at which the syringe pump speed is calculated (every 40 ms). #define SYRINGE_PUMP_SPEED_CALC_INTERVAL ( 40 / TASK_PRIORITY_INTERVAL ) +/// Interval (ms/task time) at which the syringe pump position is checked when pump off state (every 50 ms). +#define SYRINGE_PUMP_STOP_POSITION_CHECK_INTERVAL ( 50 / TASK_PRIORITY_INTERVAL ) /// Number of syringe pump encoder positions kept in buffer to hold last 1 second of position data. #define SYRINGE_PUMP_SPEED_CALC_BUFFER_LEN ( MS_PER_SECOND / SYRINGE_PUMP_SPEED_CALC_INTERVAL / TASK_PRIORITY_INTERVAL ) @@ -164,10 +166,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 in milliseconds. #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 { @@ -217,9 +221,11 @@ static S32 syringePumpVolumeStartPosition; ///< Start position for the current volume calculation. static S32 syringePumpHomePositionOffset; ///< FPGA reported position when at home postion. static S32 syringePumpLastPosition; ///< Position previously recorded. +static S32 syringePumpStopLastPosition; ///< Syringe pump stop position previously recorded. 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. +static U32 syringePumpStopPositionTimerCounter; ///< Used to check change in encoder position when pump stopped. 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. static F32 syringePumpVolumeRequired; ///< Volume required for complete therapy (in mL). @@ -310,12 +316,14 @@ syringePumpVolumeStartPosition = 0; syringePumpHomePositionOffset = 0; syringePumpLastPosition = 0; + syringePumpStopLastPosition = 0; syringePumpVolumeRequired = 0.0; syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; syringePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; + syringePumpStopPositionTimerCounter = 0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpStateStartTime = getMSTimerCount(); @@ -343,6 +351,7 @@ 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_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, @@ -1304,17 +1313,25 @@ { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; - // Check position is not changing while stopped - if ( ( syringePumpLastPosition != getSyringePumpPosition() ) && ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_SYRINGE_PUMP_OFF_ERROR ) ) ) + // Check the encoder position every 50ms interval after pump off state transition. + if ( ++syringePumpStopPositionTimerCounter >= SYRINGE_PUMP_STOP_POSITION_CHECK_INTERVAL ) { -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) -#endif + // Check position is not changing while stopped + if ( ( syringePumpStopLastPosition != getSyringePumpPosition() ) && ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_SYRINGE_PUMP_OFF_ERROR ) ) ) { - activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR ); - activateSafetyShutdown(); + #ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) + #endif + { + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR ); + activateSafetyShutdown(); + } } + // last pump stop position value + syringePumpStopLastPosition = getSyringePumpPosition(); + syringePumpStopPositionTimerCounter = 0; } + // Reset persistence for direction alarms while pump is off isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, FALSE ); isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, FALSE );