Index: firmware/App/Controllers/BloodFlow.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/BloodFlow.c (.../BloodFlow.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -240,7 +240,7 @@ bpMotorSpeedCalcIdx = 0; for ( i = 0; i < BP_SPEED_CALC_BUFFER_LEN; i++ ) { - bpLastMotorHallSensorCounts[ i ] = 0; + bpLastMotorHallSensorCounts[ i ] = getFPGABloodPumpHallSensorCount(); } resetBloodPumpRotorCount(); @@ -1080,7 +1080,9 @@ ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_DIRECTION_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) ) { lastBloodPumpDirectionCount = dirErrorCnt; +#ifndef DISABLE_PUMP_DIRECTION_CHECKS SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_PUMP_DIRECTION_STATUS_ERROR, (U32)HD_PUMP_BLOOD_PUMP ) +#endif } bpMCDir = ( getMeasuredBloodPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); bpDir = ( getMeasuredBloodPumpSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); Index: firmware/App/Controllers/BloodLeak.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/BloodLeak.c (.../BloodLeak.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -546,18 +546,21 @@ { BLOOD_LEAK_STATES_T state = BLOOD_LEAK_SELF_TEST_STATE; +#ifndef IGNORE_BLOOD_LEAK_SELF_TEST if ( SELF_TEST_STATUS_IN_PROGRESS == bloodLeakSelfTestStatus ) { if ( FALSE == noFPGABloodLeakDetected() ) // Faked blood leak caused by independent MCU board { bloodLeakSelfTestStatus = SELF_TEST_STATUS_PASSED; clearFPGABloodLeakSelfTest(); } + else if ( TRUE == didTimeout( bloodLeakSelfTestStartTime, BLOOD_LEAK_TIMEOUT_MS ) ) { bloodLeakSelfTestStatus = SELF_TEST_STATUS_FAILED; - +#ifndef IGNORE_BLOOD_LEAK_ALARM activateAlarmNoData( ALARM_ID_HD_BLOOD_LEAK_SELF_TEST_FAILURE ); +#endif } } else @@ -568,6 +571,7 @@ state = BLOOD_LEAK_NORMAL_STATE; } } +#endif return state; } Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -329,26 +329,26 @@ /*********************************************************************//** * @brief - * The getDialysateTemperature function gets the latest dialysate temperature. - * @details Inputs: dgDialysateTemp + * The getDGDisinfectsStates function returns the DG disinfects readings. + * @details Inputs: none * @details Outputs: none - * @return the current dialysate temperature + * @return the current DG disinfects readings *************************************************************************/ -F32 getDialysateTemperature( void ) +DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) { - return dgDialysateTemp; + return disinfectsStatus; } /*********************************************************************//** * @brief - * The getDGDisinfectsStates function returns the DG disinfects readings. - * @details Inputs: none + * The getDialysateTemperature function gets the latest dialysate temperature. + * @details Inputs: dgDialysateTemp * @details Outputs: none - * @return the current DG disinfects readings + * @return the current dialysate temperature *************************************************************************/ -DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ) +F32 getDialysateTemperature( void ) { - return disinfectsStatus; + return dgDialysateTemp; } /*********************************************************************//** Index: firmware/App/Controllers/DialInFlow.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/DialInFlow.c (.../DialInFlow.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -237,7 +237,7 @@ dipMotorSpeedCalcIdx = 0; for ( i = 0; i < DIP_SPEED_CALC_BUFFER_LEN; i++ ) { - dipLastMotorHallSensorCounts[ i ] = 0; + dipLastMotorHallSensorCounts[ i ] = getFPGADialInPumpHallSensorCount(); } // Initialize dialysate inlet flow PI controller @@ -1008,7 +1008,9 @@ ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_PUMP_DIRECTION_CHECKS ) != SW_CONFIG_ENABLE_VALUE ) ) { lastDialInPumpDirectionCount = dirErrorCnt; +#ifndef DISABLE_PUMP_DIRECTION_CHECKS SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_PUMP_DIRECTION_STATUS_ERROR, (U32)HD_PUMP_DIALYSATE_INLET_PUMP ) +#endif } dipMCDir = ( getMeasuredDialInPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); Index: firmware/App/Controllers/DialOutFlow.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/DialOutFlow.c (.../DialOutFlow.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -233,7 +233,7 @@ dopMotorSpeedCalcIdx = 0; for ( i = 0; i < DOP_SPEED_CALC_BUFFER__LEN; i++ ) { - dopLastMotorHallSensorCounts[ i ] = 0; + dopLastMotorHallSensorCounts[ i ] = getFPGADialOutPumpHallSensorCount(); } dopMeasuredRate = 0.0; @@ -923,7 +923,9 @@ if ( lastDialOutPumpDirectionCount != dirErrorCnt ) { lastDialOutPumpDirectionCount = dirErrorCnt; +#ifndef DISABLE_PUMP_DIRECTION_CHECKS SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_PUMP_DIRECTION_STATUS_ERROR, (U32)HD_PUMP_DIALYSATE_OUTLET_PUMP ) +#endif } dopMCDir = ( getMeasuredDialOutPumpMCSpeed() >= 0.0 ? MOTOR_DIR_FORWARD : MOTOR_DIR_REVERSE ); Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -648,11 +648,21 @@ if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) { signalBloodPumpHardStop(); // Stop pump immediately - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + //SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) } else if ( bpOccl < ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) { - clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); + //clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); + // Check for occlusion + if ( bpOccl > ( OCCLUSION_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { + signalBloodPumpHardStop(); // Stop pump immediately + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) + } + else if ( bpOccl < ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + { + clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); + } } } } Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -15,27 +15,27 @@ * ***************************************************************************/ #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 BD_SYRINGE_ID_RADIUS_CM ( 1.4427 / 2.0 ) ///< Radius from inner diameter (in cm) of supported BD syringe. @@ -55,20 +55,18 @@ /// 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.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). -#define HEPARIN_BOLUS_TIME_HR ( 5.0 / MIN_PER_HOUR ) ///< Duration (in hours) of Heparin bolus. +#define HEPARIN_BOLUS_TARGET_RATE 40.0 ///< Heparin bolus target rate (in ml/hr); #define SYRINGE_PUMP_RETRACT_RATE 3600.0 ///< Retract rate is 5 mL/ 5 s = 1 mL/s = 3,600 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/hr). -#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_RATE_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump speed check alarms. +#define SYRINGE_PUMP_DIR_ALARM_PERSISTENCE 3000 ///< Alarm persistence period (in ms) for syringe pump direction check alarms. #define SYRINGE_PUMP_OFF_ALARM_PERSISTENCE 1000 ///< Alarm persistence period (in ms) for syringe pump off check alarms. #define SYRINGE_PUMP_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). @@ -81,6 +79,7 @@ #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_OCCLUSION_DIFF_V 0.5 ///< Force sensor difference (in V) which an occlusion alarm is triggered. #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). @@ -90,8 +89,9 @@ #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 * 10.84 ) +/// Expected position of empty in relation to home position. +#define SYRINGE_PUMP_EMPTY_POS ( SYRINGE_ENCODER_COUNTS_PER_ML * 10.84 ) ///< get syringe volume from home to empty (11 mL is placeholder) + /// Margin of error for empty position determination. #define SYRINGE_PUMP_EMPTY_POS_MARGIN ( SYRINGE_ENCODER_COUNTS_PER_ML * 0.5 ) /// Minimum retract position. @@ -154,32 +154,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). @@ -189,6 +189,7 @@ static OVERRIDE_U32_T syringePumpADCReadCtr = {0, 0, 0, 0}; ///< Syringe pump ADC read counter reported by FPGA. static F32 syringePumpSetRate; ///< Set rate for syringe pump (in mL/hr). +static F32 forceAtEndOfSeek; ///< Force sensor reading in Volts at the end of seek. 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). @@ -222,10 +223,10 @@ static U32 syringePumpStallRetryCount; ///< Counts pump ramp up stall retries. 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 ); @@ -235,7 +236,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 ); @@ -248,22 +249,22 @@ static void calcMeasRate( void ); static void calcSafetyVolumeDelivered( void ); static BOOL checkDirection( BOOL stopPump, MOTOR_DIR_T expDir ); -static BOOL checkOcclusionOrEmpty( BOOL stopPump ); +static BOOL checkSyringeEmpty( BOOL stopPump ); static BOOL checkSyringeRemoved( BOOL stopPump ); static BOOL checkMaxTravel( BOOL stopPump, S32 maxPos ); static BOOL checkMeasRate( BOOL stopPump, F32 pctMargin ); static BOOL checkVolumeVsSafetyVolume( BOOL stopPump, F32 pctMargin ); static BOOL checkForStall( BOOL stopPump ); 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 ) + +/*********************************************************************//** + * @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; @@ -312,7 +313,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(); } @@ -522,6 +523,7 @@ if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( TRUE == isSyringeDetected() ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) && ( TRUE == syringePumpPlungerFound ) ) { + forceAtEndOfSeek = getSyringePumpForceV(); // Get the force sensor reading when syringe pump prime has been requested (after seek) syringePumpSetRate = SYRINGE_PUMP_PRIME_RATE; syringePumpPrimeRequested = TRUE; resetHeparinVolumeDelivered(); @@ -554,13 +556,10 @@ *************************************************************************/ BOOL startHeparinBolus( void ) { - F32 tgtRate = 0.0; + F32 tgtRate = HEPARIN_BOLUS_TARGET_RATE; // fixed rate - // Get set Heparin bolus volume (mL) and convert to target rate (mL/hr) - tgtRate = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ) / HEPARIN_BOLUS_TIME_HR; - // If valid to start a bolus, kick it off - if ( ( tgtRate >= MIN_HEPARIN_BOLUS_RATE ) && ( tgtRate <= MAX_HEPARIN_BOLUS_RATE ) && ( FALSE == isSyringePumpHome() ) ) + if ( FALSE == isSyringePumpHome() ) { if ( ( TRUE == isSyringeDetected() ) && ( TRUE == syringePumpPrimeCompleted ) && ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( HEPARIN_STATE_STOPPED == heparinDeliveryState ) ) @@ -1043,14 +1042,14 @@ } } -/*********************************************************************//** - * @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(); @@ -1071,7 +1070,7 @@ case SYRINGE_PUMP_OFF_STATE: syringePumpState = handleSyringePumpOffState(); break; - + case SYRINGE_PUMP_RETRACT_STATE: syringePumpState = handleSyringePumpRetractState(); break; @@ -1096,15 +1095,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(); } /*********************************************************************//** @@ -1133,7 +1132,7 @@ } return result; -} +} /*********************************************************************//** * @brief @@ -1312,7 +1311,7 @@ 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 hepDurHr = ( (F32)( setTxDur - preStop ) / (F32)MIN_PER_HOUR ); F32 txVolume = SYRINGE_PUMP_PRIME_VOLUME_ML + bolusVol + ( hepDurHr * contRate ); F32 syringeVol = ( SYRINGE_PUMP_EMPTY_POS - (F32)pos ) / SYRINGE_ENCODER_COUNTS_PER_ML; @@ -1323,14 +1322,14 @@ if ( ( getSyringePumpForceV() >= SYRINGE_FORCE_PLUNGER_THRESHOLD_V ) || ( syringeVol < txVolume ) ) { stopPump = TRUE; - syringePumpPlungerFound = TRUE; syringePumpVolumeDelivered.data = 0.0; syringePumpSafetyVolumeDelivered = 0.0; syringePumpVolumeStartPosition = pos; // Check estimated syringe volume needed for treatment vs. volume detected - if insufficient for treatment needs, alarm if ( syringeVol >= txVolume ) { + syringePumpPlungerFound = TRUE; syringeVolumeAdequate = TRUE; } else @@ -1390,16 +1389,13 @@ // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); - // Check for occlusion - stopPump = checkOcclusionOrEmpty( stopPump ); - // Check position > max travel stopPump = checkMaxTravel( stopPump, syringePumpVolumeStartPosition + ( SYRINGE_PUMP_PRIME_VOLUME_ML * TEN_PCT_OVER_ALLOWANCE * SYRINGE_ENCODER_COUNTS_PER_ML ) ); // Check pump direction stopPump = checkDirection( stopPump, MOTOR_DIR_FORWARD ); - // If anything found that would require stopping the pump, stop pump and go to off state + // If anything found that would require stopping the pump, stop pump if ( TRUE == stopPump ) { stopSyringePump(); @@ -1437,8 +1433,8 @@ // Check volume vs. safety volume stopPump = checkVolumeVsSafetyVolume( stopPump, SYRINGE_PUMP_VOLUME_CHECK_MARGIN ); - // Check for occlusion - stopPump = checkOcclusionOrEmpty( stopPump ); + // Check for syringe pump empty + stopPump = checkSyringeEmpty( stopPump ); // Check for commanded vs. meas. rate stopPump = checkMeasRate( stopPump, SYRINGE_PUMP_RATE_CHECK_MARGIN ); @@ -1478,8 +1474,8 @@ // Has syringe been removed? stopPump = checkSyringeRemoved( stopPump ); - // Check for occlusion - stopPump = checkOcclusionOrEmpty( stopPump ); + // Check for syringe pump empty + stopPump = checkSyringeEmpty( stopPump ); // Check position > empty + 0.5 mL stopPump = checkMaxTravel( stopPump, SYRINGE_PUMP_EMPTY_POS + SYRINGE_PUMP_EMPTY_POS_MARGIN ); @@ -1568,32 +1564,50 @@ /*********************************************************************//** * @brief - * The checkOcclusionOrEmpty function checks the force sensor for excessive - * pressure. Would indicate occlusion or jam or empty syringe. + * The checkSyringeEmpty function checks the force sensor position + * to determine if the syringe pump is empty. * @details Inputs: syringePumpMeasForce.data, syringePumpPosition.data - * @details Outputs: alarm triggered if max force detected + * @details Outputs: alarm triggered if position is empty. * @param stopPump flag passed in by caller indicating whether pump should be stopped * @return TRUE if pump should be stopped, FALSE if not *************************************************************************/ -static BOOL checkOcclusionOrEmpty( BOOL stopPump ) +static BOOL checkSyringeEmpty( BOOL stopPump ) { BOOL result = stopPump; F32 force = getSyringePumpForceV(); + S32 pos = getSyringePumpPosition(); - if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, ( force >= SYRINGE_FORCE_OCCLUSION_THRESHOLD_V ) ) ) + // If near empty position, assume syringe is empty + if ( fabs( pos - SYRINGE_PUMP_EMPTY_POS ) < SYRINGE_PUMP_EMPTY_POS_MARGIN ) { - S32 pos = getSyringePumpPosition(); + heparinDeliveryState = HEPARIN_STATE_EMPTY; + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_SYRINGE_EMPTY, (F32)pos, force ) + result = TRUE; + } - // 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 ) - } + return result; +} + +/*********************************************************************//** + * @brief + * The checkForPrimeOcclusion function checks the force sensor for excessive + * pressure. Would indicate occlusion or jam or empty syringe. + * @details Inputs: syringePumpMeasForce.data, syringePumpPosition.data + * @details Outputs: alarm triggered if max force detected + * @param stopPump flag passed in by caller indicating whether pump should be stopped + * @return TRUE if pump should be stopped, FALSE if not + *************************************************************************/ +BOOL checkForPrimeOcclusion( void ) +{ + BOOL result = FALSE; // Return FALSE if no occlusion is detected + F32 forceAtEndOfPriming = getSyringePumpForceV(); // Read the force sensor at the end of the priming + F32 forceDelta = forceAtEndOfPriming - forceAtEndOfSeek; // Occlusion is detected if force at end of prime is > than force at end of seek by 0.5 volts or more + BOOL occlusionDetected = ( forceDelta >= SYRINGE_FORCE_OCCLUSION_DIFF_V ? TRUE : FALSE ); + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, occlusionDetected ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_SYRINGE_PUMP_OCCLUSION, forceAtEndOfSeek, forceAtEndOfPriming ) // reuse this alarm after prime + forceAtEndOfSeek = 0.0; // reset this value in case we want to prime again result = TRUE; } @@ -1787,7 +1801,7 @@ } } } - + /*********************************************************************//** * @brief * The calcStepperToggleTimeForTargetRate function calculates the stepper @@ -1858,18 +1872,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; @@ -1887,68 +1901,68 @@ ( (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; + } } - -/************************************************************************* - * 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 @@ -2271,7 +2285,7 @@ return result; } - + /*********************************************************************//** * @brief * The testSetSyringePumpStatus function overrides the syringe pump @@ -2452,4 +2466,4 @@ return result; } -/**@}*/ +/**@}*/ Index: firmware/App/HDCommon.h =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/HDCommon.h (.../HDCommon.h) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -10,8 +10,8 @@ * @author (last) Dara Navaei * @date (last) 04-Jan-2022 * -* @author (original) Sean -* @date (original) 27-Feb-2020 +* @author (original) Sean +* @date (original) 27-Feb-2020 * ***************************************************************************/ @@ -25,7 +25,7 @@ #define HD_VERSION_MAJOR 0 #define HD_VERSION_MINOR 6 #define HD_VERSION_MICRO 0 -#define HD_VERSION_BUILD 31 +#define HD_VERSION_BUILD 220 // ********** development build switches ********** @@ -38,6 +38,7 @@ // #define RUN_WITHOUT_DG 1 // Run HD w/o DG // #define SIMULATE_UI 1 // Build w/o requirement that UI be there // #define TASK_TIMING_OUTPUT_ENABLED 1 // Re-purposes alarm lamp pins for task timing + #define DISABLE_BATT_COMM 1 // Disable battery communication // #define READ_FPGA_ASYNC_DATA 1 // Test build reads non-priority register page every other time // #define DISABLE_FPGA_COUNTER_CHECKS 1 // Disable alarms associated with FPGA read/error counters Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -248,22 +248,13 @@ // Do not run syringe pump if no Heparin included in prescription or it was paused or if Heparin should be stopped at this stage of treatment if ( ( minRem > (F32)preStop ) && ( HEPARIN_STATE_STOPPED == currentHeparinState ) ) { - // If not done with bolus, start/resume bolus - if ( ( bolusVol > 0.0 ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) + if ( hepRate > 0.0 ) { - startHeparinBolus(); // TODO - check return status or have function trigger alarm if not successful + startHeparinContinuous(); // TODO - check return status } - // Otherwise, start/resume continuous delivery else { - if ( hepRate > 0.0 ) - { - startHeparinContinuous(); // TODO - check return status - } - else - { - setHeparinCompleted(); - } + setHeparinCompleted(); } } else Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -37,6 +37,7 @@ #include "RTC.h" #include "SafetyShutdown.h" #include "SyringePump.h" +#include "system.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Temperatures.h" Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -41,6 +41,7 @@ #define PUMP_RUN_SELF_TEST_TIME_MS ( 15 * MS_PER_SECOND ) ///< Self-test time to run pumps in ms. #define PUMP_SELF_TEST_FLOW_RATE_ML_MIN 100 ///< Self-test pump flow rate in mL/min. +#define SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ( 1 * MS_PER_SECOND ) ///< Delay 1 second then check for syringe pump prime occlusion. #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 ( 4 * MS_PER_SECOND ) ///< Time to wait for pressure to normalize in ms. @@ -58,7 +59,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 12.0 ///< Tolerance in the load cell readings of the displacement in grams (2%). +#define WET_SELF_TEST_DISPLACEMENT_TOLERANCE_G 25.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. @@ -112,6 +113,7 @@ static U32 selfTestStartTime; ///< Starting time of self-test (in ms). static U32 selfTestPreviousPublishDataTime; ///< Last time self-test time data is being published (in ms). +static U32 syringeOcclusionDelayStartTime; ///< Used to calculate the 1 second delay time before check for prime occlusion. static BOOL useHeparin; ///< Flag indicates the user of heparin. @@ -135,6 +137,7 @@ static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsState( SELF_TEST_STATUS_T *result ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestPressureSensorsNormalState( SELF_TEST_STATUS_T *result ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpPrimeState( void ); +static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ); static DRY_SELF_TESTS_STATE_T handleDrySelfTestStoppedState( void ); static WET_SELF_TESTS_STATE_T handleWetSelfTestStartState( void ); @@ -161,6 +164,7 @@ { selfTestStartTime = 0; selfTestPreviousPublishDataTime = 0; + syringeOcclusionDelayStartTime = 0; } /*********************************************************************//** @@ -328,7 +332,7 @@ } else { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT, currentNoCartSelfTestsState ); +// SET_ALARM_WITH_1_U32_DATA( ALARM_ID_HD_NO_CART_SELF_TEST_TIMEOUT, currentNoCartSelfTestsState ); } } } @@ -429,6 +433,10 @@ currentDrySelfTestsState = handleDrySelfTestSyringePumpPrimeState(); break; + case DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE: + currentDrySelfTestsState = handleDrySelfTestSyringePumpOcclusionDetectionState(); + break; + case DRY_SELF_TESTS_STOPPED_STATE: currentDrySelfTestsState = handleDrySelfTestStoppedState(); break; @@ -838,10 +846,10 @@ { state = DRY_SELF_TESTS_OCCLUSION_SENSORS_STATE; } - else - { - activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); - } +// else +// { +// activateAlarmNoData( ALARM_ID_INSTALL_NEW_CARTRIDGE ); +// } if ( TRUE == doesAlarmStatusIndicateStop() ) { @@ -986,7 +994,8 @@ { if ( TRUE == isSyringePumpPrimed() ) { - state = DRY_SELF_TESTS_COMPLETE_STATE; + state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; + syringeOcclusionDelayStartTime = getMSTimerCount(); // Get the current time to check for occlusion after 1 second has elapsed } else { @@ -1022,6 +1031,33 @@ /*********************************************************************//** * @brief + * The handleDrySelfTestSyringePumpOcclusionDetectionState function handles + * occlusion detection after prime has completed. + * @details Inputs: none + * @details Outputs: none + * @return the next state of dry self-tests state machine + *************************************************************************/ +static DRY_SELF_TESTS_STATE_T handleDrySelfTestSyringePumpOcclusionDetectionState( void ) +{ + DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_SYRINGE_PUMP_OCCLUSION_DETECTION_STATE; + + if ( TRUE == didTimeout( syringeOcclusionDelayStartTime, SYRINGE_PUMP_OCCLUSION_CHECK_DELAY ) ) + { + checkForPrimeOcclusion(); + state = DRY_SELF_TESTS_COMPLETE_STATE; + } + + if ( TRUE == doesAlarmStatusIndicateStop() ) + { + state = DRY_SELF_TESTS_STOPPED_STATE; + setupForSelfTestsStop(); + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleDrySelfTestStoppedState function handles the stopped dry self-tests * operation. * @details Inputs: none @@ -1038,6 +1074,7 @@ if ( TRUE == selfTestsResumeRequested ) { selfTestsResumeRequested = FALSE; + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRY_SELF_TESTS ) != SW_CONFIG_ENABLE_VALUE ) { state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; @@ -1090,8 +1127,27 @@ if ( FALSE == cmdResp.rejected ) { - setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SETUP_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - fmdIntegratedVolume = 0.0; + if ( ( TRUE == isValvesSettingSent ) && ( TRUE == getDGCommandResponse( DG_CMD_VALVE_SETTING, &cmdResp ) ) ) + { + // Re-send command if DG rejects + isValvesSettingSent = FALSE; + + if ( FALSE == cmdResp.rejected ) + { + F32 bolusVol = getTreatmentParameterF32( TREATMENT_PARAM_HEPARIN_BOLUS_VOLUME ); + + setDialInPumpTargetFlowRate( DIP_FLOW_RATE_SETUP_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + fmdIntegratedVolume = 0.0; + + if ( ( bolusVol > 0.0 ) && ( getSyringePumpVolumeDelivered() < bolusVol ) ) + { + startHeparinBolus(); // moved here from startHeparinPump() in Dialysis.c + } + + state = WET_SELF_TESTS_SETUP_STATE; + } + } + state = WET_SELF_TESTS_SETUP_STATE; } } @@ -1214,8 +1270,10 @@ { WET_SELF_TESTS_STATE_T state = WET_SELF_TESTS_BLOOD_LEAK_DETECTOR_STATE; - if ( ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_SELF_TEST ) != SW_CONFIG_ENABLE_VALUE ) || +#ifndef IGNORE_BLOOD_LEAK_SELF_TEST + if ( /*( getSoftwareConfigStatus( SW_CONFIG_DISABLE_BLOOD_LEAK_SELF_TEST ) != SW_CONFIG_ENABLE_VALUE ) || */ ( SELF_TEST_STATUS_PASSED == getBloodLeakSelfTestStatus() ) ) +#endif { settleStartTime = getMSTimerCount(); state = WET_SELF_TESTS_FIRST_DISPLACEMENT_SETUP_STATE; Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -515,7 +515,7 @@ // If the wait time has elapsed, trigger a fill command // TODO uncomment - //if ( timeWaitToFillMS <= 0 ) + if ( timeWaitToFillMS <= 0 ) // TODO uncomment { cmdStartDGFill( FILL_RESERVOIR_TO_VOLUME_ML, targetFillFlowRateLPM ); Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r2a3a47ca90ad19851a30c52f6999a56d5f578783 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 2a3a47ca90ad19851a30c52f6999a56d5f578783) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -52,8 +52,7 @@ #define MAX_COMM_CRC_FAILURE_WINDOW_MS (10 * SEC_PER_MIN * MS_PER_SECOND) ///< CRC error window #define MSG_NOT_ACKED_TIMEOUT_MS 150 ///< Maximum time for a Denali message that requires ACK to be ACK'd - -#define MSG_NOT_ACKED_TIMEOUT_MS_INIT 5000 ///< Maximum time for a Denali message that requires ACK to be ACK'd on the INIT state for the first (UI version request) message of the POST +#define MSG_NOT_ACKED_TIMEOUT_MS_INIT 5000 ///< Maximum time for a Denali message that requires ACK to be ACK'd on the INIT state for the first (UI version request) message of the POST #define MSG_NOT_ACKED_MAX_RETRIES 3 ///< Maximum number of times a message that requires ACK that was not ACK'd can be re-sent before alarm #define PENDING_ACK_LIST_SIZE 25 ///< Maximum number of Denali messages that can be pending ACK at any given time @@ -1626,6 +1625,10 @@ handleSetHDSoftwareConfigRecord( message ); break; + case MSG_ID_HD_REQ_CURRENT_TREATMENT_PARAMETERS: + handleTestCurrentTreamtmentParametersRequest( message ); + break; + default: // Unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r29a2c3c7d7618489c0ada9f98e1d30226b455392 -re5006f5263e8540e730dd802016fef5973ecea4c --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 29a2c3c7d7618489c0ada9f98e1d30226b455392) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision e5006f5263e8540e730dd802016fef5973ecea4c) @@ -2407,7 +2407,7 @@ TEMPERATURE_SENSORS_DATA_T payload; memcpy( &payload, message->payload, sizeof( TEMPERATURE_SENSORS_DATA_T ) ); - setDialysateTemperatureReadings( payload.inletDialysate, payload.outletRedundant ); + setDialysateTemperatureReadings( payload.TDi, payload.TRo ); } // TODO - what to do if invalid payload length? // TODO - how to know if DG stops sending these? @@ -2715,6 +2715,8 @@ return result; } + + /*********************************************************************//** * @brief * The handleChangeUFSettingsRequest function handles a ultrafiltration @@ -5231,6 +5233,7 @@ if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen ) { memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) ); + if ( FALSE == payload.reset ) { result = testSetBatteryRemainingPercentOverride( payload.state.u32 ); @@ -6921,4 +6924,50 @@ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } +/*********************************************************************//** + * @brief + * The handleTestCurrentTreamtmentParametersRequest function handles a + * request to retrieve the current treatment parameters. + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ + +void handleTestCurrentTreamtmentParametersRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + // verify payload length + if ( 0 == message->hdr.payloadLen ) + { + result = TRUE; + // ACK request + result = testUpdateCurrentTreatmentParameters(); + } + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The sendTestCurrentTreatmentParametersResponse function constructs a current + * treatment parameter response message to the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: current treatment prameters response msg constructed and queued. + * @param data response data record + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ + +BOOL sendTestCurrentTreatmentParametersResponse(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T current_params) +{ + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_HD_RES_CURRENT_TREATMENT_PARAMETERS; + msg.hdr.payloadLen = sizeof(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T); + memcpy(payloadPtr, ¤t_params, sizeof(CURRENT_TREATMENT_PARAMS_DATA_PAYLOAD_T)); + + return serializeMessage(msg, COMM_BUFFER_OUT_CAN_PC, ACK_REQUIRED ); +} + /**@}*/