/************************************************************************** * * Copyright (c) 2019-2020 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) Sean Nash * @date (last) 02-Mar-2021 * * @author (original) Sean Nash * @date (original) 02-Mar-2021 * ***************************************************************************/ #include "AlarmMgmt.h" #include "FPGA.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SyringePump.h" #include "SystemCommMessages.h" #include "TaskPriority.h" #include "Timers.h" /** * @addtogroup SyringePump * @{ */ // ********** private definitions ********** /// Default publication interval for syringe pump data. #define SYRINGE_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) /// Speed check interval. #define SYRINGE_PUMP_SPEED_CHECK_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) #define BD_SYRINGE_ID_RADIUS_CM ( 1.402 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. /// Milliliters per mm of syringe plunger travel. #define SYRINGE_ML_PER_MM ( ( BD_SYRINGE_ID_RADIUS_CM * BD_SYRINGE_ID_RADIUS_CM ) * PI * 0.1 ) #define SYRINGE_MM_PER_REV 0.635 ///< Travel (in mm) per revolution. #define SYRINGE_ENCODER_COUNTS_PER_REV 4000.0 ///< Number of encoder counts per revolution. #define SYRINGE_STEPS_PER_REV 200.0 ///< Number of steps per revolution. #define MICRO_SECONDS_PER_SECOND 1000000.0 ///< Microseconds per second conversion. #define SYRINGE_TOGGLES_PER_STEP 2.0 ///< Stepper motor driver toggles per step or microstep. #define SYRINGE_MICRO_STEPS_PER_STEP 32.0 ///< Micro-steps per step. /// Number of micro steps per revolution. #define SYRINGE_MICRO_STEPS_PER_REV ( SYRINGE_STEPS_PER_REV * SYRINGE_MICRO_STEPS_PER_STEP ) /// Number of encoder counts per mm. #define SYRINGE_ENCODER_COUNTS_PER_MM ( SYRINGE_ENCODER_COUNTS_PER_REV / SYRINGE_MM_PER_REV ) /// Number of encoder counts per mL. #define SYRINGE_ENCODER_COUNTS_PER_ML ( SYRINGE_ENCODER_COUNTS_PER_MM / SYRINGE_ML_PER_MM ) /// Number of micro steps per mL. #define SYRINGE_MICRO_STEPS_PER_ML ( ( SYRINGE_MICRO_STEPS_PER_REV / SYRINGE_MM_PER_REV ) / SYRINGE_ML_PER_MM ) #define MIN_HEPARIN_CONTINUOUS_RATE 0.1 ///< Minimum continuous Heparin flow rate (in mL/hr). #define MAX_HEPARIN_CONTINUOUS_RATE 1.0 ///< Maximum continuous Heparin flow rate (in mL/hr). #define MIN_HEPARIN_BOLUS_RATE 1.2 ///< Minimum Heparin bolus flow rate (in mL/hr). #define MAX_HEPARIN_BOLUS_RATE 24.0 ///< Maximum Heparin bolus flow rate (in mL/hr). #define SYRINGE_PUMP_RETRACT_RATE 10800.0 ///< Retract rate is 15 mL/ 5 s = 3 mL/s = 10,800 mL/hr. #define SYRINGE_PUMP_SEEK_RATE 3600.0 ///< Seek plunger rate is 5 mL/ 5 s = 1 mL/s = 3,600 mL/hr. #define SYRINGE_PUMP_PRIME_RATE 635.0 ///< Prime rate is 0.5 mm ^ 2 x PI x 450 mm = 0.353 mL / 2s = 635 mL/hr. #define SYRINGE_PUMP_MAX_RATE 11000.0 ///< Maximum rate of the syringe pump (in mL). #define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE ( 1 * MS_PER_SECOND ) ///< Alarm persistence period for syringe pump speed check alarms. #define STEPS_TO_MICROSTEPS( s ) ( (s) * 32.0 ) ///< Macro conversion from steps to microsteps. #define MICROSTEPS_TO_STEPS( m ) ( (m) / 32.0 ) ///< Macro conversion from microsteps to steps. #define SYRINGE_PUMP_ADC_REF_V 3.3 ///< Syringe pump ADC reference voltage. #define SYRINGE_PUMP_ADC_FULL_SCALE_BITS 1024.0 ///< Syringe pump ADC has 1024 full scale counts (10-bit) per channel. #define SYRINGE_PUMP_DAC_FULL_SCALE_BITS 4096.0 ///< Syringe pump DAC has has 4096 full scale counts (12-bit). #define SYRINGE_FORCE_OCCLUSION_THRESHOLD_V 3.2 ///< Force sensor threshold (in V) above which an occlusion is detected. #define SYRINGE_FORCE_PLUNGER_THRESHOLD_V 0.25 ///< Force sensor threshold (in V) above which we have engaged with plunger. #define SYRINGE_PUMP_SYRINGE_DETECT_THRESHOLD_V 2.0 ///< Syringe pump syringe detected threshold (in V). #define SYRINGE_PUMP_HOME_DETECT_THRESHOLD_V 0.25 ///< Syringe pump home detected threshold (in V). #define SYRINGE_PUMP_PRIME_VOLUME_ML 0.353 ///< Target syringe prime volume (in mL). #define SYRINGE_PUMP_START_RAMP_SPEED 300000 ///< Starting speed for all syringe pump operations to ramp up from. #define SYRINGE_PUMP_RAMP_DIVISOR 5 ///< Used for ramping profile. // Bit definitions for syringe pump control register #define SYRINGE_PUMP_CONTROL_SLEEP_OFF 0x40 ///< Syringe pump control register bit for sleep mode (active low). #define SYRINGE_PUMP_CONTROL_NOT_RESET 0x20 ///< Syringe pump control register bit for resetting stepper motor (active low). #define SYRINGE_PUMP_CONTROL_ENABLE 0x00 ///< Syringe pump control register bit mask for enable. #define SYRINGE_PUMP_CONTROL_DISABLE 0x10 ///< Syringe pump control register bit for enable (active low). #define SYRINGE_PUMP_CONTROL_REVERSE_DIR 0x08 ///< Syringe pump control register bit for direction (0=fwd, 1=rev). #define SYRINGE_PUMP_CONTROL_FORWARD_DIR 0x00 ///< Syringe pump control register bit mask for forward direction. #define SYRINGE_PUMP_CONTROL_32TH_STEP 0x03 ///< Syringe pump control register bits for 1/32 micro-stepping mode. // Bit definitions for syringe pump ADC/DAC control register #define SYRINGE_PUMP_ADC_DAC_CONTROL_WR_ADC_SETUP 0x04 ///< Syringe pump ADC/DAC control bit for re-write ADC setup registers to ADC. #define SYRINGE_PUMP_ADC_DAC_CONTROL_RD_DAC_ON_ADC 0x02 ///< Syringe pump ADC/DAC control bit for reading (once) DAC setting from device. #define SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_DAC 0x01 ///< Syringe pump ADC/DAC control bit for write DAC setting to device (ADC reads are off). #define SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_ADC 0x00 ///< Syringe pump ADC/DAC control bit mask for enable ADC reads. // Bit definitions for syringe pump ADC/DAC status register #define SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_DAC_WR_DONE 0x80 ///< Syringe pump ADC/DAC error status bit for DAC write done. #define SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_DAC_WR_ERROR 0x40 ///< Syringe pump ADC/DAC error status bit for DAC write error. #define SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_MASK 0x3F ///< Syringe pump ADC/DAC error status count bit-mask. // Bit definitions for syringe pump encoder status register #define SYRINGE_PUMP_ENCODER_STATUS_DIRECTION 0x80 ///< Syringe pump encoder status direction bit (0-Fwd, 1=Rev). #define SYRINGE_PUMP_ENCODER_STATUS_ERROR_COUNT_MASK 0x3F ///< Syringe pump encoder status error count bit-mask. // 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). /// 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 | SYRINGE_PUMP_CONTROL_ENABLE | SYRINGE_PUMP_CONTROL_REVERSE_DIR | SYRINGE_PUMP_CONTROL_32TH_STEP; /// Control bits to run syringe pump in forward direction static const U08 SYRINGE_PUMP_CONTROL_RUN_FORWARD = SYRINGE_PUMP_CONTROL_SLEEP_OFF | SYRINGE_PUMP_CONTROL_NOT_RESET | SYRINGE_PUMP_CONTROL_ENABLE | SYRINGE_PUMP_CONTROL_FORWARD_DIR | SYRINGE_PUMP_CONTROL_32TH_STEP; /// Defined states for the syringe pump control state machine. typedef enum SyringePump_States { SYRINGE_PUMP_INIT_STATE = 0, ///< Syringe pump initialize state SYRINGE_PUMP_OFF_STATE, ///< Syringe pump off state SYRINGE_PUMP_RETRACT_STATE, ///< Syringe pump retract state SYRINGE_PUMP_SEEK_STATE, ///< Syringe pump seek plunger state SYRINGE_PUMP_PRIME_STATE, ///< Syringe pump prime state SYRINGE_PUMP_HEP_BOLUS_STATE, ///< Syringe pump bolus delivery of Heparin state SYRINGE_PUMP_HEP_CONTINUOUS_STATE, ///< Syringe pump continuous delivery of Heparin state SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE, ///< Syringe pump configure DAC gain for force sensor state NUM_OF_SYRINGE_PUMP_STATES ///< Number of syringe pump control states } SYRINGE_PUMP_STATE_T; /// Defined states for the pressure and occlusion self-test state machine. typedef enum Syringe_Pump_Self_Test_States { SYRINGE_PUMP_SELF_TEST_STATE_START = 0, ///< Self test start state. SYRINGE_PUMP_TEST_STATE_IN_PROGRESS, ///< Self test in progress state. SYRINGE_PUMP_TEST_STATE_COMPLETE, ///< Self test completed state. NUM_OF_SYRINGE_PUMP_SELF_TEST_STATES ///< Number of syringe pump self-test states. } SYRINGE_PUMP_SELF_TEST_STATE_T; // ********** private data ********** static SYRINGE_PUMP_STATE_T syringePumpState; ///< Current state of syringe pump control state machine. static U32 syringePumpDataPublicationTimerCounter; ///< Used to schedule syringe pump data publication to CAN bus. static U32 syringePumpSpeedCalcTimerCounter; ///< Used to calculate measured rate from change in position over time. static U32 syringePumpRampTimerCtr; ///< Used to track ramp up time. /// Interval (in ms) at which to publish syringe pump data to CAN bus. static OVERRIDE_U32_T syringePumpDataPublishInterval = { SYRINGE_PUMP_DATA_PUB_INTERVAL, SYRINGE_PUMP_DATA_PUB_INTERVAL, 0, 0 }; static OVERRIDE_F32_T syringePumpMeasRate = {0.0, 0.0, 0.0, 0 }; ///< Measured rate for syringe pump (in mL/hr). static OVERRIDE_F32_T syringePumpMeasForce = {0.0, 0.0, 0.0, 0 }; ///< Measured driver force (in V). static OVERRIDE_F32_T syringePumpMeasSyringeDetectionSwitch = {0, 0, 0, 0 }; ///< Measured syringe detect switch (in V). static OVERRIDE_F32_T syringePumpMeasHome = {0.0, 0.0, 0.0, 0 }; ///< Measured optical home (in V). static OVERRIDE_S32_T syringePumpPosition = {0, 0, 0, 0 }; ///< Encoder based position (in steps). static OVERRIDE_F32_T syringePumpVolumeDelivered = {0.0, 0.0, 0.0, 0 }; ///< Measured volume delivered (in mL). static F32 syringePumpSetRate; ///< Set rate for syringe pump (in mL/hr). static U32 syringePumpSetToggleTime; ///< Set rate for syringe pump (in uSec/toggle). static U32 syringePumpRampUpToggleTime; ///< Current ramp rate for syringe pump (in uSec/toggle). static F32 syringePumpSafetyVolumeDelivered; ///< Calculated volume (in mL) (from set rate over time). static S32 syringePumpVolumeStartPosition; ///< Start position for the current volume calculation. static S32 syringePumpHomePositionOffset; ///< FPGA reported position when at home postion. static S32 syringePumpPosition1SecAgo; ///< Position recorded at last 1 Hz speed check. static BOOL syringePumpRetractRequested; ///< Flag indicates a retract operation is requested. static BOOL syringePumpPrimeRequested; ///< Flag indicates plunger seek and Heparin prime operations are requested. static BOOL syringePumpBolusRequested; ///< Flag indicates start or resume of a Heparin bolus operation is requested. static BOOL syringePumpContinuousRequested; ///< Flag indicates start or resume of a Heparin continuous delivery operation is requested. static BOOL syringePumpDACVrefSetRequested; ///< Flag indicates request to set DAC Vref for force sensor. static BOOL syringePumpDACVrefWriteInProgress; ///< Flag indicates DAC Vref write is in progress. static F32 syringePumpDACVref; ///< DAC Vref setting for force sensor. static U08 lastSyringePumpADCReadCtr; ///< Remember last ADC read counter to check new reads are fresh. static SYRINGE_PUMP_SELF_TEST_STATE_T syringePumpSelfTestState; ///< Current syringe pump self-test state. static U32 syringePumpSelfTestTimerCount; ///< Timer counter for syringe pump self-test. // ********** private function prototypes ********** static void resetSyringePumpRequestFlags( void ); static void execSyringePumpMonitor( void ); static U32 getPublishSyringePumpDataInterval( void ); static S32 getSyringePumpPosition( void ); static F32 getSyringePumpMeasRate( void ); static F32 getSyringePumpSyringeDetectorV( void ); static F32 getSyringePumpHomeDetectorV( void ); static F32 getSyringePumpForceV( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpInitState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpOffState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpRetractState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpSeekState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpPrimeState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpBolusState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpContinuousState( void ); static SYRINGE_PUMP_STATE_T handleSyringePumpCalibrateForceSensorState( void ); static void rampSyringePump( void ); static void calcStepperToggleTimeForTargetRate( F32 rate ); static void calcMeasRate( void ); static void calcSafetyVolumeDelivered( void ); static BOOL checkOcclusionOrEmpty( BOOL stopPump ); static BOOL checkSyringeRemoved( BOOL stopPump ); static BOOL checkMaxTravel( BOOL stopPump, S32 maxPos ); static BOOL checkMaxMeasRate( BOOL stopPump, F32 maxRate ); static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static void publishSyringePumpData( void ); /*********************************************************************//** * @brief * The initSyringePump function initializes the syringe pump module. * @details Inputs: none * @details Outputs: syringe pump module initialized. * @return none *************************************************************************/ void initSyringePump( void ) { syringePumpState = SYRINGE_PUMP_INIT_STATE; syringePumpSelfTestState = SYRINGE_PUMP_SELF_TEST_STATE_START; syringePumpSetRate = 0.0; syringePumpSetToggleTime = 0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = 0; syringePumpHomePositionOffset = 0; syringePumpPosition1SecAgo = 0; syringePumpDataPublicationTimerCounter = 0; syringePumpSelfTestTimerCount = 0; syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; lastSyringePumpADCReadCtr = 0; // Reset request flags resetSyringePumpRequestFlags(); } /*********************************************************************//** * @brief * The resetSyringePumpRequestFlags function resets request flags. * @details Inputs: none * @details Outputs: syringePumpSetRate, syringePumpRetractRequested * @return TRUE if request accepted, FALSE if not *************************************************************************/ static void resetSyringePumpRequestFlags( void ) { syringePumpRetractRequested = FALSE; syringePumpPrimeRequested = FALSE; syringePumpBolusRequested = FALSE; syringePumpContinuousRequested = FALSE; syringePumpDACVrefSetRequested = FALSE; } /*********************************************************************//** * @brief * The stopSyringePump function requests syringe pump be stopped. * @details Inputs: none * @details Outputs: syringePumpSetRate, syringePumpRetractRequested, syringePumpState * @return TRUE if request accepted, FALSE if not *************************************************************************/ void stopSyringePump( void ) { syringePumpSetRate = 0.0; setFPGASyringePumpStepToggleTime( SYRINGE_PUMP_MICROSTEP_TOGGLE_TIME_FOR_STOP ); syringePumpState = SYRINGE_PUMP_OFF_STATE; } /*********************************************************************//** * @brief * The retractSyringePump function requests retract operation. * @details Inputs: syringePumpState * @details Outputs: syringePumpSetRate, syringePumpRetractRequested * @return TRUE if request accepted, FALSE if not *************************************************************************/ BOOL retractSyringePump( void ) { if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( FALSE == isSyringeDetected() ) ) { syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; syringePumpRetractRequested = TRUE; } return syringePumpRetractRequested; } /*********************************************************************//** * @brief * The primeSyringePump function requests plunger seek and prime operations. * @details Inputs: syringePumpState * @details Outputs: syringePumpSetRate, syringePumpBolusRequested * @return TRUE if request accepted, FALSE if not *************************************************************************/ BOOL primeSyringePump( void ) { if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( TRUE == isSyringeDetected() ) && ( TRUE == isSyringePumpHome() ) ) { syringePumpSetRate = SYRINGE_PUMP_SEEK_RATE; syringePumpPrimeRequested = TRUE; } return syringePumpPrimeRequested; } /*********************************************************************//** * @brief * The startHeparinBolus function requests Heparin bolus delivery. * @details Inputs: syringePumpState * @details Outputs: syringePumpSetRate, syringePumpBolusRequested * @param flowRate desired bolus flow rate (in mL/hr) * @return TRUE if request accepted, FALSE if not *************************************************************************/ BOOL startHeparinBolus( F32 flowRate ) { if ( ( flowRate >= MIN_HEPARIN_BOLUS_RATE ) && ( flowRate <= MAX_HEPARIN_BOLUS_RATE ) && ( TRUE == isSyringeDetected() ) && ( FALSE == isSyringePumpHome() ) ) { if ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) { syringePumpSetRate = flowRate; syringePumpBolusRequested = TRUE; } } else { // TODO - s/w fault } return syringePumpBolusRequested; } /*********************************************************************//** * @brief * The startHeparinContinuous function requests Heparin continuous delivery. * @details Inputs: syringePumpState * @details Outputs: syringePumpSetRate, syringePumpContinuousRequested * @param flowRate desired flow rate (in mL/hr) * @return TRUE if request accepted, FALSE if not *************************************************************************/ BOOL startHeparinContinuous( F32 flowRate ) { if ( ( flowRate >= MIN_HEPARIN_CONTINUOUS_RATE ) && ( flowRate <= MAX_HEPARIN_CONTINUOUS_RATE ) && ( TRUE == isSyringeDetected() ) && ( FALSE == isSyringePumpHome() ) ) { if ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) { syringePumpSetRate = flowRate; syringePumpContinuousRequested = TRUE; } } else { // TODO - s/w fault } return syringePumpContinuousRequested; } /*********************************************************************//** * @brief * The setSyringePumpDACVref function requests to set the DAC Vref setting. * @details Inputs: none * @details Outputs: syringePumpDACVrefSetRequested, syringePumpDACVref * @param vRef voltage to set DAC Vref to (in V) * @return TRUE if request accepted, FALSE if not *************************************************************************/ BOOL setSyringePumpDACVref( F32 vRef ) { if ( ( vRef >= 0.0 ) && ( vRef <= 3.3 ) ) { if ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) { syringePumpDACVref = vRef; syringePumpDACVrefSetRequested = TRUE; } } else { // TODO - s/w fault } return syringePumpDACVrefSetRequested; } /*********************************************************************//** * @brief * The getPublishSyringePumpDataInterval function gets the syringe pump data * publication interval. * @details Inputs: syringePumpDataPublishInterval * @details Outputs: none * @return the current syringe pump data publication interval (in task intervals). *************************************************************************/ static U32 getPublishSyringePumpDataInterval( void ) { U32 result = syringePumpDataPublishInterval.data; if ( OVERRIDE_KEY == syringePumpDataPublishInterval.override ) { result = syringePumpDataPublishInterval.ovData; } return result; } /*********************************************************************//** * @brief * The getSyringePumpVolumeDelivered function gets the current syringe pump * volume delivered. * @details Inputs: syringePumpVolumeDelivered * @details Outputs: none * @return the current syringe pump volume delivered (in mL). *************************************************************************/ F32 getSyringePumpVolumeDelivered( void ) { F32 result = syringePumpVolumeDelivered.data; if ( OVERRIDE_KEY == syringePumpVolumeDelivered.override ) { result = syringePumpVolumeDelivered.ovData; } return result; } /*********************************************************************//** * @brief * The getSyringePumpMeasRate function gets the current syringe pump measured * rate. * @details Inputs: syringePumpMeasRate * @details Outputs: none * @return the current syringe pump measured rate (in mL/hr). *************************************************************************/ static F32 getSyringePumpMeasRate( void ) { F32 result = syringePumpMeasRate.data; if ( OVERRIDE_KEY == syringePumpMeasRate.override ) { result = syringePumpMeasRate.ovData; } return result; } /*********************************************************************//** * @brief * The getSyringePumpPosition function gets the current syringe pump * position. * @details Inputs: syringePumpPosition * @details Outputs: none * @return the current syringe pump syringe position (in steps). *************************************************************************/ static S32 getSyringePumpPosition( void ) { S32 result = syringePumpPosition.data; if ( OVERRIDE_KEY == syringePumpPosition.override ) { result = syringePumpPosition.ovData; } return result; } /*********************************************************************//** * @brief * The getSyringePumpSyringeDetectorV function gets the current syringe pump * syringe detect signal. * @details Inputs: syringePumpMeasSyringeDetectionSwitch * @details Outputs: none * @return the current syringe pump syringe detect signal (in V). *************************************************************************/ static F32 getSyringePumpSyringeDetectorV( void ) { F32 result = syringePumpMeasSyringeDetectionSwitch.data; if ( OVERRIDE_KEY == syringePumpMeasSyringeDetectionSwitch.override ) { result = syringePumpMeasSyringeDetectionSwitch.ovData; } return result; } /*********************************************************************//** * @brief * The getSyringePumpHomeDetectorV function gets the current syringe pump * home detect signal. * @details Inputs: syringePumpMeasHome * @details Outputs: none * @return the current syringe pump home detect signal (in V). *************************************************************************/ static F32 getSyringePumpHomeDetectorV( void ) { F32 result = syringePumpMeasHome.data; if ( OVERRIDE_KEY == syringePumpMeasHome.override ) { result = syringePumpMeasHome.ovData; } return result; } /*********************************************************************//** * @brief * The getSyringePumpForceV function gets the current syringe pump force. * @details Inputs: syringePumpMeasForce * @details Outputs: none * @return the current syringe pump force (in V). *************************************************************************/ static F32 getSyringePumpForceV( void ) { F32 result = syringePumpMeasForce.data; if ( OVERRIDE_KEY == syringePumpMeasForce.override ) { result = syringePumpMeasForce.ovData; } return result; } /*********************************************************************//** * @brief * The isSyringeDetected function determines whether a syringe is currently * detected. * @details Inputs: syringePumpMeasSyringeDetectionSwitch * @details Outputs: none * @return TRUE if syringe detected, FALSE if not *************************************************************************/ BOOL isSyringeDetected( void ) { BOOL result = FALSE; if ( getSyringePumpSyringeDetectorV() >= SYRINGE_PUMP_SYRINGE_DETECT_THRESHOLD_V ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The isSyringePumpHome function determines whether the syringe drive position * is at the home position. * @details Inputs: syringePumpMeasHome * @details Outputs: none * @return TRUE if home detected, FALSE if not *************************************************************************/ BOOL isSyringePumpHome( void ) { BOOL result = FALSE; if ( getSyringePumpHomeDetectorV() <= SYRINGE_PUMP_HOME_DETECT_THRESHOLD_V ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The isSyringePumpStopped function determines whether the syringe pump * is currently stopped. * @details Inputs: syringePumpState * @details Outputs: none * @return TRUE if syringe pump is currently stopped, FALSE if running. *************************************************************************/ BOOL isSyringePumpStopped( void ) { BOOL result = FALSE; if ( ( syringePumpState > SYRINGE_PUMP_OFF_STATE ) || ( syringePumpState < SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE ) ) { result = TRUE; } return result; } /*********************************************************************//** * @brief * The execSyringePumpMonitor function executes the syringe pump monitor. * @details Inputs: FPGA syringe pump readings * @details Outputs: Alarm(s) may be triggered * @return none *************************************************************************/ static void execSyringePumpMonitor( void ) { S32 encPosition = getFPGASyringePumpEncoderPosition(); U08 pmpStatus = getFPGASyringePumpStatus(); U08 encStatus = getFPGASyringePumpEncoderStatus(); U08 adcReadCtr = getFPGASyringePumpADCReadCounter(); U08 adcDACStatus= getFPGASyringePumpADCandDACStatus(); // Get latest ADC data and convert to V syringePumpMeasHome.data = ( (F32)getFPGASyringePumpADCChannel2() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; syringePumpMeasSyringeDetectionSwitch.data = ( (F32)getFPGASyringePumpADCChannel1() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; syringePumpMeasForce.data = ( (F32)getFPGASyringePumpADCChannel0() * SYRINGE_PUMP_ADC_REF_V ) / SYRINGE_PUMP_ADC_FULL_SCALE_BITS; // Apply home offset to encoder position syringePumpPosition.data = encPosition - syringePumpHomePositionOffset; // Calculate volume delivered from position syringePumpVolumeDelivered.data = (F32)(syringePumpPosition.data - syringePumpVolumeStartPosition) / SYRINGE_ENCODER_COUNTS_PER_ML; calcSafetyVolumeDelivered(); // Calculate measured rate (mL/hr) calcMeasRate(); if ( syringePumpDACVrefWriteInProgress != TRUE ) { // Check ADC read is fresh if ( lastSyringePumpADCReadCtr == adcReadCtr ) { // TODO - fault } lastSyringePumpADCReadCtr = adcReadCtr; } } /*********************************************************************//** * @brief * The execSyringePump function executes the syringe pump control state machine. * @details Inputs: syringePumpState * @details Outputs: syringePumpState * @return none *************************************************************************/ void execSyringePump( void ) { // Execute syringe pump monitor execSyringePumpMonitor(); // 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; case SYRINGE_PUMP_SEEK_STATE: syringePumpState = handleSyringePumpSeekState(); break; case SYRINGE_PUMP_PRIME_STATE: syringePumpState = handleSyringePumpPrimeState(); break; case SYRINGE_PUMP_HEP_BOLUS_STATE: syringePumpState = handleSyringePumpBolusState(); break; case SYRINGE_PUMP_HEP_CONTINUOUS_STATE: syringePumpState = handleSyringePumpContinuousState(); break; case SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE: syringePumpState = handleSyringePumpCalibrateForceSensorState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, 0, syringePumpState ) // TODO - replace 0 with appropriate enum break; } resetSyringePumpRequestFlags(); // Publish syringe pump data on interval publishSyringePumpData(); } /*********************************************************************//** * @brief * The handleSyringePumpInitState function handles the initialize state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpInitState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; // Set FPGA rate to zero setFPGASyringePumpStepToggleTime( SYRINGE_PUMP_MICROSTEP_TOGGLE_TIME_FOR_STOP ); // Set FPGA control bits for ADC/DAC setFPGASyringePumpADCandDACControlFlags( SYRINGE_PUMP_ADC_DAC_CONTROL_RD_DAC_ON_ADC | SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_ADC ); // Set FPGA control bits for stepper motor (enable, no sleep, dir=FWD, ...) setFPGASyringePumpControlFlags( SYRINGE_PUMP_CONTROL_RUN_REVERSE ); return result; } /*********************************************************************//** * @brief * The handleSyringePumpOffState function handles the off state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpOffState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; // TODO - check position is not changing while stopped // Check for request flags if ( TRUE == syringePumpRetractRequested ) { result = SYRINGE_PUMP_RETRACT_STATE; } else if ( TRUE == syringePumpPrimeRequested ) { result = SYRINGE_PUMP_SEEK_STATE; } else if ( TRUE == syringePumpBolusRequested ) { result = SYRINGE_PUMP_HEP_BOLUS_STATE; } else if ( TRUE == syringePumpContinuousRequested ) { result = SYRINGE_PUMP_HEP_CONTINUOUS_STATE; } else if ( TRUE == syringePumpDACVrefSetRequested ) { U16 vRef = (U16)( ( syringePumpDACVref / SYRINGE_PUMP_ADC_REF_V ) * SYRINGE_PUMP_DAC_FULL_SCALE_BITS ); setFPGASyringePumpDACOutputLevel( vRef ); setFPGASyringePumpADCandDACControlFlags( SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_DAC ); syringePumpDACVrefWriteInProgress = TRUE; result = SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE; } // 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 ) ) { if ( SYRINGE_PUMP_RETRACT_STATE == result ) { // Set fpga direction to reverse setFPGASyringePumpControlFlags( SYRINGE_PUMP_CONTROL_RUN_REVERSE ); } else { // Set fpga direction to forward setFPGASyringePumpControlFlags( SYRINGE_PUMP_CONTROL_RUN_FORWARD ); } // Calculate target FPGA rate from set rate in mL/hr converted to microstep toggle interval in uSec calcStepperToggleTimeForTargetRate( syringePumpSetRate ); setFPGASyringePumpStepToggleTime( syringePumpRampUpToggleTime ); } // Reset ramp up timer syringePumpRampTimerCtr = 1; return result; } /*********************************************************************//** * @brief * The handleSyringePumpRetractState function handles the retract state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpRetractState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_RETRACT_STATE; // Handle ramp up rampSyringePump(); // Stop retract when home position is detected if ( TRUE == isSyringePumpHome() ) { stopSyringePump(); syringePumpHomePositionOffset = getFPGASyringePumpEncoderPosition(); syringePumpPosition.data = 0; syringePumpVolumeStartPosition = 0; syringePumpVolumeDelivered.data = 0.0; result = SYRINGE_PUMP_OFF_STATE; } // Stop retract if syringe is detected (should not have a syringe loaded during retract) else if ( TRUE == isSyringeDetected() ) { stopSyringePump(); result = SYRINGE_PUMP_OFF_STATE; // TODO - alarm } return result; } /*********************************************************************//** * @brief * The handleSyringePumpSeekState function handles the seek plunger state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpSeekState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_SEEK_STATE; BOOL stopPump = FALSE; // Handle ramp up rampSyringePump(); // Is plunger contact detected? if ( ( syringePumpRampTimerCtr > 800 ) || ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) ) { syringePumpVolumeDelivered.data = 0.0; syringePumpVolumeStartPosition = syringePumpPosition.data; syringePumpSetRate = SYRINGE_PUMP_PRIME_RATE; // Calculate target FPGA rate from set rate in mL/hr converted to microstep toggle interval in uSec calcStepperToggleTimeForTargetRate( syringePumpSetRate ); setFPGASyringePumpStepToggleTime( syringePumpRampUpToggleTime ); result = SYRINGE_PUMP_PRIME_STATE; } // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); // If anything found that would require stopping the pump, stop pump and go to off state if ( TRUE == stopPump ) { stopSyringePump(); result = SYRINGE_PUMP_OFF_STATE; } return result; } /*********************************************************************//** * @brief * The handleSyringePumpPrimeState function handles the prime state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpPrimeState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_PRIME_STATE; BOOL stopPump = FALSE; // Handle ramp up rampSyringePump(); // Has prime volume been delivered? if ( getSyringePumpVolumeDelivered() >= SYRINGE_PUMP_PRIME_VOLUME_ML ) { stopPump = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpVolumeStartPosition = syringePumpPosition.data; } // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); // If anything found that would require stopping the pump, stop pump and go to off state if ( TRUE == stopPump ) { stopSyringePump(); result = SYRINGE_PUMP_OFF_STATE; } return result; } /*********************************************************************//** * @brief * The handleSyringePumpBolusState function handles the bolus delivery state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpBolusState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_HEP_BOLUS_STATE; BOOL stopPump = FALSE; // Handle ramp up rampSyringePump(); // Is bolus completed? if ( getSyringePumpVolumeDelivered() >= 2.0 ) // TODO - get bolus volume from treatment params { stopPump = TRUE; } // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); // TODO - check volume vs. safety volume (fault) // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); // TODO - check for meas. speed > 1.05 mL/hr for TBD sec (fault) // If anything found that would require stopping the pump, stop pump and go to off state if ( TRUE == stopPump ) { stopSyringePump(); result = SYRINGE_PUMP_OFF_STATE; } return result; } /*********************************************************************//** * @brief * The handleSyringePumpContinuousState function handles the continuous state * of the syringe pump control state machine. * @details Inputs: TBD * @details Outputs: TBD * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpContinuousState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_HEP_CONTINUOUS_STATE; BOOL stopPump = FALSE; // Handle ramp up rampSyringePump(); // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); // TODO - check volume vs. safety volume (fault) // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); // TODO - check for meas. speed > 1.05 mL/hr for TBD sec (fault) // TODO - check position > max travel (alarm for empty syringe) // If anything found that would require stopping the pump, stop pump and go to off state if ( TRUE == stopPump ) { stopSyringePump(); result = SYRINGE_PUMP_OFF_STATE; } return result; } /*********************************************************************//** * @brief * The checkOcclusionOrEmpty function checks the force sensor for excessive * pressure. Would indicate occlusion or jam or empty syringe. * @details Inputs: TBD * @details Outputs: TBD * @param stopPump flag passed in by caller indicating whether pump should be stopped * @return TRUE if occlusion/empty condition detected, FALSE if not *************************************************************************/ static BOOL checkOcclusionOrEmpty( BOOL stopPump ) { BOOL result = stopPump; if ( getSyringePumpForceV() >= SYRINGE_FORCE_OCCLUSION_THRESHOLD_V ) { result = TRUE; // TODO - alarm (alarm for occlusion or empty syringe depending on position) } return result; } /*********************************************************************//** * @brief * The checkSyringeRemoved function checks whether the syringe has been removed. * This function should only be called from states that require the syringe to * be installed. * @details Inputs: TBD * @details Outputs: TBD * @param stopPump flag passed in by caller indicating whether pump should be stopped * @return TRUE if syringe removed, FALSE if not *************************************************************************/ static BOOL checkSyringeRemoved( BOOL stopPump ) { BOOL result = stopPump; if ( FALSE == isSyringeDetected() ) { result = TRUE; // TODO - alarm } return result; } /*********************************************************************//** * @brief * The checkMaxTravel function checks whether a maximum travel (position) * has been exceeded. This threshold is state dependent so the calling function * must provide the maximum position to apply. * @details Inputs: TBD * @details Outputs: TBD * @param stopPump flag passed in by caller indicating whether pump should be stopped * @param maxPos maximum position allowed in current state * @return TRUE if max travel exceeded, FALSE if not *************************************************************************/ static BOOL checkMaxTravel( BOOL stopPump, S32 maxPos ) { BOOL result = stopPump; return result; } /*********************************************************************//** * @brief * The checkMaxMeasRate function checks whether the measured rate is exceeding * a maximum rate (in mL/hr). This threshold is state dependent so the calling * function must provide the maximum rate to apply. * @details Inputs: TBD * @details Outputs: TBD * @param stopPump flag passed in by caller indicating whether pump should be stopped * @param maxRate maximum measured rate allowed in current state * @return TRUE if max rate exceeded, FALSE if not *************************************************************************/ static BOOL checkMaxMeasRate( BOOL stopPump, F32 maxRate ) { BOOL result = stopPump; return result; } /*********************************************************************//** * @brief * The checkVolumeVsSafetyVolume function checks whether the volume delivered * and the safety volume delivered have diverged too much. The threshold * is state dependent so the calling function must provide the tolerance (in +/- %) * to apply. * @details Inputs: TBD * @details Outputs: TBD * @param stopPump flag passed in by caller indicating whether pump should be stopped * @param pctMargin percent tolerance allowed between volume and safety volume * @return TRUE if volume check fails, FALSE if not *************************************************************************/ static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ) { BOOL result = stopPump; return result; } /*********************************************************************//** * @brief * The handleSyringePumpCalibrateForceSensorState function handles the * calibrate force sensor state of the syringe pump control state machine. * of the pressure/occlusion monitor state machine. * @details Inputs: DAC status * @details Outputs: syringePumpDACVrefWriteInProgress, ADC read mode restored * @return next state *************************************************************************/ static SYRINGE_PUMP_STATE_T handleSyringePumpCalibrateForceSensorState( void ) { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_CONFIG_FORCE_SENSOR_STATE; // Wait for DAC setting write to EEPROM to complete if ( ( getFPGASyringePumpADCandDACStatus() & SYRINGE_PUMP_ADC_DAC_ERROR_COUNT_DAC_WR_DONE ) != 0 ) { syringePumpDACVrefWriteInProgress = FALSE; // Switch back from DAC to ADC control setFPGASyringePumpADCandDACControlFlags( SYRINGE_PUMP_ADC_DAC_CONTROL_RD_DAC_ON_ADC | SYRINGE_PUMP_ADC_DAC_CONTROL_ENABLE_ADC ); // Back to off state result = SYRINGE_PUMP_OFF_STATE; } return result; } /*********************************************************************//** * @brief * The rampSyringePump function handles the ramp-up for the syringe pump. * @details Inputs: syringePumpRampTimerCtr, syringePumpSetToggleTime * @details Outputs: syringePumpRampUpToggleTime * @return none *************************************************************************/ static void rampSyringePump( void ) { syringePumpRampTimerCtr++; if ( syringePumpRampUpToggleTime > syringePumpSetToggleTime ) { syringePumpRampUpToggleTime = (U32)((F32)SYRINGE_PUMP_START_RAMP_SPEED / (F32)( syringePumpRampTimerCtr * syringePumpRampTimerCtr * syringePumpRampTimerCtr / SYRINGE_PUMP_RAMP_DIVISOR )); if ( syringePumpRampUpToggleTime > syringePumpSetToggleTime ) { setFPGASyringePumpStepToggleTime( syringePumpRampUpToggleTime ); } else { setFPGASyringePumpStepToggleTime( syringePumpSetToggleTime ); } } } /*********************************************************************//** * @brief * The calcStepperToggleTimeForTargetRate function calculates the stepper * toggle period for a given rate. * @details Inputs: none * @details Outputs: syringePumpSetToggleTime, syringePumpRampUpToggleTime * @param rate the rate (in mL/hr) to calculate stepper toggle period for * @return none *************************************************************************/ static void calcStepperToggleTimeForTargetRate( F32 rate ) { F32 conv = 0.0; // Convert given rate to stepper toggle period conv = rate * SYRINGE_MICRO_STEPS_PER_ML; // = uSteps/hr conv /= (F32)( MIN_PER_HOUR * SEC_PER_MIN); // = uSteps/sec conv /= MICRO_SECONDS_PER_SECOND; // = uSteps/uSec conv *= SYRINGE_TOGGLES_PER_STEP; // = toggles/uSec conv = 1.0 / conv; // = uSec/toggle // Set stepper toggle time to calculated value syringePumpSetToggleTime = FLOAT_TO_INT_WITH_ROUND( conv ); // Set stepper ramp toggle time to initial ramp up speed initially syringePumpRampUpToggleTime = SYRINGE_PUMP_START_RAMP_SPEED; } /*********************************************************************//** * @brief * The calcMeasRate function calculates the measured rate from a given delta * position in last 10 ms. * @details Inputs: syringePumpPosition1SecAgo, syringePumpSpeedCalcTimerCounter * @details Outputs: syringePumpMeasRate, syringePumpSpeedCalcTimerCounter * @return none *************************************************************************/ static void calcMeasRate( void ) { if ( ++syringePumpSpeedCalcTimerCounter > SYRINGE_PUMP_SPEED_CHECK_INTERVAL ) { S32 countsPerSec = syringePumpMeasRate.data - syringePumpPosition1SecAgo; S32 countsPerHr = countsPerSec * ( MIN_PER_HOUR * SEC_PER_MIN); F32 mLPerHr = (F32)countsPerHr / SYRINGE_ENCODER_COUNTS_PER_ML; syringePumpMeasRate.data = mLPerHr; syringePumpSpeedCalcTimerCounter = 0; } } /*********************************************************************//** * @brief * The calcSafetyVolumeDelivered function calculates the safety volume from * commanded rate over time (last 10 ms). * @details Inputs: syringePumpSetRate * @details Outputs: syringePumpSafetyVolumeDelivered * @return none *************************************************************************/ static void calcSafetyVolumeDelivered( void ) { syringePumpSafetyVolumeDelivered += ( syringePumpSetRate / ( MIN_PER_HOUR * SEC_PER_MIN * ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ) ); } /*********************************************************************//** * @brief * The publishSyringePumpData function publishes syringe pump data at the * set interval. * @details Inputs: latest syringe pump data, syringePumpDataPublicationTimerCounter * @details Outputs: Syringe pump data are published to CAN bus. * @return none *************************************************************************/ static void publishSyringePumpData( void ) { // Publish syringe pump data on interval if ( ++syringePumpDataPublicationTimerCounter >= getPublishSyringePumpDataInterval() ) { SYRINGE_PUMP_DATA_PAYLOAD_T data; data.syringePumpMeasForce = getSyringePumpForceV(); data.syringePumpMeasHome = getSyringePumpHomeDetectorV(); data.syringePumpMeasRate = getSyringePumpMeasRate(); data.syringePumpMeasSwitch = getSyringePumpSyringeDetectorV(); data.syringePumpPosition = getSyringePumpPosition(); data.syringePumpSetRate = syringePumpSetRate; data.syringePumpState = (U32)syringePumpState; data.syringePumpVolumeDelivered = getSyringePumpVolumeDelivered(); broadcastSyringePumpData( data ); syringePumpDataPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The execSyringePumpTest function executes the state machine for the * syringe pump self-test. * @details Inputs: none * @details Outputs: none * @return the current state of the syringe pump self-test. *************************************************************************/ SELF_TEST_STATUS_T execSyringePumpTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_FAILED; // TODO - implement self-test(s) return result; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetSyringePumpDataPublishIntervalOverride function overrides the * syringe pump data publish interval. * @details Inputs: none * @details Outputs: syringePumpDataPublishInterval * @param value override syringe pump data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpDataPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; result = TRUE; syringePumpDataPublishInterval.ovData = intvl; syringePumpDataPublishInterval.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpDataPublishIntervalOverride function resets the override * of the syringe pump data publish interval. * @details Inputs: none * @details Outputs: syringePumpDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpDataPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpDataPublishInterval.override = OVERRIDE_RESET; syringePumpDataPublishInterval.ovData = syringePumpDataPublishInterval.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSyringePumpOperationRequest function requests a given syringe pump * operation. * @details Inputs: none * @details Outputs: TBD * @param opParams record containing the requested operation and its parameters * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSyringePumpOperationRequest( SYRINGE_PUMP_OP_PAYLOAD_T opParams ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { SYRINGE_PUMP_OPERATION_T op = (SYRINGE_PUMP_OPERATION_T)(opParams.syringePumpOp); switch ( op ) { case SYRINGE_PUMP_OP_STOP: stopSyringePump(); result = TRUE; break; case SYRINGE_PUMP_OP_RETRACT: result = retractSyringePump(); break; case SYRINGE_PUMP_OP_SEEK_AND_PRIME: result = primeSyringePump(); break; case SYRINGE_PUMP_OP_BOLUS: result = startHeparinBolus( opParams.rate ); break; case SYRINGE_PUMP_OP_CONTINUOUS: result = startHeparinContinuous( opParams.rate ); break; default: // Ok, just ignore and we will return FALSE rejecting request break; } } return result; } /*********************************************************************//** * @brief * The testSetSyringePumpMeasuredRateOverride function overrides the measured * rate of the syringe pump. * @details Inputs: none * @details Outputs: syringePumpMeasRate * @param value override syringe pump measured rate with this value (in mL/hr) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpMeasuredRateOverride( F32 value ) { BOOL result = FALSE; if ( ( TRUE == isTestingActivated() ) && ( value <= SYRINGE_PUMP_MAX_RATE ) ) { result = TRUE; syringePumpMeasRate.ovData = value; syringePumpMeasRate.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpMeasuredRateOverride function resets the override * of the syringe pump measured rate. * @details Inputs: none * @details Outputs: syringePumpMeasRate * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpMeasuredRateOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpMeasRate.override = OVERRIDE_RESET; syringePumpMeasRate.ovData = syringePumpMeasRate.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetSyringePumpMeasuredForceOverride function overrides the measured * force analog signal of the syringe pump. * @details Inputs: none * @details Outputs: syringePumpMeasForce * @param value override syringe pump measured force signal with this value (in V) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpMeasuredForceOverride( F32 value ) { BOOL result = FALSE; if ( ( TRUE == isTestingActivated() ) && ( value >= 0.0 ) && ( value <= SYRINGE_PUMP_ADC_REF_V ) ) { result = TRUE; syringePumpMeasForce.ovData = value; syringePumpMeasForce.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpMeasuredForceOverride function resets the override * of the syringe pump measured force analog signal. * @details Inputs: none * @details Outputs: syringePumpMeasForce * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpMeasuredForceOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpMeasForce.override = OVERRIDE_RESET; syringePumpMeasForce.ovData = syringePumpMeasForce.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetSyringePumpMeasuredSyringeDetectOverride function overrides the measured * syringe detect analog signal of the syringe pump. * @details Inputs: none * @details Outputs: syringePumpMeasSyringeDetectionSwitch * @param value override syringe pump measured syringe detection signal with this value (in V) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpMeasuredSyringeDetectOverride( F32 value ) { BOOL result = FALSE; if ( ( TRUE == isTestingActivated() ) && ( value >= 0.0 ) && ( value <= SYRINGE_PUMP_ADC_REF_V ) ) { result = TRUE; syringePumpMeasSyringeDetectionSwitch.ovData = value; syringePumpMeasSyringeDetectionSwitch.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpMeasuredSyringeDetectOverride function resets the override * of the syringe pump measured syringe detect analog signal. * @details Inputs: none * @details Outputs: syringePumpMeasSyringeDetectionSwitch * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpMeasuredSyringeDetectOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpMeasSyringeDetectionSwitch.override = OVERRIDE_RESET; syringePumpMeasSyringeDetectionSwitch.ovData = syringePumpMeasSyringeDetectionSwitch.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetSyringePumpMeasuredHomeOverride function overrides the measured * home analog signal of the syringe pump. * @details Inputs: none * @details Outputs: syringePumpMeasHome * @param value override syringe pump measured home signal with this value (in V) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpMeasuredHomeOverride( F32 value ) { BOOL result = FALSE; if ( ( TRUE == isTestingActivated() ) && ( value >= 0.0 ) && ( value <= SYRINGE_PUMP_ADC_REF_V ) ) { result = TRUE; syringePumpMeasHome.ovData = value; syringePumpMeasHome.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpMeasuredHomeOverride function resets the override * of the syringe pump measured home analog signal. * @details Inputs: none * @details Outputs: syringePumpMeasHome * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpMeasuredHomeOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpMeasHome.override = OVERRIDE_RESET; syringePumpMeasHome.ovData = syringePumpMeasHome.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetSyringePumpMeasuredPositionOverride function overrides the measured * position of the syringe pump. * @details Inputs: none * @details Outputs: syringePumpPosition * @param value override syringe pump measured position with this value (in encoder counts) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpMeasuredPositionOverride( S32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpPosition.ovData = value; syringePumpPosition.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpMeasuredPositionOverride function resets the override * of the syringe pump measured position. * @details Inputs: none * @details Outputs: syringePumpPosition * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpMeasuredPositionOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpPosition.override = OVERRIDE_RESET; syringePumpPosition.ovData = syringePumpPosition.ovInitData; } return result; } /*********************************************************************//** * @brief * The testSetSyringePumpMeasuredVolumeOverride function overrides the measured * rate of the syringe pump measured volume delivered. * @details Inputs: none * @details Outputs: syringePumpVolumeDelivered * @param value override syringe pump measured volume with this value (in mL) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetSyringePumpMeasuredVolumeOverride( F32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpVolumeDelivered.ovData = value; syringePumpVolumeDelivered.override = OVERRIDE_KEY; } return result; } /*********************************************************************//** * @brief * The testResetSyringePumpMeasuredVolumeOverride function resets the override * of the syringe pump measured volume delivered. * @details Inputs: none * @details Outputs: syringePumpVolumeDelivered * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetSyringePumpMeasuredVolumeOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { result = TRUE; syringePumpVolumeDelivered.override = OVERRIDE_RESET; syringePumpVolumeDelivered.ovData = syringePumpVolumeDelivered.ovInitData; } return result; } /**@}*/