Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -ra69fcb7945b0300b47ce3287f8cb22c7c26171dc -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision a69fcb7945b0300b47ce3287f8cb22c7c26171dc) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -23,6 +23,7 @@ #include "ModeTreatment.h" #include "ModeTreatmentParams.h" #include "OperationModes.h" +#include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "Timers.h" @@ -33,15 +34,24 @@ // ********** private definitions ********** -#define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. -#define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. +#define START_DG_CMD TRUE ///< Parameter for DG start/stop command function. True = start. +#define STOP_DG_CMD FALSE ///< Parameter for DG start/stop command function. False = stop. -#define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). +#define RESERVOIR_SETTLE_TIME_MS 5000 ///< Time (in ms) allotted for reservoir to settle (after fill, before drain). -#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. +#define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. -#define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. +#define DIALYSATE_TEMP_PERSISTENCE_PERIOD ( 3 * MS_PER_SECOND ) ///< Persistence period for dialysate temperature alarm. +#define DIALYSATE_TEMP_RECOVERY_TOLERANCE_C 2.0 ///< Dialysate temperature recovery tolerance in degree C. +#define DIALYSATE_TEMP_TOLERANCE_C 4.0 ///< Dialysate temperature tolerance in degree C. +#define DIALYSATE_TEMP_HIGH_LIMIT_C 42.0 ///< Dialysate high temperature limit in degree C. +#define DIALYSATE_TEMP_LOW_LIMIT_C 33.0 ///< Dialysate low temperature limit in degree C. + +#define MAX_RESERVOIR_VOLUME_ML 1950.0 ///< Maximum reservoir volume. Switch reservoirs if active reservoir exceeds this volume. + +#define SIZE_OF_LARGE_LOAD_CELL_AVG 32 ///< Large load cell moving average has 32 samples. + /// States of the treatment reservoir management state machine. typedef enum TreatmentReservoirMgmt_States { @@ -161,6 +171,9 @@ lgLoadCellReadingsIdx = 0; lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; + + initPersistentAlarm( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, DIALYSATE_TEMP_PERSISTENCE_PERIOD, DIALYSATE_TEMP_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, DIALYSATE_TEMP_PERSISTENCE_PERIOD, DIALYSATE_TEMP_PERSISTENCE_PERIOD ); } /*********************************************************************//** @@ -1113,6 +1126,47 @@ /*********************************************************************//** * @brief + * The checkDialysateTemperature function checks the dialysate temperature + * reported by DG and alarm if temperature is out of range. + * @details Inputs: dgTrimmerTempSet, dgDialysateTemp, dgRedundantDialysateTemp + * @details Outputs: alarm if dialysate temperature is out of accepted range + * @return none + *************************************************************************/ +void checkDialysateTemperature( void ) +{ + BOOL const dialysateHighTemp = ( ( ( dgDialysateTemp - dgTrimmerTempSet ) > DIALYSATE_TEMP_TOLERANCE_C ) || + ( dgDialysateTemp > DIALYSATE_TEMP_HIGH_LIMIT_C ) ); + + BOOL const dialysateLowTemp = ( ( ( dgTrimmerTempSet - dgDialysateTemp ) > DIALYSATE_TEMP_TOLERANCE_C ) || + ( dgDialysateTemp < DIALYSATE_TEMP_LOW_LIMIT_C ) ); + + BOOL const dialysateTempRecovered = fabs( dgDialysateTemp - dgTrimmerTempSet ) < DIALYSATE_TEMP_RECOVERY_TOLERANCE_C ? TRUE : FALSE; + +#ifndef DISABLE_DIALYSATE_TEMP_CHECK + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dgTrimmerTempSet, dgDialysateTemp ); + } + + if ( TRUE == isPersistentAlarmTriggered( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateLowTemp ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dgTrimmerTempSet, dgDialysateTemp ); + } + + if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH, dialysateHighTemp ) ) + { + clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_HIGH ); + } + + if ( TRUE == isPersistentAlarmConditionCleared( ALARM_ID_DIALYSATE_TEMPERATURE_LOW, dialysateTempRecovered ) ) + { + clearAlarmCondition( ALARM_ID_DIALYSATE_TEMPERATURE_LOW ); + } +#endif +} + +/*********************************************************************//** + * @brief * The checkDGRestart function checks to see if DG has restarted after started * by HD and triggers appropriate alarm. * @details Inputs: dgStarted Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -r3f2b9de757500da37e0ed8881e4e906d94f3076c -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 3f2b9de757500da37e0ed8881e4e906d94f3076c) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -187,6 +187,8 @@ void handleDGCommandResponse( DG_CMD_RESPONSE_T *dgCmdRespPtr ); BOOL getDGCommandResponse( U32 commandID, DG_CMD_RESPONSE_T *cmdRespPtr ); +void checkDialysateTemperature( void ); + BOOL testSetDialOutLoadCellWeightOverride( U32 sensor, F32 value ); BOOL testResetDialOutLoadCellWeightOverride( U32 sensor ); Index: firmware/App/HDCommon.h =================================================================== diff -u -ra64f4bd62ca1b6065cd8946f5130674e578bc2d7 -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/HDCommon.h (.../HDCommon.h) (revision a64f4bd62ca1b6065cd8946f5130674e578bc2d7) +++ firmware/App/HDCommon.h (.../HDCommon.h) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -55,6 +55,7 @@ #define ALWAYS_ALLOW_SYRINGE_PUMP_CMDS 1 // Allow syringe pump commands at any time except when pump is busy #define DISABLE_PRESSURE_CHECKS 1 // Do not error on HD pressure checks // #define DISABLE_UF_ALARMS 1 // Do not error on HD ultrafiltration checks + #define DISABLE_DIALYSATE_TEMP_CHECK 1 // Disable dialysate temperature check // #define DISABLE_VALVE_ALARMS 1 // Do not error on HD valve position #define SKIP_CAL_CHECK 1 // #define RUN_PUMPS_OPEN_LOOP 1 // BP and DPi pumps will be run open loop (no flow sensor feedback) Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r6287441e188e7a245f59d3d0d47cdc77808cdb91 -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 6287441e188e7a245f59d3d0d47cdc77808cdb91) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -198,6 +198,10 @@ postState = handlePOSTStatus( testStatus ); break; + case POST_STATE_ALARM_AUDIO: + postState = POST_STATE_ACCELEROMETER; + break; + case POST_STATE_ACCELEROMETER: #ifndef DISABLE_ACCELS testStatus = execAccelTest(); Index: firmware/App/Modes/ModePreTreat.c =================================================================== diff -u -r8466e63f95f65a3ffb18c3af85ac99328e41167b -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 8466e63f95f65a3ffb18c3af85ac99328e41167b) +++ firmware/App/Modes/ModePreTreat.c (.../ModePreTreat.c) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -376,6 +376,10 @@ case ALARM_ACTION_END_TREATMENT: if ( HD_PRE_TREATMENT_PRIME_STATE > currentPreTreatmentState ) { + if ( HD_PRE_TREATMENT_WATER_SAMPLE_STATE == currentPreTreatmentState ) + { + cmdDGSampleWater( SAMPLE_WATER_CMD_END ); + } requestNewOperationMode( MODE_STAN ); } else Index: firmware/App/Modes/ModeTreatment.c =================================================================== diff -u -r58e7f4184d79fe6dbef4db3d256ad2b56ba7a0aa -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 58e7f4184d79fe6dbef4db3d256ad2b56ba7a0aa) +++ firmware/App/Modes/ModeTreatment.c (.../ModeTreatment.c) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -610,6 +610,8 @@ activateAlarmNoData( ALARM_ID_TREATMENT_STOPPED_BY_USER ); } + checkDialysateTemperature(); + // Treatment mode state machine switch ( currentTreatmentState ) { Index: firmware/App/Modes/Prime.c =================================================================== diff -u -re5d1d67106a93a6cd1b5692b586625d715732e2f -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Modes/Prime.c (.../Prime.c) (revision e5d1d67106a93a6cd1b5692b586625d715732e2f) +++ firmware/App/Modes/Prime.c (.../Prime.c) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -35,20 +35,21 @@ // ********** private definitions ********** -#define MAX_PRIME_TIME ( 10 * SEC_PER_MIN ) ///< Maximum prime time (in seconds). -#define PRIME_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the prime data is published on the CAN bus. +#define MAX_PRIME_TIME ( 10 * SEC_PER_MIN ) ///< Maximum prime time (in seconds). +#define PRIME_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the prime data is published on the CAN bus. -#define BLOOD_PUMP_FLOW_RATE_PURGE_AIR 500 ///< Blood pump flow rate during prime purge air state. -#define BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT 300 ///< Blood pump flow rate during prime recirculate blood circuit state. +#define BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN 400 ///< Blood pump fast flow rate to fill fluid. +#define BLOOD_PUMP_SLOW_FLOW_RATE_PURGE_AIR_ML_MIN 150 ///< Blood pump slow flow rate after fluid reach lower level of air trap sensor. +#define BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN 300 ///< Blood pump flow rate during prime recirculate blood circuit state. -#define DIALYSATE_PUMP_PRIME_FLOW_RATE 300 ///< Dialysate pump flow rate during priming fluid path. -#define LOAD_CELL_VOLUME_NOISE_TOLERANCE 0.05 ///< Allow 5% tolerance on load cell readings. +#define DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN 300 ///< Dialysate pump flow rate during priming fluid path. +#define LOAD_CELL_VOLUME_NOISE_TOLERANCE 0.05 ///< Allow 5% tolerance on load cell readings. -#define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. -#define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. -#define MIN_LOAD_CELL_STEADY_VOLUME_TIME ( 10 * MS_PER_SECOND ) ///< Minimum time load cell reading need to remain steady in ms. -#define PRIME_DIALYSATE_DIALYZER_TIME_LIMIT ( 120 * MS_PER_SECOND ) ///< Time limit for priming dialysate dialyzer circuit. -#define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 120 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. +#define NO_AIR_DETECTED_COUNT ( 20 * MS_PER_SECOND ) ///< No air detected time period count. +#define PURGE_AIR_TIME_OUT_COUNT ( 60 * MS_PER_SECOND ) ///< Time period count for purge air time out. +#define MIN_LOAD_CELL_STEADY_VOLUME_TIME ( 10 * MS_PER_SECOND ) ///< Minimum time load cell reading need to remain steady in ms. +#define PRIME_DIALYSATE_DIALYZER_TIME_LIMIT ( 120 * MS_PER_SECOND ) ///< Time limit for priming dialysate dialyzer circuit. +#define PRIME_DIALYSATE_BYPASS_TIME_LIMIT ( 120 * MS_PER_SECOND ) ///< Time limit for priming dialysate bypass circuit. /// States of the treatment reservoir management state machine. typedef enum PrimeReservoirMgmt_States @@ -341,7 +342,7 @@ signalDialOutPumpHardStop(); signalDialInPumpHardStop(); - setBloodPumpTargetFlowRate( BLOOD_PUMP_FLOW_RATE_PURGE_AIR, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setBloodPumpTargetFlowRate( BLOOD_PUMP_FAST_FLOW_RATE_PURGE_AIR_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); } /*********************************************************************//** @@ -412,6 +413,11 @@ activateAlarmNoData( ALARM_ID_HD_PRIME_PURGE_AIR_TIME_OUT ); } + if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_LOWER ) ) + { + setBloodPumpTargetFlowRate( BLOOD_PUMP_SLOW_FLOW_RATE_PURGE_AIR_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + } + if ( AIR_TRAP_LEVEL_FLUID == getAirTrapLevel( AIR_TRAP_LEVEL_SENSOR_UPPER ) ) { setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); @@ -420,7 +426,7 @@ setValvePosition( VBV, VALVE_POSITION_B_OPEN ); setValveAirTrap( STATE_CLOSED ); - setBloodPumpTargetFlowRate( BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setBloodPumpTargetFlowRate( BLOOD_PUMP_FLOW_RATE_CIRC_BLOOD_CIRCUIT_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); noAirDetectedStartTime = getMSTimerCount(); state = HD_PRIME_SALINE_CIRC_BLOOD_CIRCUIT_STATE; } @@ -493,8 +499,8 @@ setValvePosition( VBV, VALVE_POSITION_C_CLOSE ); setValveAirTrap( STATE_CLOSED ); - setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); - setDialOutPumpTargetRate( DIALYSATE_PUMP_PRIME_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialOutPumpTargetRate( DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); previousLoadCellReading = 0; loadcellSteadyVolumeStartTime = getMSTimerCount(); @@ -586,7 +592,7 @@ if ( TRUE == hasDGCompletedReservoirSwitch() ) { signalDialOutPumpHardStop(); - setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); + setDialInPumpTargetFlowRate( DIALYSATE_PUMP_PRIME_FLOW_RATE_ML_MIN, MOTOR_DIR_FORWARD, PUMP_CONTROL_MODE_OPEN_LOOP ); setValvePosition( VDI, VALVE_POSITION_C_CLOSE ); setValvePosition( VDO, VALVE_POSITION_C_CLOSE ); Index: firmware/App/Modes/SelfTests.c =================================================================== diff -u -r44a100f8e5210a02c23b8fcc4527d8e96d577381 -r88e0f56fa5eb3af397fee7cebb49efdab54f8491 --- firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 44a100f8e5210a02c23b8fcc4527d8e96d577381) +++ firmware/App/Modes/SelfTests.c (.../SelfTests.c) (revision 88e0f56fa5eb3af397fee7cebb49efdab54f8491) @@ -593,6 +593,7 @@ signalBloodPumpHardStop(); signalDialInPumpHardStop(); signalDialOutPumpHardStop(); + selfTestStartTime = getMSTimerCount(); // TODO: Use appropriate sensor driver if ( STATE_CLOSED == getFPGADoorState() ) @@ -750,6 +751,9 @@ { NO_CART_SELF_TESTS_STATE_T state = NO_CART_SELF_TESTS_STOPPED_STATE; + // Restart self-test start time + selfTestStartTime = getMSTimerCount(); + if ( TRUE == selfTestsResumeRequested ) { selfTestsResumeRequested = FALSE; @@ -772,6 +776,9 @@ { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_WAIT_FOR_DOOR_CLOSE_STATE; + // Restart self-test start time + selfTestStartTime = getMSTimerCount(); + // TODO: Use appropriate sensor driver if ( STATE_CLOSED == getFPGADoorState() ) { @@ -992,6 +999,9 @@ { DRY_SELF_TESTS_STATE_T state = DRY_SELF_TESTS_STOPPED_STATE; + // Restart self-test start time + selfTestStartTime = getMSTimerCount(); + if ( TRUE == selfTestsResumeRequested ) { selfTestsResumeRequested = FALSE;