Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r9c6a93cfc7757e5b1e6a443e16fb5d33c0601512 -r0c599603188536e9d329fbd60a8768affd0c49a2 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 9c6a93cfc7757e5b1e6a443e16fb5d33c0601512) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 0c599603188536e9d329fbd60a8768affd0c49a2) @@ -240,7 +240,7 @@ } else if ( TRUE == isConductTooHigh ) { - checkPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY, isConductTooHigh, conductivity, COND_SENSOR_CPI_WARNING_HIGH ); + checkPersistentAlarm( ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY, isConductTooHigh, conductivity, COND_SENSOR_CPI_WARNING_LOW ); } else if ( TRUE == isConductInWarningRange ) { Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -ref46e2aa7eba74dabd99bfcd9e6b38b8ce77820c -r0c599603188536e9d329fbd60a8768affd0c49a2 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision ef46e2aa7eba74dabd99bfcd9e6b38b8ce77820c) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 0c599603188536e9d329fbd60a8768affd0c49a2) @@ -247,22 +247,24 @@ } else { - if ( TRUE == isEmptyAcidBottle() ) - { - activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); // trigger empty acid bottle alarm - setBottlesNeedPrimeFlag( TRUE ); - } - else if ( TRUE == isEmptyBicarbBottle() ) - { - setBottlesNeedPrimeFlag( TRUE ); - activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); // trigger empty bicarb bottle alarm - } - else if ( ( FALSE == isAlarmActive( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ) ) || - ( FALSE == isAlarmActive( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ) ) ) - { - requestNewOperationMode( DG_MODE_GENE ); - } + requestNewOperationMode( DG_MODE_GENE ); } + + if ( TRUE == isEmptyAcidBottle() ) // is acid volume < 10% + { + setThisFisrtFillFlag( TRUE ); // indicates bottles need prime + activateAlarmNoData( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ); // trigger empty acid bottle alarm + } + else if ( TRUE == isEmptyBicarbBottle() ) // is bicarb volume < 10% + { + setThisFisrtFillFlag( TRUE ); // indicates bottles need prime + activateAlarmNoData( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ); // trigger empty bicarb bottle alarm + } + else if ( ( FALSE == isAlarmActive( ALARM_ID_DG_ACID_BOTTLE_LOW_VOLUME ) ) || + ( FALSE == isAlarmActive( ALARM_ID_DG_BICARB_BOTTLE_LOW_VOLUME ) ) ) + { + requestNewOperationMode( DG_MODE_FILL ); + } } // Drain timed out raise the alarm Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r60834a8b3bf8348515a367ba635aa8ad63ea7f22 -r0c599603188536e9d329fbd60a8768affd0c49a2 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 60834a8b3bf8348515a367ba635aa8ad63ea7f22) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 0c599603188536e9d329fbd60a8768affd0c49a2) @@ -100,7 +100,6 @@ BOOL fillAvgConductivityOutOfRange; ///< Fill average conductivity out of range. BOOL fillEmtyAcidBottleDetected; ///< Fill acid bottle empty detected. BOOL fillEmtyBicarbBottleDetected; ///< Fill bicarb bottle empty detected. - BOOL fillBottlesNeedPrimeFlag; ///< Fill flag to indicate acid and bicarb bottle need priming. } FILL_CONDITION_STATUS_T; /// DG broadcast dialysate fill data structure. @@ -383,7 +382,6 @@ fillStatus.fillAvgConductivityOutOfRange = FALSE; fillStatus.fillEmtyAcidBottleDetected = FALSE; fillStatus.fillEmtyBicarbBottleDetected = FALSE; - fillStatus.fillBottlesNeedPrimeFlag = FALSE; } /*********************************************************************//** @@ -414,26 +412,6 @@ /*********************************************************************//** * @brief - * The isBadFill function returns the boolean flag that indicates - * whether the bad fill is detected at the end of the fill mode. - * @details Inputs: none - * @details Outputs: none - * @return TRUE if bad fill, otherwise FALSE - *************************************************************************/ -BOOL isBadFill( void ) -{ - BOOL badFillFlag = FALSE; - - if ( TRUE == isAvgConductivityOutOfRange() ) - { - badFillFlag = TRUE; - } - - return badFillFlag; -} - -/*********************************************************************//** - * @brief * The isEmptyAcidBottle function returns the boolean flag that indicates * whether the acid bottle is empty. * @details Inputs: none @@ -460,35 +438,19 @@ /*********************************************************************//** * @brief - * The setBottlesNeedPrimeFlag function sets the boolean flag that indicates + * The setThisFisrtFillFlag function sets the boolean flag that indicates * the acid and bicarb bottle need priming. * @details Inputs: none * @details Outputs: none - * @return fillStatus.fillBottlesNeedPrimeFlag * @param flag to TRUE if prime is needed otherwise FALSE *************************************************************************/ -BOOL setBottlesNeedPrimeFlag( BOOL flag ) +void setThisFisrtFillFlag( BOOL flag ) { - fillStatus.fillBottlesNeedPrimeFlag = flag; - - return fillStatus.fillBottlesNeedPrimeFlag; + fillStatus.isThisFirstFill = flag; } /*********************************************************************//** * @brief - * The getBottlesNeedPrimeFlag function gets the boolean flag that indicates - * the acid and bicarb bottle need priming. - * @details Inputs: none - * @details Outputs: none - * @return fillStatus.fillBottlesNeedPrimeFlag - *************************************************************************/ -BOOL getBottlesNeedPrimeFlag( void ) -{ - return fillStatus.fillBottlesNeedPrimeFlag; -} - -/*********************************************************************//** - * @brief * The handleTestInletWaterState function tests for inlet water quality * and if this is the first fill of a treatment, prime the acid and bicarb * lines before jumping to dialysate production state. @@ -507,7 +469,7 @@ // If this is the first fill of a treatment, prime acid and bicarb lines, otherwise transition // to dialysate production directly #ifndef DISABLE_MIXING - if ( TRUE == isThisTheFirstFill() || TRUE == getBottlesNeedPrimeFlag() ) + if ( TRUE == isThisTheFirstFill() ) { // Prepare the acid and bicarb pumps to prime the concentrate lines setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); @@ -839,20 +801,18 @@ { fillStatus.fillAvgConductivityOutOfRange = TRUE; // flag to signal idle mode to handle bad fill fillStatus.isThisFirstFill = TRUE; - setBottlesNeedPrimeFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_REPLACE_CONCENTRATE_BOTTLES, avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT, avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY ); // immediately trigger wait for dialysate alarm #2 - requestNewOperationMode( DG_MODE_GENE ); // leave fill mode and go to idle + setThisFisrtFillFlag( TRUE ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgBicarbConductivity, BICARB_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 + activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); } if ( TRUE == isValueWithinPercentRange( avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY, FIVE_PERCENT_FACTOR ) ) { fillStatus.fillAvgConductivityOutOfRange = TRUE; // flag to signal idle mode to handle bad fill fillStatus.isThisFirstFill = TRUE; - setBottlesNeedPrimeFlag( TRUE ); - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_REPLACE_CONCENTRATE_BOTTLES, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 then - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); // immediately trigger wait for dialysate alarm #2 - requestNewOperationMode( DG_MODE_GENE ); // leave fill mode and go to idle + setThisFisrtFillFlag( TRUE ); + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE, avgAcidConductivity, ACID_NORMAL_CONDUCTIVITY ); // trigger replace bottles alarm #1 then + activateAlarmNoData ( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); } #endif // Done with this fill. Calculate the average fill flow rate and average temperature Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -ref46e2aa7eba74dabd99bfcd9e6b38b8ce77820c -r0c599603188536e9d329fbd60a8768affd0c49a2 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision ef46e2aa7eba74dabd99bfcd9e6b38b8ce77820c) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 0c599603188536e9d329fbd60a8768affd0c49a2) @@ -45,10 +45,8 @@ F32 getLastFillTemperature( void ); -BOOL setBottlesNeedPrimeFlag( BOOL flag ); +void setThisFisrtFillFlag( BOOL flag ); // indicates bottles need prime when set to TRUE -BOOL getBottlesNeedPrimeFlag( void ); - void resetFillStatusParameters( void ); BOOL isThisTheFirstFill( void ); @@ -57,8 +55,6 @@ BOOL isEmptyBicarbBottle( void ); -BOOL isBadFill( void ); - BOOL isAvgConductivityOutOfRange( void ); BOOL testSetUsedAcidVolumeMLOverride( F32 value ); Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -ref46e2aa7eba74dabd99bfcd9e6b38b8ce77820c -r0c599603188536e9d329fbd60a8768affd0c49a2 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision ef46e2aa7eba74dabd99bfcd9e6b38b8ce77820c) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 0c599603188536e9d329fbd60a8768affd0c49a2) @@ -45,16 +45,13 @@ #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define TARGET_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. -#define TARGET_FLUSH_WATER_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. TODO: determine the flow rate - /// The time of HD lost comm before DG transition back to standby. #define HD_LOST_COMM_TIMEOUT_MS (5 * SEC_PER_MIN * MS_PER_SECOND ) // ********** private data ********** static DG_GEN_IDLE_MODE_STATE_T genIdleState; ///< Currently active generation idle state. static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T badFillState; ///< Current active bad fill state. -static F32 flushWaterVolumeL = 0.0; ///< Volume of water pumped by RO pump during flush water state. static U32 hdLostCommStartTime_ms = 0; ///< Lost communication with HD start time in ms. // ********** private function prototypes ********** @@ -79,8 +76,7 @@ void initGenIdleMode( void ) { genIdleState = DG_GEN_IDLE_MODE_STATE_START; - badFillState = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; - flushWaterVolumeL = 0.0; +// badFillState = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; hdLostCommStartTime_ms = 0; } @@ -118,7 +114,7 @@ // because the initial guess in the heaters driver needs the target flow to calculate // the new PWMs for the main and small primary heaters #ifndef DISABLE_FLOW_CONTROL_TREATMENT - setROPumpTargetFlowRateLPM( TARGET_FLUSH_WATER_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); + setROPumpTargetFlowRateLPM( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); setHeaterTargetTemperature( DG_PRIMARY_HEATER, getPrimaryHeaterTargetTemperature() ); startHeater( DG_PRIMARY_HEATER ); #endif @@ -187,6 +183,7 @@ switch ( genIdleState ) { case DG_GEN_IDLE_MODE_STATE_START: + badFillState = DG_HANDLE_BAD_FILL_STATE_START; genIdleState = handleIdleStartState(); break; @@ -219,7 +216,8 @@ { DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_START; - if ( TRUE == isBadFill() ) // bad fill due to conductivity is out of range and assume bottles need prime +// if ( TRUE == isBadFill() ) // bad fill due to conductivity is out of range and assume bottles need prime + if ( TRUE == isAvgConductivityOutOfRange() ) { result = DG_GEN_IDLE_MODE_STATE_HANDLE_BAD_FILL ; } @@ -304,10 +302,9 @@ *************************************************************************/ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleFirstDrainState( void ) { - DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; // after first drain is completed, go to next sub-state requestNewOperationMode( DG_MODE_DRAI ); // go to drain mode to empty bad dialysate because this is a bad fill - result = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; // after first drain is completed, go to next sub-state return result; } @@ -324,9 +321,21 @@ { DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_FLUSH_FILL; - requestNewOperationMode( DG_MODE_FILL ); // When fill is completed, it goes to generation idle mode (DG_GEN_IDLE_MODE_STATE_START) - result = DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN; // (idle 1.2) + if ( FALSE == isAlarmActive( ALARM_ID_FILL_CONDUCTIVITY_OUT_OF_RANGE ) ) // alarm is no longer active - cleared by user + { + // TODO fill only up to 1000 mL not 1500 mL + requestNewOperationMode( DG_MODE_FILL ); // When fill is completed, it goes to generation idle mode (DG_GEN_IDLE_MODE_STATE_START) + if ( TRUE == isAvgConductivityOutOfRange() ) + { + result = DG_HANDLE_BAD_FILL_STATE_FIRST_DRAIN; + } + else + { + result = DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN; // (idle 1.2) + } + } + return result; } @@ -340,10 +349,9 @@ *************************************************************************/ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleSecondDrainState( void ) { - DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_SECOND_DRAIN; + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_REFILL; // after second drain completed, go to refill sub-state (idle 1.3) requestNewOperationMode( DG_MODE_DRAI ); // go to drain mode to empty bad dialysate because this is a bad fill - result = DG_HANDLE_BAD_FILL_STATE_REFILL; // after second drain completed, go to refill sub-state (idle 1.3) return result; } @@ -358,10 +366,11 @@ *************************************************************************/ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( void ) { - DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_REFILL; + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_CLEAR_ALARM; // (idle 1.4) + // TODO fill only up to 1500 mL not 1000 mL + requestNewOperationMode( DG_MODE_FILL ); - result = DG_HANDLE_BAD_FILL_STATE_CLEAR_ALARM; // (idle 1.4) return result; } @@ -376,7 +385,7 @@ *************************************************************************/ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleClearAlarmState( void ) { - DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_CLEAR_ALARM; + DG_GEN_IDLE_MODE_BAD_FILL_STATE_T result = DG_HANDLE_BAD_FILL_STATE_START; // clear wait for dialysate alarm condition to allow resume clearAlarmCondition( ALARM_ID_CREATING_DIALYSATE_PLEASE_WAIT ); // resume option will appear