Index: firmware/App/Controllers/DGInterface.c =================================================================== diff -u -r19a8bf98a7154e24c35da25225d4b55bf70ddd09 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 19a8bf98a7154e24c35da25225d4b55bf70ddd09) +++ firmware/App/Controllers/DGInterface.c (.../DGInterface.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -69,11 +69,14 @@ static OVERRIDE_F32_T loadCellWeightInGrams[ NUM_OF_LOAD_CELLS ]; /// Filtered (32 sample) weight of reservoirs. static F32 lgFilteredReservoirWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; +static F32 lgFilteredReservoirBackupWeightInGrams[ NUM_OF_DG_RESERVOIRS ]; // Load cell filtering data static F32 lgLoadCellReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; ///< Holds load cell samples for large load cell moving average. static U32 lgLoadCellReadingsIdx = 0; ///< Index for next sample in large load cell rolling average sample array. static F32 lgLoadCellReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc large load cell moving average. +static F32 lgLoadCellBackupReadings[ NUM_OF_DG_RESERVOIRS ][ SIZE_OF_LARGE_LOAD_CELL_AVG ]; ///< Holds load cell samples for large load cell moving average. +static F32 lgLoadCellBackupReadingsTotal[ NUM_OF_DG_RESERVOIRS ]; ///< Rolling total - used to calc large load cell moving average. // DG Dialysate flow rate static F32 dgDialysateFlowRateMlMin = 0.0; ///< Latest dialysate flow rate reported by the DG. @@ -132,6 +135,7 @@ for ( j = 0; j < SIZE_OF_LARGE_LOAD_CELL_AVG; j++ ) { lgLoadCellReadings[ i ][ j ] = 0.0; + lgLoadCellBackupReadings[ i ][ j ] = 0.0; } } @@ -146,6 +150,8 @@ lgLoadCellReadingsIdx = 0; lgLoadCellReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; lgLoadCellReadingsTotal[ DG_RESERVOIR_2 ] = 0.0; + lgLoadCellBackupReadingsTotal[ DG_RESERVOIR_1 ] = 0.0; + lgLoadCellBackupReadingsTotal[ 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 ); @@ -329,6 +335,27 @@ /*********************************************************************//** * @brief + * The getReservoirBackupWeightLargeFilter function gets the backup load cell weight + * of the given reservoir after large (32 sample) filter applied. + * @details Inputs: lgFilteredReservoirWeightInGrams[] + * @details Outputs: none + * @param resID ID of reservoir to get filtered weight for + * @return the current filtered weight of the given reservoir in grams + *************************************************************************/ +F32 getReservoirBackupWeightLargeFilter( DG_RESERVOIR_ID_T resID ) +{ + F32 result = 0.0; + + if ( resID < NUM_OF_DG_RESERVOIRS ) + { + result = lgFilteredReservoirBackupWeightInGrams[ resID ]; + } + + return result; +} + +/*********************************************************************//** + * @brief * The getDialysateTemperature function gets the latest dialysate temperature. * @details Inputs: dgDialysateTemp * @details Outputs: none @@ -492,6 +519,12 @@ lgLoadCellReadings[ res ][ lgLoadCellReadingsIdx ] = wt; lgLoadCellReadingsTotal[ res ] += wt; lgFilteredReservoirWeightInGrams[ res ] = lgLoadCellReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; + + wt = ( res == DG_RESERVOIR_1 ? res1Backup : res2Backup ); + lgLoadCellBackupReadingsTotal[ res ] -= lgLoadCellBackupReadings[ res ][ lgLoadCellReadingsIdx ]; + lgLoadCellBackupReadings[ res ][ lgLoadCellReadingsIdx ] = wt; + lgLoadCellBackupReadingsTotal[ res ] += wt; + lgFilteredReservoirBackupWeightInGrams[ res ] = lgLoadCellBackupReadingsTotal[ res ] / (F32)SIZE_OF_LARGE_LOAD_CELL_AVG; } lgLoadCellReadingsIdx = INC_WRAP( lgLoadCellReadingsIdx, 0, SIZE_OF_LARGE_LOAD_CELL_AVG - 1 ); Index: firmware/App/Controllers/DGInterface.h =================================================================== diff -u -r19a8bf98a7154e24c35da25225d4b55bf70ddd09 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 19a8bf98a7154e24c35da25225d4b55bf70ddd09) +++ firmware/App/Controllers/DGInterface.h (.../DGInterface.h) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -34,6 +34,8 @@ #define DEFAULT_TARGET_FILL_FLOW_RATE_LPM 0.8F ///< Default target fill flow rate in L/min. #define DRAIN_RESERVOIR_TO_VOLUME_ML 0 ///< Drain reservoir to this volume (in mL) during treatment. +#define LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS 10.0F ///< Reservoir load cell drift difference allowed +#define LOAD_CELL_ILLEGAL_WEIGHT_VALUE -10000.0F ///< Initial value for Load Cells, known bad value /// DG Concentrate ratios data structure. typedef struct @@ -148,6 +150,7 @@ F32 getLoadCellWeight( LOAD_CELL_ID_T loadCellID ); F32 getReservoirWeight( DG_RESERVOIR_ID_T resID ); F32 getReservoirWeightLargeFilter( DG_RESERVOIR_ID_T resID ); +F32 getReservoirBackupWeightLargeFilter( DG_RESERVOIR_ID_T resID ); F32 getDialysateTemperature( void ); DG_DISINFECT_UI_STATES_T getDGDisinfectsStates( void ); DG_MIXING_RATIOS_T getDGMixingRatios( void ); Index: firmware/App/Controllers/PresOccl.c =================================================================== diff -u -rbb5280946ac08388b456c7c1848d7797c4a28038 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision bb5280946ac08388b456c7c1848d7797c4a28038) +++ firmware/App/Controllers/PresOccl.c (.../PresOccl.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -587,8 +587,8 @@ } // Check arterial pressure during treatment mode - if ( MODE_TREA == getCurrentOperationMode() && - TREATMENT_DIALYSIS_STATE == getTreatmentState() && getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) + if ( ( MODE_TREA == getCurrentOperationMode() ) && + ( TREATMENT_DIALYSIS_STATE == getTreatmentState() ) && ( getDialysisState() != DIALYSIS_SALINE_BOLUS_STATE ) ) { F32 artLowLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_LOW_LIMIT ); F32 artHighLimit = (F32)getTreatmentParameterS32( TREATMENT_PARAM_ART_PRESSURE_HIGH_LIMIT ); @@ -727,7 +727,7 @@ signalBloodPumpHardStop(); // Stop pump immediately SET_ALARM_WITH_1_U32_DATA( ALARM_ID_OCCLUSION_BLOOD_PUMP, bpOccl ) } - else if ( bpOccl <= ( OCCLUSION_CLEAR_THRESHOLD_OFFSET + bloodPumpOcclusionAfterCartridgeInstall ) ) + else { clearAlarmCondition( ALARM_ID_OCCLUSION_BLOOD_PUMP ); } Index: firmware/App/Controllers/Switches.c =================================================================== diff -u -rbb5280946ac08388b456c7c1848d7797c4a28038 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Controllers/Switches.c (.../Switches.c) (revision bb5280946ac08388b456c7c1848d7797c4a28038) +++ firmware/App/Controllers/Switches.c (.../Switches.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -105,7 +105,8 @@ break; #ifndef _VECTORCAST_ - // The default cannot be reached in VectorCAST since the cases are run in a for loop + // Since this is a for loop the default cannot be reached in VectorCAST for 100% coverage + default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_HD_SOFTWARE_FAULT, SW_FAULT_ID_HD_INVALID_SWITCH_ID, i ) break; Index: firmware/App/Controllers/SyringePump.c =================================================================== diff -u -r9051b47d2d0e9f112d4ebc310a5572844b7528f4 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 9051b47d2d0e9f112d4ebc310a5572844b7528f4) +++ firmware/App/Controllers/SyringePump.c (.../SyringePump.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -498,12 +498,9 @@ if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) && ( heparinDeliveryState != HEPARIN_STATE_OFF ) ) { { - heparinDeliveryState = HEPARIN_STATE_STOPPED; - if ( ( SYRINGE_PUMP_OFF_STATE == syringePumpState ) ) - { - syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; - syringePumpRetractRequested = TRUE; - } + heparinDeliveryState = HEPARIN_STATE_STOPPED; + syringePumpSetRate = SYRINGE_PUMP_RETRACT_RATE; + syringePumpRetractRequested = TRUE; } } @@ -1818,9 +1815,9 @@ syringePumpRampTimerCtr++; if ( syringePumpRampUpToggleTime > syringePumpSetToggleTime ) { - syringePumpRampUpToggleTime = (U32)((F32)SYRINGE_PUMP_START_RAMP_SPEED / - (F32)( ( syringePumpRampTimerCtr * syringePumpRampTimerCtr * syringePumpRampTimerCtr ) / SYRINGE_PUMP_RAMP_DIVISOR ) ); - syringePumpRampUpPct = syringePumpSetToggleTime / syringePumpRampUpToggleTime; + syringePumpRampUpToggleTime = (U32)( (F32)SYRINGE_PUMP_START_RAMP_SPEED / + ( (F32)( syringePumpRampTimerCtr * syringePumpRampTimerCtr * syringePumpRampTimerCtr ) / (F32)SYRINGE_PUMP_RAMP_DIVISOR ) ); + syringePumpRampUpPct = (F32)syringePumpSetToggleTime / (F32)syringePumpRampUpToggleTime; if ( syringePumpRampUpToggleTime > syringePumpSetToggleTime ) { setFPGASyringePumpStepToggleTime( syringePumpRampUpToggleTime ); Index: firmware/App/Modes/Dialysis.c =================================================================== diff -u -r19a8bf98a7154e24c35da25225d4b55bf70ddd09 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 19a8bf98a7154e24c35da25225d4b55bf70ddd09) +++ firmware/App/Modes/Dialysis.c (.../Dialysis.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -65,6 +65,7 @@ static F32 resCurrVolume[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoir current volume. static F32 resLastVolume[ NUM_OF_DG_RESERVOIRS ]; ///< Reservoir previous volume. static F32 measUFVolumeFromPriorReservoirs; ///< Current total ultrafiltration volume from previous reservoirs in current treatment. +static F32 lcLastSteadyWeight[NUM_OF_LOAD_CELLS]; ///< Load Cell Last Steady Weight for drift test static U32 uFTimeMS; ///< Current elapsed ultrafiltration time (in ms). Used for calculating UF reference volume. static U32 lastUFTimeStamp; ///< HD timer value when we last took stock of ultrafiltration time (so we can determine how much time has elapsed since). @@ -106,6 +107,7 @@ static void updateUFVolumes( void ); static void publishSalineBolusData( void ); +static void checkLoadCellsStablePrimaryBackupDriftOutOfRange( DG_RESERVOIR_ID_T reservoirID ); /*********************************************************************//** * @brief @@ -118,6 +120,8 @@ *************************************************************************/ void initDialysis( void ) { + U16 i; + currentDialysisState = DIALYSIS_START_STATE; currentUFState = UF_START_STATE; currentSalineBolusState = SALINE_BOLUS_STATE_IDLE; @@ -142,6 +146,10 @@ uFAccuracyCheckTimerCtr = 0; lastUFVolumeChecked = 0.0; + for (i=0; i (LOAD_CELL_ILLEGAL_WEIGHT_VALUE + 1) ) + { + // Weight has been previously saved, ok to test + loadCellPreviousDrift = lcLastSteadyWeight[lcPrimaryIndex] - lcLastSteadyWeight[lcBackupIndex]; + driftDiff = fabs ( loadCellCurrentDrift - loadCellPreviousDrift ); + } + // Save latest reading for next test time + lcLastSteadyWeight[lcPrimaryIndex] = loadCellPrimaryWeight; + lcLastSteadyWeight[lcBackupIndex] = loadCellBackupWeight; + + // Check for drift out of range + if ( driftDiff > LOAD_CELL_PRIMARY_BACKUP_MAX_ALLOWED_DRIFT_GRAMS ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_HD_LOAD_CELL_PRIMARY_BACKUP_DRIFT_OUT_OF_RANGE, loadCellCurrentDrift, loadCellPreviousDrift ) + } +} + /**@}*/ Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -r19a8bf98a7154e24c35da25225d4b55bf70ddd09 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 19a8bf98a7154e24c35da25225d4b55bf70ddd09) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -586,7 +586,6 @@ static HD_STANDBY_STATE_T handleStandbyModeWaitForDGFlushCmdResponseState( void ) { DG_CMD_RESPONSE_T dgCmdResp; - HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DG_FLUSH_CMD_RESPONSE_STATE; BOOL result = FALSE; @@ -666,7 +665,6 @@ static HD_STANDBY_STATE_T handleStandbyModeWaitForDGHeatDisinfectCmdResponseState( void ) { DG_CMD_RESPONSE_T dgCmdResp; - HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DG_HEAT_DISINFECT_CMD_RESPONSE_STATE; BOOL result = FALSE; @@ -743,7 +741,6 @@ static HD_STANDBY_STATE_T handleStandbyModeWaitForDGChemDisinfectCmdResponseState( void ) { DG_CMD_RESPONSE_T dgCmdResp; - HD_STANDBY_STATE_T state = STANDBY_WAIT_FOR_DG_CHEM_DISINFECT_CMD_RESPONSE_STATE; BOOL result = FALSE; Index: firmware/App/Modes/Rinseback.c =================================================================== diff -u -r19a8bf98a7154e24c35da25225d4b55bf70ddd09 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 19a8bf98a7154e24c35da25225d4b55bf70ddd09) +++ firmware/App/Modes/Rinseback.c (.../Rinseback.c) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -491,14 +491,8 @@ { RINSEBACK_STATE_T result = RINSEBACK_STOP_STATE; - // Have we been in this stopped state for too long w/o having delivered full blood volume back to patient? - if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < rinsebackTargetVolume_mL ) ) - { - signalGoToTreatmentStopped(); - activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); - } // Have we been in this stopped state for too long despite having delivered full blood volume back to patient? - else if ( ( rinsebackTimerCtr > MAX_RINSEBACK_DONE_TIME ) && ( getRinsebackVolume() >= rinsebackTargetVolume_mL ) ) + if ( ( rinsebackTimerCtr > MAX_RINSEBACK_DONE_TIME ) && ( getRinsebackVolume() >= rinsebackTargetVolume_mL ) ) { signalGoToTreatmentStopped(); activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); @@ -509,6 +503,12 @@ { activateAlarmNoData( ALARM_ID_HD_TREATMENT_RINSEBACK_TIMEOUT_WARNING ); } + // Have we been in this stopped state for too long w/o having delivered full blood volume back to patient? + else if ( ( rinsebackTimerCtr > MAX_RINSEBACK_TIME ) && ( getRinsebackVolume() < rinsebackTargetVolume_mL ) ) + { + signalGoToTreatmentStopped(); + activateAlarmNoData( ALARM_ID_TREATMENT_RINSEBACK_TIMEOUT_ALARM ); + } else if ( TRUE == recircRequested ) { signalRinsebackToRecirc(); Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r03c434e902b640c4093cfc96ceaeb93940c15340 -r9848d793638e2f613678e60ea7c0f1e7bc31d9eb --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 03c434e902b640c4093cfc96ceaeb93940c15340) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 9848d793638e2f613678e60ea7c0f1e7bc31d9eb) @@ -7,8 +7,8 @@ * * @file SystemCommMessages.h * -* @author (last) Darren Cox -* @date (last) 10-Mar-2022 +* @author (last) Dara Navaei +* @date (last) 14-Jun-2022 * * @author (original) Dara Navaei * @date (original) 05-Nov-2019 @@ -569,10 +569,8 @@ // MSG_ID_HD_VALVES_SET_POSITION void handleSetHDValvePositionOverrideRequest( MESSAGE_T *message ); -#ifdef DEBUG_ENABLED // MSG_ID_HD_VALVES_SET_PWM_OVERRIDE void handleSetHDValvePWMOverrideRequest( MESSAGE_T *message ); -#endif // MSG_ID_HD_SOFTWARE_RESET_REQUEST void handleHDSoftwareResetRequest( MESSAGE_T *message );