Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r880dd112d3477bf4cbec0865126802f8a3d3f910 -r4efd42acbcbde896a1e9e532db77a72bebea0bdc --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 880dd112d3477bf4cbec0865126802f8a3d3f910) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 4efd42acbcbde896a1e9e532db77a72bebea0bdc) @@ -1,45 +1,45 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 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) 15-Nov-2021 +* @author (last) Dara Navaei +* @date (last) 04-Jan-2022 * * @author (original) Sean Nash * @date (original) 04-Mar-2021 * ***************************************************************************/ #include - -#include "AlarmMgmt.h" + +#include "AlarmMgmt.h" #include "FPGA.h" #include "ModeTreatmentParams.h" -#include "NVDataMgmt.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SafetyShutdown.h" -#include "SyringePump.h" -#include "SystemCommMessages.h" -#include "TaskPriority.h" -#include "Timers.h" - -/** - * @addtogroup SyringePump - * @{ - */ - -// ********** private definitions ********** - -/// Default publication interval for syringe pump data. +#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 ) #define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 1 * MS_PER_SECOND ) ///< Delay 1 second then check for syringe pump prime occlusion. -#define BD_SYRINGE_ID_RADIUS_CM ( 1.402 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. +#define BD_SYRINGE_ID_RADIUS_CM ( 1.4427 / 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. @@ -56,9 +56,9 @@ /// 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 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 MIN_HEPARIN_CONTINUOUS_RATE 0.2 ///< 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). @@ -71,7 +71,7 @@ #define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE 2000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. #define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. -#define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 500 ///< Alarm persistence period (in ms) for syringe pump off check alarms. +#define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. #define SYRINGE_PUMP_OCCLUSION_ALARM_PERSISTENCE 30 ///< Alarm persistence period (in ms) for syringe pump occlusion alarms. #define SYRINGE_PUMP_ADC_READ_PERSISTENCE 100 ///< Syringe pump ADC stale read alarm persistence time (in ms). @@ -94,7 +94,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 postion. -#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) ///< get syringe volume from home to empty (11 mL is placeholder) +#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) /// Minimum retract position. @@ -128,7 +128,7 @@ #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 | @@ -155,32 +155,32 @@ #define SYRINGE_PUMP_RAMP_STALL_RETRIES 3 ///< Syringe pump ramp stall retries allowed. #define SYRINGE_PUMP_STALL_SPEED_THRESHOLD 0.05 ///< Minimum syringe pump speed to be considered not stalled. -/// Defined states for the syringe pump control state machine. -typedef enum SyringePump_States -{ +/// 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_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; - -// ********** private data ********** - -static SYRINGE_PUMP_STATE_T syringePumpState; ///< Current state of syringe pump control state machine. + NUM_OF_SYRINGE_PUMP_STATES ///< Number of syringe pump control states +} SYRINGE_PUMP_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 syringePumpRampTimerCtr; ///< Used to track ramp up time. static HEPARIN_STATE_T heparinDeliveryState; ///< Current state of Heparin delivery. - + /// 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_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). @@ -228,10 +228,10 @@ static U32 syringeOcclusionDelayStartTime; ///< Used to calculate the 1 second delay time before check for prime occlusion. static HD_HEPARIN_FORCE_SENSOR_CAL_RECORD_T forceSensorCalRecord; ///< HD heparin force sensor calibration record. -// ********** private function prototypes ********** +// ********** private function prototypes ********** static void resetSyringePumpRequestFlags( void ); -static void execSyringePumpMonitor( void ); +static void execSyringePumpMonitor( void ); static S32 getSyringePumpPosition( void ); static F32 getSyringePumpMeasRate( void ); static F32 getSyringePumpSyringeDetectorV( void ); @@ -241,7 +241,7 @@ static U08 getSyringePumpEncoderStatus( void ); static U08 getSyringePumpADCReadCounter( void ); static U08 getSyringePumpADCandDACStatus( void ); -static SYRINGE_PUMP_STATE_T handleSyringePumpInitState( 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 ); @@ -264,15 +264,15 @@ static BOOL checkForStall( BOOL stopPump ); static void publishSyringePumpData( void ); static BOOL processCalibrationData( void ); - -/*********************************************************************//** - * @brief - * The initSyringePump function initializes the syringe pump module. - * @details Inputs: none - * @details Outputs: syringe pump module initialized. - * @return none - *************************************************************************/ -void initSyringePump( void ) + +/*********************************************************************//** + * @brief + * The initSyringePump function initializes the syringe pump module. + * @details Inputs: none + * @details Outputs: syringe pump module initialized. + * @return none + *************************************************************************/ +void initSyringePump( void ) { U32 i; @@ -321,7 +321,7 @@ 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_ALARM_PERSISTENCE ); - // Reset request flags + // Reset request flags resetSyringePumpRequestFlags(); } @@ -566,7 +566,7 @@ F32 tgtRate = HEPARIN_BOLUS_TARGET_RATE_ML_PER_HR; // fixed rate // If valid to start a bolus, kick it off - if ( FALSE == isSyringePumpHome() ) + if ( ( tgtRate >= MIN_HEPARIN_BOLUS_RATE ) && ( tgtRate <= MAX_HEPARIN_BOLUS_RATE ) && ( FALSE == isSyringePumpHome() ) ) { if ( ( TRUE == isSyringeDetected() ) && ( TRUE == syringePumpPrimeCompleted ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( HEPARIN_STATE_STOPPED == heparinDeliveryState ) ) @@ -941,6 +941,21 @@ /*********************************************************************//** * @brief + * The isSyringePumpRunning function determines whether the syringe pump + * is currently running an operation. + * @details Inputs: syringePumpState + * @details Outputs: none + * @return TRUE if syringe pump operation is currently running, FALSE if not. + *************************************************************************/ +BOOL isSyringePumpRunning( void ) +{ + BOOL result = ( syringePumpState > SYRINGE_PUMP_OFF_STATE ? TRUE : FALSE ); + + return result; +} + +/*********************************************************************//** + * @brief * The execSyringePumpMonitor function executes the syringe pump monitor. * @details Inputs: FPGA syringe pump readings * @details Outputs: Alarm(s) may be triggered @@ -1029,29 +1044,35 @@ } } -/*********************************************************************//** - * @brief - * The execSyringePump function executes the syringe pump control state machine. - * @details Inputs: syringePumpState - * @details Outputs: syringePumpState - * @return none - *************************************************************************/ -void execSyringePump( void ) +/*********************************************************************//** + * @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; - + + // 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 ); + } + + // 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; @@ -1076,15 +1097,15 @@ syringePumpState = handleSyringePumpCalibrateForceSensorState(); break; - default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_SYRINGE_INVALID_STATE, syringePumpState ) - break; - } + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_SYRINGE_INVALID_STATE, syringePumpState ) + break; + } resetSyringePumpRequestFlags(); - - // Publish syringe pump data on interval - publishSyringePumpData(); + + // Publish syringe pump data on interval + publishSyringePumpData(); } /*********************************************************************//** @@ -1112,7 +1133,7 @@ } return result; -} +} /*********************************************************************//** * @brief @@ -1150,9 +1171,6 @@ { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; - isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, FALSE ); // reset direction alarm persistence when pump is off - isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, FALSE ); // reset direction alarm persistence when pump is off - #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() ) ) ) @@ -1290,22 +1308,21 @@ { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_SEEK_STATE; BOOL stopPump = FALSE; + S32 pos = getSyringePumpPosition(); + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + F32 contRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); + U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); + U32 setTxDur = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); + F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ) - HEPARIN_BOLUS_TIME_HR; + F32 txVolume = SYRINGE_PUMP_PRIME_VOLUME_ML + bolusVol + ( hepDurHr * contRate ); + F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_ENCODER_COUNTS_PER_ML; // Handle ramp up rampSyringePump(); - // Is plunger contact detected? - if ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) + // Is plunger contact detected or insufficient Heparin volume detected? + if ( ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) || ( syringeVol < txVolume ) ) { - S32 pos = getSyringePumpPosition(); - F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); - F32 contRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_DISPENSE_RATE ); - U32 preStop = getTreatmentParameterU32( TREATMENT_PARAM_HEPARIN_PRE_STOP_TIME ); - U32 setTxDur = getTreatmentParameterU32( TREATMENT_PARAM_TREATMENT_DURATION ); - F32 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ) - HEPARIN_BOLUS_TIME_HR; - F32 txVolume = bolusVol + ( hepDurHr * contRate ); - F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_MICRO_STEPS_PER_ML; - stopPump = TRUE; syringePumpPlungerFound = TRUE; syringePumpVolumeDelivered.data = 0.0; @@ -1338,7 +1355,6 @@ if ( TRUE == stopPump ) { stopSyringePump(); - retractSyringePump(); result = SYRINGE_PUMP_OFF_STATE; } @@ -1581,14 +1597,15 @@ { S32 pos = getSyringePumpPosition(); - if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) // + // If near empty position, assume syringe is empty + if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) { heparinDeliveryState = HEPARIN_STATE_EMPTY; SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, force ) } else { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, (F32)pos, force ) // reuse this alarm after prime + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, (F32)pos, force ) } result = TRUE; } @@ -1831,7 +1848,7 @@ } } } - + /*********************************************************************//** * @brief * The calcStepperToggleTimeForTargetRate function calculates the stepper @@ -1902,18 +1919,18 @@ 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 >= getU32OverrideValue( &syringePumpDataPublishInterval ) ) +/*********************************************************************//** + * @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 >= getU32OverrideValue( &syringePumpDataPublishInterval ) ) { SYRINGE_PUMP_DATA_PAYLOAD_T data; @@ -1931,11 +1948,11 @@ ( (U32)getSyringePumpEncoderStatus() << SHIFT_16_BITS_FOR_WORD_SHIFT ) | ( (U32)getSyringePumpADCandDACStatus() << SHIFT_8_BITS_FOR_BYTE_SHIFT ) | ( (U32)getSyringePumpADCReadCounter() ); - + 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*)&data.syringePumpVolumeDelivered, sizeof( F32 ) ); - syringePumpDataPublicationTimerCounter = 0; - } + syringePumpDataPublicationTimerCounter = 0; + } } /*********************************************************************//** @@ -1973,63 +1990,63 @@ forceSensorCalRecord.hdHeparinForceSensor.offset = calData.hdHeparinForceSensor.offset; return status; -} - - -/************************************************************************* - * 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; -} +} + +/************************************************************************* + * 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 @@ -2352,7 +2369,7 @@ return result; } - + /*********************************************************************//** * @brief * The testSetSyringePumpStatus function overrides the syringe pump @@ -2533,4 +2550,4 @@ return result; } -/**@}*/ +/**@}*/ Index: firmware/App/Controllers/SyringePump.h =================================================================== diff -u -r09e6cf9de34acf18f6e1138bf56ac0edb4821186 -r4efd42acbcbde896a1e9e532db77a72bebea0bdc --- firmware/App/Controllers/SyringePump.h (.../SyringePump.h) (revision 09e6cf9de34acf18f6e1138bf56ac0edb4821186) +++ firmware/App/Controllers/SyringePump.h (.../SyringePump.h) (revision 4efd42acbcbde896a1e9e532db77a72bebea0bdc) @@ -1,6 +1,6 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 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. @@ -14,24 +14,24 @@ * @date (original) 04-Mar-2021 * ***************************************************************************/ - -#ifndef __SYRINGE_PUMP_H__ -#define __SYRINGE_PUMP_H__ - -#include "HDCommon.h" + +#ifndef __SYRINGE_PUMP_H__ +#define __SYRINGE_PUMP_H__ + +#include "HDCommon.h" #include "HDDefs.h" - -/** - * @defgroup SyringePump SyringePump - * @brief Syringe pump controller/monitor module. Controls the syringe pump - * and monitors status. - * - * @addtogroup SyringePump - * @{ - */ - -// ********** public definitions ********** - + +/** + * @defgroup SyringePump SyringePump + * @brief Syringe pump controller/monitor module. Controls the syringe pump + * and monitors status. + * + * @addtogroup SyringePump + * @{ + */ + +// ********** public definitions ********** + /// Enumeration of syringe pump operations. typedef enum SyringePumpOperations { @@ -68,9 +68,9 @@ U32 syringePumpStatus; } SYRINGE_PUMP_DATA_PAYLOAD_T; -// ********** public function prototypes ********** - -void initSyringePump( void ); +// ********** public function prototypes ********** + +void initSyringePump( void ); void execSyringePump( void ); SELF_TEST_STATUS_T execSyringePumpSelfTest( void ); @@ -95,10 +95,11 @@ BOOL isSyringePlungerFound( void ); BOOL isSyringeVolumeAdequate( void ); BOOL isSyringePumpPrimed( void ); +BOOL isSyringePumpRunning( void ); F32 getSyringePumpVolumeDelivered( void ); -BOOL testSetSyringePumpDataPublishIntervalOverride( U32 value ); -BOOL testResetSyringePumpDataPublishIntervalOverride( void ); +BOOL testSetSyringePumpDataPublishIntervalOverride( U32 value ); +BOOL testResetSyringePumpDataPublishIntervalOverride( void ); BOOL testSyringePumpOperationRequest( SYRINGE_PUMP_OP_PAYLOAD_T opParams ); BOOL testSetSyringePumpMeasuredRateOverride( F32 value ); BOOL testResetSyringePumpMeasuredRateOverride( void ); @@ -120,7 +121,7 @@ BOOL testResetSyringePumpADCandDACStatus( void ); BOOL testSetSyringePumpADCReadCounter( U32 ctr ); BOOL testResetSyringePumpADCReadCounter( void ); - -/**@}*/ - -#endif + +/**@}*/ + +#endif Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r26d736280fef713e7639cd2b98eed975e2eb4353 -r4efd42acbcbde896a1e9e532db77a72bebea0bdc --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 26d736280fef713e7639cd2b98eed975e2eb4353) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 4efd42acbcbde896a1e9e532db77a72bebea0bdc) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 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 SelfTests.c * -* @author (last) Sean Nash -* @date (last) 12-Nov-2021 +* @author (last) Dara Navaei +* @date (last) 04-Jan-2022 * * @author (original) Quang Nguyen * @date (original) 28-Jan-2021 @@ -43,12 +43,12 @@ #define PUMP_SELF_TEST_FLOW_RATE_ML_MIN 100 ///< Self-test pump flow rate in mL/min. #define BLOOD_PUMP_RUN_TIME_PRESSURE_SELF_TEST ( 5 * MS_PER_SECOND ) ///< Pressure self-test time to run blood pump in ms. -#define NORMALIZED_PRESSURE_SELF_TEST_TIME ( 2 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. +#define NORMALIZED_PRESSURE_SELF_TEST_TIME ( 4 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. #define ARTERIAL_PRESSURE_SELF_TEST_LOW_LIMIT_MMHG -50.0 ///< Arterial pressure low limit after running blood pump. #define VENOUS_PRESSURE_SELF_TEST_HIGH_LIMIT_MMHG 400 ///< Venous pressure high limit after running blood pump. -#define NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG 5.0 ///< Difference in pressure readings after return to normal state tolerance (in mmHg). +#define NORMAL_PRESSURE_DIFF_TOLERANCE_MMHG 10.0 ///< Difference in pressure readings after return to normal state tolerance (in mmHg). #define DIP_FLOW_RATE_SETUP_ML_MIN 150 ///< Dialysate inlet pump flow rate during the setup for wet self-test. #define DIP_FLOW_RATE_FIRST_DISPLACEMENT_ML_MIN 100 ///< Dialysate inlet pump flow rate during the first displacement in wet self-test. @@ -58,7 +58,7 @@ #define WET_SELF_TEST_FIRST_DISPLACEMENT_TARGET_VOLUME_ML 100.0 ///< Target of first displacement volume in ml. #define WET_SELF_TEST_SECOND_DISPLACEMENT_TARGET_VOLUME_ML 600.0 ///< Target of second displacement volume in ml. #define WET_SELF_TEST_INTEGRATED_VOLUME_TOLERANCE 5.0 ///< Tolerance on integrated volume in percentage. -#define WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G 1.5 ///< Tolerance in the load cell readings of the displacement in grams. +#define WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G 12.0 ///< Tolerance in the load cell readings of the displacement in grams (2%). #define WET_SELF_TEST_DISPLACEMENT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Time to displace dialysate in wet self-test in ms. #define RESERVOIR_SETTLE_TIME_MS ( 4 * MS_PER_SECOND ) ///< Time allotted for reservoir to settle in ms. @@ -487,6 +487,7 @@ void transitionToWetSelfTests() { F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + signalDialInPumpHardStop(); // turn off DPi that was on in previous dialysate bypass state wetSelfTestsResult = FALSE; currentWetSelfTestsState = WET_SELF_TESTS_START_STATE; settleStartTime = 0; @@ -828,10 +829,9 @@ { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_USED_CARTRIDGE_CHECK_STATE; - BUBBLE_STATUS_T const ADABubbleStatus = getBubbleStatus( ADA ); BUBBLE_STATUS_T const ADVBubbleStatus = getBubbleStatus( ADV ); - if ( ( BUBBLE_DETECTED == ADABubbleStatus ) && ( BUBBLE_DETECTED == ADVBubbleStatus ) && + if ( ( BUBBLE_DETECTED == ADVBubbleStatus ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) && ( AIR_TRAP_LEVEL_AIR == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) ) { @@ -979,21 +979,31 @@ if ( TRUE == useHeparin ) { - if ( TRUE == isSyringePlungerFound() ) + if ( FALSE == isSyringePumpRunning() ) { - if ( TRUE == isSyringePumpPrimed() ) + if ( TRUE == isSyringePlungerFound() ) { - state = DRY_SELF_TESTS_COMPLETE_STATE; + if ( TRUE == isSyringePumpPrimed() ) + { + state = DRY_SELF_TESTS_COMPLETE_STATE; + } + else + { + primeSyringePump(); + } } else { - primeSyringePump(); + if ( TRUE == isAlarmActive( ALARM_ID_HD_SYRINGE_PUMP_NOT_ENOUGH_HEPARIN_ALARM ) ) + { + retractSyringePump(); + } + else if ( TRUE == isSyringePumpHome() ) + { + seekSyringePlunger(); + } } } - else - { - seekSyringePlunger(); - } } else { @@ -1108,7 +1118,6 @@ if ( setupDisplacementVolume <= 0 ) { signalDialInPumpHardStop(); - selfTestBubble( ADA ); selfTestBubble( ADV ); state = WET_SELF_TESTS_BUBBLES_STATE; } @@ -1134,7 +1143,7 @@ { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BUBBLES_STATE; - if ( ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADA ) ) && ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADV ) ) ) + if ( SELF_TEST_STATUS_PASSED == getBubbleSelfTestStatus( ADV ) ) { state = WET_SELF_TESTS_PRIME_CHECK_STATE; } @@ -1162,7 +1171,6 @@ WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_PRIME_CHECK_STATE; *result = SELF_TEST_STATUS_FAILED; - BUBBLE_STATUS_T const ADABubbleStatus = getBubbleStatus( ADA ); BUBBLE_STATUS_T const ADVBubbleStatus = getBubbleStatus( ADV ); #ifndef SKIP_AIR_BUBBLE_CHECK