Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r185d29637c348c3106737da35a88d409e65093ad -r158b4394cb66d4585bbcef39471193a7396709c6 --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 185d29637c348c3106737da35a88d409e65093ad) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 158b4394cb66d4585bbcef39471193a7396709c6) @@ -20,6 +20,7 @@ #include "ModeTreatmentParams.h" #include "OperationModes.h" #include "PersistentAlarm.h" +#include "SafetyShutdown.h" #include "SyringePump.h" #include "SystemCommMessages.h" #include "TaskPriority.h" @@ -66,7 +67,9 @@ #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/hr). -#define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE ( 1 * MS_PER_SECOND ) ///< Alarm persistence period for syringe pump speed check alarms. +#define SYRINGE_PUMP_RATE_ALARM_PERSISTENCE ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Alarm persistence period for syringe pump speed check alarms. +#define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Alarm persistence period for syringe pump direction check alarms. +#define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE ( 500 / TASK_PRIORITY_INTERVAL ) ///< Alarm persistence period for syringe pump off 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. @@ -82,13 +85,16 @@ #define SYRINGE_PUMP_PRIME_VOLUME_ML 0.353 ///< Target syringe prime volume (in mL). #define SYRINGE_PUMP_MAX_VOL_ERROR_ML 0.1 ///< Maximum Heparin volume error (in mL). #define SYRINGE_PUMP_MAX_RATE_ERROR_ML_HR 0.1 ///< Maximum Heparin delivery rate error (in mL/hr). +#define SYRINGE_PUMP_MAX_RATE_WHILE_OFF_ML_HR 0.001 ///< Maximum Heparin rate measured while in off state (in mL/hr). #define TEN_PCT_OVER_ALLOWANCE 1.1 ///< Allow 10 percent over target before alarming on over travel. #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 * 11.0 ) /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) +/// Minimum retract position. +#define SYRINGE_PUMP_RETRACT_POS_MIN ( SYRINGE_ENCODER_COUNTS_PER_ML * -0.5 ) #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. @@ -152,15 +158,6 @@ NUM_OF_SYRINGE_PUMP_STATES ///< Number of syringe pump control states } SYRINGE_PUMP_STATE_T; -/// Defined states for the syringe pump 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. @@ -204,10 +201,12 @@ static U08 lastSyringePumpADCReadCtr; ///< Remember last ADC read counter to check new reads are fresh. static U32 syringePumpADCReadErrorCtr; ///< Stale ADC read error persistence timer counter. +static U32 syringePumpEncoderDirectionErrorCtr; ///< Encoder direction error persistence timer counter. +static U32 syringePumpControllerDirectionErrorCtr; ///< Controller direction error persistence timer counter. +static U32 syringePumpRunningWhileBPOffErrorCtr; ///< Pump running while BP off error persistence timer counter. +static U32 syringePumpRunningWhileOffErrorCtr; ///< Pump running while in off state error persistence timer counter. +static U32 syringePumpRateErrorCtr; ///< Pump rate error persistence timer counter. -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 ); @@ -248,7 +247,6 @@ { syringePumpState = SYRINGE_PUMP_INIT_STATE; heparinDeliveryState = HEPARIN_STATE_OFF; - syringePumpSelfTestState = SYRINGE_PUMP_SELF_TEST_STATE_START; syringePumpSetRate = 0.0; syringePumpSetToggleTime = 0; @@ -260,7 +258,6 @@ syringePumpEncoderMeasuredDirection = MOTOR_DIR_FORWARD; syringePumpDataPublicationTimerCounter = 0; - syringePumpSelfTestTimerCount = 0; syringePumpSpeedCalcTimerCounter = 0; syringePumpRampTimerCtr = 0; @@ -270,6 +267,11 @@ lastSyringePumpADCReadCtr = 0; syringePumpADCReadErrorCtr = 0; + syringePumpEncoderDirectionErrorCtr = 0; + syringePumpControllerDirectionErrorCtr = 0; + syringePumpRunningWhileBPOffErrorCtr = 0; + syringePumpRunningWhileOffErrorCtr = 0; + syringePumpRateErrorCtr = 0; // Reset request flags resetSyringePumpRequestFlags(); @@ -859,7 +861,7 @@ // Check pump status if ( pmpStatus != 0 ) { - // TODO - pump failure fault + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_FAULT, (U32)pmpStatus ); } } } @@ -956,9 +958,19 @@ { SYRINGE_PUMP_STATE_T result = SYRINGE_PUMP_OFF_STATE; - // TODO - check position is not changing while stopped - // activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR ); - // activateSafetyShutdown(); + // Check position is not changing while stopped + if ( getSyringePumpMeasRate() > SYRINGE_PUMP_MAX_RATE_WHILE_OFF_ML_HR ) // TODO - add persistence + { + if ( ++syringePumpRunningWhileOffErrorCtr > SYRINGE_PUMP_OFF_ALARM_PERSISTENCE ) + { + activateAlarmNoData( ALARM_ID_HD_SYRINGE_PUMP_NOT_STOPPED_ERROR ); + activateSafetyShutdown(); + } + } + else + { + syringePumpRunningWhileOffErrorCtr = 0; + } // Check for request flags if ( TRUE == syringePumpRetractRequested ) @@ -1052,15 +1064,23 @@ else if ( syringePumpControllerMeasuredDirection != MOTOR_DIR_REVERSE ) { // TODO - alarm w/ some persistence + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR, (U32)syringePumpControllerMeasuredDirection, (U32)SYRINGE_PUMP_RETRACT_STATE ); } else if ( syringePumpEncoderMeasuredDirection != MOTOR_DIR_REVERSE ) { // TODO - alarm w/ some persistence + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR, (U32)syringePumpEncoderMeasuredDirection, (U32)SYRINGE_PUMP_RETRACT_STATE ); } + else if ( ( TRUE == syringePumpPositionKnown ) && ( getSyringePumpPosition() < SYRINGE_PUMP_RETRACT_POS_MIN ) ) + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OVER_TRAVEL_ERROR, (U32)getSyringePumpPosition(), (U32)SYRINGE_PUMP_RETRACT_STATE ); + } // TODO - if position known from prior retract, ensure we don't go lower than -TBD position return result; } +ALARM_ID_HD_SYRINGE_PUMP_ENCODER_DIRECTION_ERROR = 187, ///< HD syringe pump direction (from encoder) error +ALARM_ID_HD_SYRINGE_PUMP_CONTROLLER_DIRECTION_ERROR = 188, ///< HD syringe pump direction (from controller) error /*********************************************************************//** * @brief @@ -1094,7 +1114,8 @@ // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); - // TODO - check max position > TBD + // Check max position > empty + 0.5 mL + stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); // TODO - calc estimate syringe volume - if insufficient for treatment needs, alarm @@ -1222,7 +1243,7 @@ // Check for occlusion stopPump = checkOcclusionOrEmpty( stopPump ); - // Check position > max travel + // Check position > empty + 0.5 mL stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); // Check for commanded vs. meas. rate @@ -1346,7 +1367,7 @@ BOOL result = stopPump; S32 pos = getSyringePumpPosition(); - if ( pos > ( SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ) ) + if ( pos > ( SYRINGE_PUMP_EMPTY_POS - SYRINGE_PUMP_EMPTY_POS_MARGIN ) ) { result = TRUE; heparinDeliveryState = HEPARIN_STATE_EMPTY; @@ -1355,6 +1376,10 @@ 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; @@ -1538,24 +1563,7 @@ } } -/*********************************************************************//** - * @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 *************************************************************************/