Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r8abde9a00d09d1e687be6fe88592e66706c1a81d -rf0c16ca7223ad48b7bdb86b8f010b74b550c0051 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 8abde9a00d09d1e687be6fe88592e66706c1a81d) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision f0c16ca7223ad48b7bdb86b8f010b74b550c0051) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2021-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file SyringePump.c * -* @author (last) Dara Navaei -* @date (last) 09-Nov-2022 +* @author (last) Sean Nash +* @date (last) 16-Aug-2023 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 @@ -68,6 +68,9 @@ #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_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. #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. @@ -76,12 +79,12 @@ #define SYRINGE_PUMP_ADC_FULL_SCALE_BITS 1024.0F ///< Syringe pump ADC has 1024 full scale counts (10-bit) per channel. #define SYRINGE_PUMP_DAC_FULL_SCALE_BITS 4096.0F ///< Syringe pump DAC has has 4096 full scale counts (12-bit). -#define SYRINGE_FORCE_OCCLUSION_THRESHOLD_V 3.2F ///< Force sensor threshold (in V) above which an occlusion is detected. +#define SYRINGE_FORCE_OCCLUSION_THRESHOLD_V 2.5F ///< Force sensor threshold (in V) above which an occlusion is detected. #define SYRINGE_FORCE_OCCLUSION_DIFF_V 0.5F ///< Force sensor difference (in V) which an occlusion alarm is triggered. #define SYRINGE_FORCE_PLUNGER_THRESHOLD_V 0.25F ///< Force sensor threshold (in V) above which we have engaged with plunger. #define SYRINGE_PUMP_SYRINGE_DETECT_THRESHOLD_V 2.0F ///< Syringe pump syringe detected threshold (in V). #define SYRINGE_PUMP_HOME_DETECT_THRESHOLD_V 0.25F ///< Syringe pump home detected threshold (in V). -#define SYRINGE_PUMP_PRIME_VOLUME_ML 0.353F ///< Target syringe prime volume (in mL). +#define SYRINGE_PUMP_EMPTY_THRESHOLD_V 2.5F ///< Syringe pump empty detected threshold (in V). #define SYRINGE_PUMP_PRELOAD_MARGIN_VOLUME_ML 1.0F ///< Target syringe preload margin volume (in mL). Total to deliver plus this give syringe load position. #define SYRINGE_PUMP_PRELOAD_MAX_VOLUME_ML 10.0F ///< Target syringe preload max volume (in mL). Leave at home position above this value. #define SYRINGE_PUMP_MAX_VOL_ERROR_ML 0.1F ///< Maximum Heparin volume error (in mL). @@ -91,9 +94,13 @@ #define SYRINGE_PUMP_DAC_VOLTAGE_MAX_ERROR 0.05F ///< Force sensor POST check for DAC voltage - max delta. #define MIN_SYRINGE_PUMP_RATE_FOR_DIR_ALARM 0.5F ///< Minimum measured rate (in mL/hr) required before enforcing direction alarm. +/// HW volume variance in the syringe pump in mL. +#define SYRINGE_PUMP_HW_TOLERANCE_ML 0.65F +/// HW volume variance in the syringe pump in encoder counts. +#define SYRINGE_PUMP_HW_TOLERANCE_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * SYRINGE_PUMP_HW_TOLERANCE_ML ) /// Expected position of empty in relation to home position. -#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84F ) -/// Margin of error for empty position determination. +#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 11.0F ) +/// Over-travel (past empty) allowance for alarm. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5F ) /// Minimum retract position. #define SYRINGE_PUMP_RETRACT_POS_MIN ( SYRINGE_ENCODER_COUNTS_PER_ML * -0.5F ) @@ -158,6 +165,8 @@ #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 { @@ -196,6 +205,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. @@ -226,6 +236,7 @@ static BOOL syringeVolumeAdequate; ///< Flag indicates whether Heparin volume is sufficient to complete treatment. static BOOL syringePumpPrimeCompleted; ///< Flag indicates prime operation was completed. static BOOL syringePumpPreLoadCompleted; ///< Flag indicates preload operation was completed. +static U32 syringePumpStateStartTime; ///< Time current syringe pump state started. static BOOL syringePumpDACVrefWriteInProgress; ///< Flag indicates DAC Vref write is in progress. static F32 syringePumpDACVref; ///< DAC Vref setting for force sensor. @@ -237,6 +248,8 @@ static U32 syringePumpDACRetryCount; static U32 syringePumpDACRetryTimer; +static U32 syringePumpEmptyForceCount; + // ********** private function prototypes ********** static void resetSyringePumpRequestFlags( void ); @@ -289,34 +302,29 @@ syringePumpState = SYRINGE_PUMP_INIT_STATE; heparinDeliveryState = HEPARIN_STATE_OFF; requireSyringeDetection = FALSE; + prevSyringeDetected = FALSE; syringePumpSetRate = 0.0; syringePumpSetToggleTime = 0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = 0; syringePumpHomePositionOffset = 0; syringePumpLastPosition = 0; syringePumpVolumeRequired = 0.0; - -#ifndef _RELEASE_ - if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) - { - syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; - syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; - } -#endif - + syringePumpControllerMeasuredDirection = MOTOR_DIR_FORWARD; + syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; syringePumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; syringePumpSafetyVolumeDelivered = 0.0; + syringePumpStateStartTime = getMSTimerCount(); syringePumpPositionKnown = FALSE; syringePumpPlungerFound = FALSE; syringeVolumeAdequate = FALSE; syringePumpPrimeCompleted = FALSE; syringePumpPreLoadCompleted = FALSE; syringePumpRampUpPct = 0.0; - + syringePumpEmptyForceCount = 0; // Zero pump position counts buffer syringePumpMotorSpeedCalcIdx = 0; for ( i = 0; i < SYRINGE_PUMP_SPEED_CALC_BUFFER_LEN; i++ ) @@ -333,8 +341,8 @@ 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 ); + 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 ); @@ -479,6 +487,18 @@ /*********************************************************************//** * @brief + * The resetPreLoadStatus function resets the syringe pump pre-load status. + * @details Inputs: none + * @details Outputs: syringePumpPreLoadCompleted + * @return none + *************************************************************************/ +void resetPreLoadStatus( void ) +{ + syringePumpPreLoadCompleted = FALSE; +} + +/*********************************************************************//** + * @brief * The stopSyringePump function requests syringe pump be stopped. * @details Inputs: none * @details Outputs: syringePumpSetRate, syringePumpState, heparinDeliveryState @@ -1017,8 +1037,6 @@ *************************************************************************/ static void execSyringePumpMonitor( void ) { - BOOL prevSyringeDetected = isSyringeDetected(); - // Check if a new calibration is available if ( TRUE == isNewCalibrationRecordAvailable() ) { @@ -1095,10 +1113,10 @@ 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; + syringePumpVolumeDelivered.data = MAX( syringePumpVolumeDelivered.data, 0.0F ); calcSafetyVolumeDelivered(); // Calculate measured rate (mL/hr) calcMeasRate(); @@ -1129,7 +1147,7 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_SYRINGE_PUMP_ALARMS ) != SW_CONFIG_ENABLE_VALUE ) #endif { - checkFPGAPersistentAlarms( FPGA_PERS_ERROR_SYRINGE_PUMP_ADC, getSyringePumpADCandDACStatus(), getSyringePumpADCReadCounter() ); + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_SYRINGE_PUMP_ADC, getSyringePumpADCReadCounter() ); } // Check pump status @@ -1149,15 +1167,10 @@ *************************************************************************/ void execSyringePump( void ) { + SYRINGE_PUMP_STATE_T priorSyringeState = syringePumpState; // 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++; @@ -1207,8 +1220,17 @@ break; } + if ( priorSyringeState != syringePumpState ) + { + SEND_EVENT_WITH_2_U32_DATA( HD_EVENT_SYRINGE_PUMP_STATE, priorSyringeState, syringePumpState ); + } + resetSyringePumpRequestFlags(); + // Save syringe pump info for next time + syringePumpLastPosition = getSyringePumpPosition(); + prevSyringeDetected = isSyringeDetected(); + // Publish syringe pump data on interval publishSyringePumpData(); } @@ -1282,7 +1304,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 ) @@ -1343,6 +1365,7 @@ // If we are starting an active pump state, set direction and calculate target toggle time to achieve desired rate if ( ( result != SYRINGE_PUMP_OFF_STATE ) && ( result != SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE ) ) { + syringePumpStateStartTime = getMSTimerCount(); if ( SYRINGE_PUMP_RETRACT_STATE == result ) { // Set fpga direction to reverse @@ -1411,8 +1434,10 @@ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OVER_TRAVEL_ERROR, (U32)getSyringePumpPosition(), (U32)SYRINGE_PUMP_RETRACT_STATE ); } + // Check for stall stopPump = checkForStall( stopPump ); + // Check direction stopPump = checkDirection( stopPump, MOTOR_DIR_REVERSE ); // If anything found that would require stopping the pump, stop pump and go to off state @@ -1447,20 +1472,11 @@ F32 txVolumeReq = SYRINGE_PUMP_PRIME_VOLUME_ML + bolusVol + ( hepDurHr * contRate ); F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_ENCODER_COUNTS_PER_ML; - syringePumpVolumeRequired = txVolumeReq; - txVolumeReq = txVolumeReq + SYRINGE_PUMP_PRELOAD_MARGIN_VOLUME_ML; + syringePumpVolumeRequired = txVolumeReq + SYRINGE_PUMP_FILL_VOLUME_OFFSET_ML; + txVolumeReq = txVolumeReq + SYRINGE_PUMP_FILL_VOLUME_OFFSET_ML + SYRINGE_PUMP_PRELOAD_MARGIN_VOLUME_ML; - // Is syringe loaded? - if ( TRUE == isSyringeDetected() ) - { - activateAlarmNoData( ALARM_ID_HD_SYRINGE_DETECTED ); - stopPump = TRUE; - } - else - { - // Handle ramp up - rampSyringePump(); - } + // Handle ramp up + rampSyringePump(); // Is plunger Heparin volume position detected? or volume requiring full syringe. if ( ( syringeVol <= txVolumeReq ) || ( SYRINGE_PUMP_PRELOAD_MAX_VOLUME_ML < txVolumeReq ) ) @@ -1472,6 +1488,9 @@ syringePumpPreLoadCompleted = TRUE; } + // Check for stall + stopPump = checkForStall( stopPump ); + // Check max position > empty + 0.5 mL stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); @@ -1519,10 +1538,9 @@ syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = pos; - syringePumpPreLoadCompleted = FALSE; - // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm - if ( syringeVol >= txVolume ) + // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm (check only applies in pre-tx mode) + if ( ( syringeVol >= txVolume ) || ( getCurrentOperationMode() != MODE_PRET ) ) { syringePumpPlungerFound = TRUE; syringeVolumeAdequate = TRUE; @@ -1538,6 +1556,9 @@ } } + // Check for stall + stopPump = checkForStall( stopPump ); + // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); @@ -1561,7 +1582,7 @@ * @brief * The handleSyringePumpPrimeState function handles the prime state * of the syringe pump control state machine. - * @details Inputs: syringePumpVolumeDelivered.data + * @details Inputs: syringePumpVolumeDelivered, syringePumpStateStartTime * @details Outputs: Syringe pump ramped up to prime rate, alarm conditions checked * @return next state *************************************************************************/ @@ -1581,9 +1602,18 @@ syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = syringePumpPosition.data; - syringePumpPreLoadCompleted = FALSE; } + // Check for timeout + if ( TRUE == didTimeout( syringePumpStateStartTime, SYRINGE_PUMP_PRIMING_TIMEOUT_MS ) ) + { + stopPump = TRUE; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, (F32)SYRINGE_PUMP_PRIMING_TIMEOUT_MS, 0.0F ) + } + + // Check for stall + stopPump = checkForStall( stopPump ); + // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); @@ -1676,6 +1706,9 @@ // Check for syringe pump empty stopPump = checkSyringeEmpty( stopPump ); + // Check for occlusion + stopPump = checkForSyringeOcclusion( stopPump ); + // Check position > empty + 0.5 mL stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); @@ -1806,8 +1839,18 @@ F32 force = getSyringePumpForceV(); S32 pos = getSyringePumpPosition(); + if ( force >= SYRINGE_PUMP_EMPTY_THRESHOLD_V ) + { + syringePumpEmptyForceCount++; + } + else + { + syringePumpEmptyForceCount = 0; + } // If near empty position, assume syringe is empty - if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) + // Check for force threshold over some time and within SYRINGE_PUMP_HW_TOLERANCE_POS of empty + if ( ( pos >= SYRINGE_PUMP_EMPTY_POS ) || + ( ( syringePumpEmptyForceCount >= SYRINGE_PUMP_EMPTY_FORCE_COUNT ) && ( pos >= ( SYRINGE_PUMP_EMPTY_POS - SYRINGE_PUMP_HW_TOLERANCE_POS ) ) ) ) { heparinDeliveryState = HEPARIN_STATE_EMPTY; SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, force ) @@ -1823,21 +1866,40 @@ * pressure. Would indicate occlusion or jam or empty syringe. * @details Inputs: syringePumpMeasForce.data, syringePumpPosition.data * @details Outputs: alarm triggered if max force detected + * @param stopPump flag passed in by caller indicating whether pump should be stopped * @return TRUE if pump should be stopped, FALSE if not *************************************************************************/ -BOOL checkForPrimeOcclusion( void ) +BOOL checkForSyringeOcclusion( BOOL stopPump ) { - BOOL result = FALSE; // Return FALSE if no occlusion is detected - F32 forceAtEndOfPriming = getSyringePumpForceV(); // Read the force sensor at the end of the priming - F32 forceDelta = forceAtEndOfPriming - forceAtEndOfSeek; // Occlusion is detected if force at end of prime is > than force at end of seek by 0.5 volts or more - BOOL occlusionDetected = ( forceDelta >= SYRINGE_FORCE_OCCLUSION_DIFF_V ? TRUE : FALSE ); + BOOL result = stopPump; + F32 currentForceV = getSyringePumpForceV(); // Read the force sensor at the end of the priming + F32 forceDelta = currentForceV - forceAtEndOfSeek; // Occlusion is detected if force at end of prime is > than force at end of seek by 0.5 volts or more + BOOL occlusionDetected = FALSE; - if ( TRUE == occlusionDetected ) + // Checking for occlusion in dry self tests without persistence + if ( MODE_PRET == getCurrentOperationMode() ) { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtEndOfSeek, forceAtEndOfPriming ) - result = TRUE; + occlusionDetected = ( forceDelta >= SYRINGE_FORCE_OCCLUSION_DIFF_V ? TRUE : FALSE ); + + if ( TRUE == occlusionDetected ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtEndOfSeek, currentForceV ) + result = TRUE; + } + else + { + clearAlarmCondition( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION ); + } } + // Check with persistence during continuous state + if ( SYRINGE_PUMP_OP_CONTINUOUS == syringePumpState ) + { + occlusionDetected = ( currentForceV >= SYRINGE_FORCE_OCCLUSION_THRESHOLD_V ? TRUE : FALSE ); + + checkPersistentAlarm( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, occlusionDetected, forceAtEndOfSeek, currentForceV ); + } + return result; } @@ -1880,20 +1942,11 @@ BOOL result = stopPump; S32 pos = getSyringePumpPosition(); - if ( pos > ( SYRINGE_PUMP_EMPTY_POS - SYRINGE_PUMP_EMPTY_POS_MARGIN ) ) + if ( pos >= maxPos ) { result = TRUE; - heparinDeliveryState = HEPARIN_STATE_EMPTY; - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, getSyringePumpForceV() ) + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OVER_TRAVEL_ERROR, (U32)pos, (U32)syringePumpState ); } - else if ( pos > maxPos ) - { - result = TRUE; - if ( syringePumpState != SYRINGE_PUMP_PRIME_STATE ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OVER_TRAVEL_ERROR, (U32)pos, (U32)syringePumpState ); - } - } return result; } @@ -1979,30 +2032,30 @@ BOOL result = stopPump; // Check for stall - if ( fabs( getSyringePumpMeasRate() ) < SYRINGE_PUMP_STALL_SPEED_THRESHOLD ) - { - if ( ++syringePumpStallCtr >= SYRINGE_PUMP_RAMP_STALL_TIME ) - { - if ( ++syringePumpStallRetryCount <= SYRINGE_PUMP_RAMP_STALL_RETRIES ) - { - syringePumpSetToggleTime++; // lower target rate (by increasing time between steps) - syringePumpRampTimerCtr = 0; // restart ramp - syringePumpRampUpToggleTime = SYRINGE_PUMP_START_RAMP_SPEED; - syringePumpStallCtr = 0; // reset stall counter - } - else - { - result = TRUE; - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_STALL, (U32)getSyringePumpPosition(), (U32)syringePumpState ); - } - } - } - else - { + if ( fabs( getSyringePumpMeasRate() ) < SYRINGE_PUMP_STALL_SPEED_THRESHOLD ) + { + if ( ++syringePumpStallCtr >= SYRINGE_PUMP_RAMP_STALL_TIME ) + { + if ( ++syringePumpStallRetryCount <= SYRINGE_PUMP_RAMP_STALL_RETRIES ) + { + syringePumpSetToggleTime++; // lower target rate (by increasing time between steps) + syringePumpRampTimerCtr = 0; // restart ramp + syringePumpRampUpToggleTime = SYRINGE_PUMP_START_RAMP_SPEED; + syringePumpStallCtr = 0; // reset stall counter + } + else + { + result = TRUE; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_STALL, (U32)getSyringePumpPosition(), (U32)syringePumpState ); + } + } + } + else + { syringePumpStallCtr = 0; - } + } - return result; + return result; } /*********************************************************************//** @@ -2138,7 +2191,7 @@ volData.syringePumpVolumeRequired = syringePumpVolumeRequired; broadcastData( MSG_ID_HD_SYRINGE_PUMP_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&data, sizeof( SYRINGE_PUMP_DATA_PAYLOAD_T ) ); - broadcastData( MSG_ID_HD_HEPARIN_DATA_BROADCAST, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&volData, sizeof( SYRINGE_PUMP_VOLUME_DATA_T ) ); + broadcastData( MSG_ID_HD_HEPARIN_DATA, COMM_BUFFER_OUT_CAN_HD_BROADCAST, (U08*)&volData, sizeof( SYRINGE_PUMP_VOLUME_DATA_T ) ); syringePumpDataPublicationTimerCounter = 0; } }