Index: firmware/App/Modes/ModeChemicalDisinfect.c =================================================================== diff -u -r4daa230ef3173ca71bab91c0c28457e6ac341797 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 4daa230ef3173ca71bab91c0c28457e6ac341797) +++ firmware/App/Modes/ModeChemicalDisinfect.c (.../ModeChemicalDisinfect.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -28,6 +28,7 @@ #include "ModeStandby.h" #include "NVDataMgmt.h" #include "OperationModes.h" +#include "PersistentAlarm.h" #include "Pressures.h" #include "Reservoirs.h" #include "ROPump.h" @@ -93,16 +94,17 @@ #define DISINFECTANT_MIX_RATIO_FILL 65.67F ///< Disinfectant mixing ratio during fill, water/disinfectant. #define RO_PUMP_FILL_DISINECTANT_FLOW_RATE_LPM 0.4F ///< ROP flow rate for disinfectant prime #define MAX_RO_PUMP_FILL_DISINFECTANT_PRESSURE_PSI 130.0F ///< ROP max pressure for disinfectant fill -#define FLUSH_DISINFECTANT_INITIAL_WAIT_TIME ( 30 * MS_PER_SECOND ) ///< Initial time to wait for temperature and conductivity to reach target in disinfectant flush state -#define FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME ( 60 * MS_PER_SECOND ) ///< Additional time to wait for temperature and conductivity to reach target in disinfectant flush state +#define FLUSH_DISINFECTANT_INITIAL_WAIT_TIME_MS ( 30 * MS_PER_SECOND ) ///< Initial time to wait for temperature and conductivity to reach target in disinfectant flush state in milliseconds. +#define FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME_MS ( 60 * MS_PER_SECOND ) ///< Additional time to wait for temperature and conductivity to reach target in disinfectant flush state // Parameters during disinfect defines #define CHEM_DISINFECT_TARGET_RO_FLOW_LPM 0.5F ///< Chemical disinfect target RO flow rate in L/min. #define CHEM_DISINFECT_MAX_RO_PRESSURE_PSI 130 ///< Chemical disinfect maximum RO pressure in psi. #define MIN_DISINFECT_CONDUCTIVITY_US_PER_CM 150.0F ///< Minimum conductivity for mixed disinfect fluid in us/cm #define MAX_DISINFECT_CONDUCTIVITY_US_PER_CM 650.0F ///< Maximum conductivity for mixed disinfect fluid in us/cm #define MAX_DISINFECT_TPO_TEMPERATURE_C 55.0F ///< Maximum temperature for mixed disinfect fluid at outlet of heater in dec C -#define MIN_MAX_CONDUCTIVITY_WAIT_TASK_INT ( ( 10 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Number of task intervals to wait for conductivity and temperature to stabilize +#define DISINFECT_COND_OUT_OF_RANGE_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< Chemical disinfect conductivity out of range in milliseconds. +#define DISINFECT_TEMP_OUT_OF_RANGE_TIMEOUT_MS ( 1 * MS_PER_SECOND ) ///< Chemical disinfect temperature out of range in milliseconds. // Initial disinfectant fill of R1 and R2 #define RSRVRS_FULL_VOL_ML 1800.0F ///< Reservoirs 1 & 2 full volume in mL. @@ -111,7 +113,7 @@ // Parameters controlling chemical disinfect #define TARGET_CHEM_DISINFECT_TIME_MS ( 12 * SEC_PER_MIN * MS_PER_SECOND ) ///< Expected chemical disinfect time in ms. -#define CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ( 6 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect reaching to minimum temperature timeout in milliseconds. +#define CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Chemical disinfect reaching to minimum temperature timeout in milliseconds. #define CHEM_DISINFECT_TARGET_TEMPERATURE_C 37.0F ///< Chemical disinfect target water temperature in C. #define CHEM_DISINFECT_MINIMUM_TEMPERATURE_C 35.0F ///< Chemical disinfect target water temperature in C. #define CHEM_DISINFECT_HEATER_CONTROL_TEMPERATURE_C 45.0F ///< Chemical disinfect heater control water temperature in C. @@ -153,14 +155,13 @@ static U32 stateTimer; ///< Chemical disinfect state timer to be used in different states. static U32 stateTrialCounter; ///< Chemical disinfect state trial counter to be used for retries in different states. static BOOL isThisLastDrain; ///< Boolean flag to check whether draining R1 and R2 is at the end of the chemical disinfect cycle or in the beginning. -static BOOL haveInletWaterChecksPassed; ///< Chemical disinfect inlet water checks flag. static DG_RESERVOIR_STATUS_T rsrvr1Status; ///< Reservoir 1 status. static DG_RESERVOIR_STATUS_T rsrvr2Status; ///< Reservoir 2 status. static BOOL isRsrvrLeaking; ///< Flag used to determine if reservoir is leaking. static U32 rsrvrsVolMonitorCounter; ///< Timer/counter used to determine if reservoir is leaking. static U32 chemDisinfectReservoirTime; ///< Chemical disinfect accumulated time in ms above the temperature target in one cycle for reservoir 1 or reservoir 2. static BOOL ischemDisinfectWarmupTargetReached; ///< Flag that indicates whether the disinfect warmup target has been reached. -static BOOL isChemDisinfectTemperatureAboveTarget; ///< Flag that indicates if the disinfect temperature is currently above the target. +static BOOL isChemDisinfectTempAboveTarget; ///< Flag that indicates if the disinfect temperature is currently above the target. static U32 DisinfectCycleCounter; ///< Counter for disinfect cycles. static U32 drpControlTimerCounter; ///< Timer/counter for reservoir volume control of DRP. static U32 dataPublishCounter; ///< Chemical Disinfect data publish timer/counter. @@ -169,7 +170,6 @@ static U32 flushCircWaitTime; ///< Variable time period in ms to wait in flush circulation state to check sensor values. static U32 flushDisinfectantWaitTime; ///< Variable time period in ms to wait in disinfectant flush state to check sensor values. static U32 primeAcidSteadyStateCounter; ///< Prime acid steady state counter. -static U32 minMaxConductivityWaitCounter; ///< Timer/counter for the disinfect conductivity check. static U32 rsrvrFillStableTimeCounter; ///< Task interval timer/counter for determining if reservoir has reached fill target. static U32 rsrvrFillToFullStableTimeCounter; ///< Task interval timer/counter for determining if reservoir is full. static F32 R1FullVolume; ///< R1 volume determined by fill to full function. @@ -204,8 +204,9 @@ static void chemicalDisinfectTimerUpdate( void ); static void publishChemicalDisinfectData( void ); static void monitorModeChemicalDisinfect( void ); -static void writeDisinfectDataToNV( void ); +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ); + /*********************************************************************//** * @brief * The initChemicalDisinfectMode function initializes the chemical @@ -237,10 +238,9 @@ isRsrvrLeaking = FALSE; chemDisinfectReservoirTime = 0; ischemDisinfectWarmupTargetReached = FALSE; - isChemDisinfectTemperatureAboveTarget = FALSE; + isChemDisinfectTempAboveTarget = FALSE; chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_NOT_RUNNING; disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; - haveInletWaterChecksPassed = FALSE; isRsrvrLeaking = FALSE; rsrvrsVolMonitorCounter = 0; DisinfectCycleCounter = 0; @@ -250,12 +250,14 @@ flushCircWaitTime = 0; flushDisinfectantWaitTime = 0; primeAcidSteadyStateCounter = 0; - minMaxConductivityWaitCounter = 0; rsrvrFillStableTimeCounter = 0; rsrvrFillToFullStableTimeCounter = 0; R1FullVolume = 0.0F; R2FullVolume = 0.0F; disinfectantMixRatio = 0.0F; + + initPersistentAlarm( ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE, DISINFECT_TEMP_OUT_OF_RANGE_TIMEOUT_MS, DISINFECT_TEMP_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CHEM_DISINFECT_TARGET_COND_OUT_OF_RANGE, DISINFECT_COND_OUT_OF_RANGE_TIMEOUT_MS, DISINFECT_COND_OUT_OF_RANGE_TIMEOUT_MS ); } /*********************************************************************//** @@ -402,6 +404,9 @@ // Check if the current operation mode is chemical disinfect if ( DG_MODE_CHEM == getCurrentOperationMode() ) { + // Reset all the actuators + deenergizeActuators( NO_PARK_CONC_PUMPS ); + // Transition to mode standby requestNewOperationMode( DG_MODE_STAN ); @@ -467,6 +472,11 @@ { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; + if ( TRUE == isThisLastDrain ) + { + writeDisinfectDataToNV( USAGE_INFO_CHEM_DIS ); + } + if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) { rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ); @@ -657,6 +667,7 @@ // Set the acid dispense pump speed at the priming rate setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, DISINFECTANT_PUMP_PRIME_SPEED_ML_PER_MIN ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + disinfectantMixRatio = DISINFECTANT_MIX_RATIO_PRIME; primeAcidSteadyStateCounter = 0; state = DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT; @@ -684,14 +695,12 @@ { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT; F32 cd2Conductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); - - // Set the chemical disinfect state that is published on the UI chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_MIX_WATER_AND_ACID; handleDisinfectantMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, disinfectantMixRatio ); #ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE != getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { if ( cd2Conductivity < MIN_PRIME_ACID_CONDUCTIVITY_US_PER_CM ) @@ -705,18 +714,18 @@ // Turn off the concentrate pump requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); // Turn on the RO pump and concentrate pump to the disinfectant fill rates - setROPumpTargetFlowRateLPM( RO_PUMP_FILL_DISINECTANT_FLOW_RATE_LPM, MAX_RO_PUMP_FILL_DISINFECTANT_PRESSURE_PSI ); + setROPumpTargetFlowRateLPM( CHEM_DISINFECT_TARGET_RO_FLOW_LPM, MAX_RO_PUMP_FILL_DISINFECTANT_PRESSURE_PSI ); setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, DISINFECTANT_PUMP_FILL_SPEED_ML_PER_MIN ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - disinfectantMixRatio = DISINFECTANT_MIX_RATIO_FILL; - flushDisinfectantWaitTime = FLUSH_DISINFECTANT_INITIAL_WAIT_TIME; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH; + disinfectantMixRatio = DISINFECTANT_MIX_RATIO_FILL; + flushDisinfectantWaitTime = FLUSH_DISINFECTANT_INITIAL_WAIT_TIME_MS; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH; } if ( TRUE == didTimeout( stateTimer, PRIME_ACID_LINE_TIMEOUT_MS ) ) { prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_PRIME_ACID_LINE_TIME_OUT; } @@ -741,46 +750,35 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectantFlushState( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH; + chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_MIX_WATER_AND_ACID; - // Set the chemical disinfect state that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_MIX_WATER_AND_ACID; - + writeDisinfectDataToNV( USAGE_INFO_CHEM_DIS_START ); handleDisinfectantMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, disinfectantMixRatio ); if ( TRUE == didTimeout( stateTimer, flushDisinfectantWaitTime ) ) { - F32 TdiTemp = getTemperatureValue( TEMPSENSORS_INLET_DIALYSATE ); - F32 cd2Conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - BOOL isCD2OutofRange = ( cd2Conductivity < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || cd2Conductivity > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); - BOOL isTPoOutofRange = ( TPoTemp > MAX_DISINFECT_TPO_TEMPERATURE_C ); + F32 cd2Cond = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + BOOL isCD2OutOfRange = ( ( cd2Cond < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || cd2Cond > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ) ? TRUE : FALSE ); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) { - isCD2OutofRange = FALSE; + isCD2OutOfRange = FALSE; } #endif - if ( ( TRUE == isCD2OutofRange ) || ( TRUE == isTPoOutofRange ) ) - { // The conditions have not been met + if ( TRUE == isCD2OutOfRange ) + { + // The conditions have not been met // Check if we have exceeded the number of trials. If not, try another time - if (++stateTrialCounter < MAX_ALLOWED_DISINFECTANT_FLUSH_PERIODS ) + if ( ++stateTrialCounter < MAX_ALLOWED_DISINFECTANT_FLUSH_PERIODS ) { - stateTimer = getMSTimerCount(); - flushDisinfectantWaitTime = FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME; + stateTimer = getMSTimerCount(); + flushDisinfectantWaitTime = FLUSH_DISINFECTANT_ADDITIONAL_WAIT_TIME_MS; } else { - if ( ( TRUE == isTPoOutofRange ) ) - { - alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; - } - else - { - alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE; //TODO: ALARM_ID_DG_NEW_CON - } - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + state = DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT; } } else @@ -792,13 +790,13 @@ setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_CLOSED ); - rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - chemDisinfectReservoirTime = 0; - rsrvrFillStableTimeCounter = 0; - isChemDisinfectTemperatureAboveTarget = FALSE; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT; + rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; + rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; + chemDisinfectReservoirTime = 0; + rsrvrFillStableTimeCounter = 0; + isChemDisinfectTempAboveTarget = FALSE; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT; } } @@ -822,10 +820,8 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectFillWithDisinfectantState( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_FILL_WITH_DISINFECTANT; + chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_DISINFECT_DEVICE; - // Set the chemical disinfect state that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_DISINFECT_DEVICE; - handleDisinfectantMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, disinfectantMixRatio ); // First reservoir 1 must be full @@ -839,7 +835,7 @@ { // Once R1 is full, keep monitoring for R2 level and timeout rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_PARTIAL_FILL_UP_TIMEOUT_MS ); - chemicalDisinfectTimerUpdate( ); + chemicalDisinfectTimerUpdate(); // Once R2 is full, transition to the next state if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) @@ -850,21 +846,21 @@ // Set the drain pump to control mode controlDRPByReservoirVolume( DG_RESERVOIR_2, TRUE ); //Initialize the PI controller for DRP - isRsrvrLeaking = FALSE; - ischemDisinfectWarmupTargetReached = FALSE; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2; + isRsrvrLeaking = FALSE; + ischemDisinfectWarmupTargetReached = FALSE; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } return state; @@ -886,28 +882,26 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR1ToR2State( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2; + chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_DISINFECT_DEVICE; - // Set the chemical disinfect that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_DISINFECT_DEVICE; - handleDisinfectantMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, disinfectantMixRatio ); - chemicalDisinfectTimerUpdate( ); + chemicalDisinfectTimerUpdate(); - if ( (TRUE != ischemDisinfectWarmupTargetReached ) && ( TRUE == didTimeout( stateTimer, CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ) ) ) + if ( ( FALSE == ischemDisinfectWarmupTargetReached ) && ( TRUE == didTimeout( stateTimer, CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ) ) ) { // Heating up to minimum temperature for chemical disinfect failed - alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; + alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } if ( TRUE == didTimeout( stateTimer, MAX_DISINFECT_STATE_TIME_MS ) ) { // Heating up to minimum temperature for chemical disinfect failed - alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; + alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } - if ( chemDisinfectReservoirTime >= DISINFECT_CYCLE_PERIOD_MS ) + if ( chemDisinfectReservoirTime >= DISINFECT_CYCLE_PERIOD_MS ) { // Set the actuators to fill R2 and drain R1 state setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); @@ -954,17 +948,17 @@ } if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { - isRsrvrLeaking = FALSE; - chemDisinfectReservoirTime = 0; - isChemDisinfectTemperatureAboveTarget = FALSE; - ischemDisinfectWarmupTargetReached = FALSE; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; + isRsrvrLeaking = FALSE; + chemDisinfectReservoirTime = 0; + isChemDisinfectTempAboveTarget = FALSE; + ischemDisinfectWarmupTargetReached = FALSE; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } else { @@ -989,28 +983,26 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectDisinfectR2ToR1State( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1; - - // Set the chemical disinfect that is published on the UI chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_DISINFECT_DEVICE; handleDisinfectantMixing( getMeasuredFlowRateLPM( RO_FLOW_SENSOR ) * ML_PER_LITER, disinfectantMixRatio ); - chemicalDisinfectTimerUpdate( ); + chemicalDisinfectTimerUpdate(); if ( (TRUE != ischemDisinfectWarmupTargetReached ) && ( TRUE == didTimeout( stateTimer, CHEM_DISINFECT_START_TEMP_TIMEOUT_MS ) ) ) { // Heating up to minimum temperature for chemical disinfect failed - alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; + alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } if ( TRUE == didTimeout( stateTimer, MAX_DISINFECT_STATE_TIME_MS ) ) { // Heating up to minimum temperature for chemical disinfect failed - alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; + alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } - if ( chemDisinfectReservoirTime >= DISINFECT_CYCLE_PERIOD_MS ) + if ( chemDisinfectReservoirTime >= DISINFECT_CYCLE_PERIOD_MS ) { if ( REQUIRED_DISINFECT_CYCLES == ++DisinfectCycleCounter ) { @@ -1035,12 +1027,10 @@ initDrainParameters( DG_RESERVOIR_2 ); rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - isThisLastDrain = TRUE; - // Set the chemical disinfect state that is published on the UI + isThisLastDrain = TRUE; chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_FLUSH_AFTER_DISINFECT; - writeDisinfectDataToNV(); - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_DRAIN_R1; } else { @@ -1089,17 +1079,17 @@ } if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { - chemDisinfectReservoirTime = 0; - isChemDisinfectTemperatureAboveTarget = FALSE; - ischemDisinfectWarmupTargetReached = FALSE; - isRsrvrLeaking = FALSE; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2; + chemDisinfectReservoirTime = 0; + isChemDisinfectTempAboveTarget = FALSE; + ischemDisinfectWarmupTargetReached = FALSE; + isRsrvrLeaking = FALSE; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { - prevChemDisinfectState = state; - state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + prevChemDisinfectState = state; + state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } else { @@ -1121,13 +1111,9 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeBasicPathState( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_CANCEL_BASIC_PATH; + chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_CANCEL_DISINFECT; + cancellationMode = CANCELLATION_MODE_BASIC; - // Set the chemical disinfect that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_CANCEL_DISINFECT; - - // Set the cancellation mode - cancellationMode = CANCELLATION_MODE_BASIC; - failChemicalDisinfect(); return state; @@ -1146,10 +1132,8 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCancelModeWaterPathState( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; + chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_CANCEL_DISINFECT; - // Set the chemical disinfect that is published on the UI - chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_CANCEL_DISINFECT; - if ( CANCELLATION_MODE_NONE == cancellationMode ) { // Stop all the actuators first then decide who should run next @@ -1219,11 +1203,9 @@ static DG_CHEM_DISINFECT_STATE_T handleChemicalDisinfectCompleteState( void ) { DG_CHEM_DISINFECT_STATE_T state = DG_CHEM_DISINFECT_STATE_COMPLETE; - - // Set the chemical disinfect that is published on the UI chemDisinfectUIState = CHEM_DISINFECT_UI_STATE_COMPLETE; - stopChemicalDisinfect(); + requestNewOperationMode( DG_MODE_CHFL ); return state; } @@ -1256,7 +1238,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrFillStatus( DG_RESERVOIR_ID_T r, F32 targetVol, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_BELOW_TARGET; - F32 volume = 0.0; + F32 volume = 0.0F; if ( DG_RESERVOIR_1 == r ) { @@ -1285,9 +1267,9 @@ else if ( TRUE == didTimeout( stateTimer, timeout ) ) { // Failed to fill ontime. Update the previous chemical disinfect state and transition to basic cancellation - prevChemDisinfectState = chemDisinfectState; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + prevChemDisinfectState = chemDisinfectState; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -1444,7 +1426,7 @@ resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP_VOLUME, MIN_DRP_VOLUME_CONTROL_RPM ); setDrainPumpTargetRPM( MIN_DRP_VOLUME_CONTROL_RPM ); //set the initial pump speed to the minimum } - else if ( TRUE == didTimeout( drpControlTimerCounter, DRP_VOLUME_CONTROL_INTERVAL_TASK_INT) ) + else if ( TRUE == didTimeout( drpControlTimerCounter, DRP_VOLUME_CONTROL_INTERVAL_TASK_INT ) ) { // Control at set interval F32 tgtVolume = (F32)DRP_VOLUME_CONTROL_TARGET_VOLUME_ML; // this is the default if no full volume is available F32 actVolume; @@ -1498,15 +1480,15 @@ // reset the chemical disinfect timers and check whether heating up has timed out if ( TdiTemp >= CHEM_DISINFECT_TARGET_TEMPERATURE_C ) { - isChemDisinfectTemperatureAboveTarget = TRUE; + isChemDisinfectTempAboveTarget = TRUE; ischemDisinfectWarmupTargetReached = TRUE; } - else if ( TdiTemp < CHEM_DISINFECT_MINIMUM_TEMPERATURE_C ) + else if ( TdiTemp < CHEM_DISINFECT_MINIMUM_TEMPERATURE_C ) { - isChemDisinfectTemperatureAboveTarget = FALSE; + isChemDisinfectTempAboveTarget = FALSE; } - if ( TRUE == isChemDisinfectTemperatureAboveTarget ) + if ( TRUE == isChemDisinfectTempAboveTarget ) { chemDisinfectReservoirTime += TASK_GENERAL_INTERVAL; } @@ -1585,15 +1567,9 @@ { BOOL isRsrvrVolumeOutOfRange = FALSE; isRsrvrLeaking = FALSE; + isRsrvrVolumeOutOfRange |= fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; + isRsrvrVolumeOutOfRange |= fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; - if ( DG_CHEM_DISINFECT_STATE_DISINFECT_R1_TO_R2 == chemDisinfectState ) - { - isRsrvrVolumeOutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; - } - else if ( DG_CHEM_DISINFECT_STATE_DISINFECT_R2_TO_R1 == chemDisinfectState ) - { - isRsrvrVolumeOutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2FullVolume ) > RSRVRS_MAX_LEAK_VOL_CHANGE_ML; - } if ( ( TRUE == isRsrvrVolumeOutOfRange ) ) { // If the leak is the first time after a while, set the flag and start the timer @@ -1637,42 +1613,37 @@ areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW ); areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE ); - if ( ( TRUE == areInletWaterAlarmsActive ) ) + if ( TRUE == areInletWaterAlarmsActive ) { prevChemDisinfectState = chemDisinfectState; chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } // Check the temperature and conductivity of the diluted disinfectant - if ( chemDisinfectState > DG_CHEM_DISINFECT_STATE_PRIME_DISINFECTANT ) + if ( ( chemDisinfectState >= DG_CHEM_DISINFECT_STATE_DISINFECTANT_FLUSH ) && ( chemDisinfectState <= DG_CHEM_DISINFECT_STATE_PARTIAL_DRAIN_R2_FILL_R1_TO_R2 ) ) { // Disinfect conditions check - F32 cd2Conductivity = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); - F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - BOOL isCD2OutofRange = ( cd2Conductivity < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM || cd2Conductivity > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); + F32 cd2CondUSCM = getConductivityValue( (U32)CONDUCTIVITYSENSORS_CD2_SENSOR ); + F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + BOOL isCD2OutofRange = ( ( cd2CondUSCM < MIN_DISINFECT_CONDUCTIVITY_US_PER_CM ) || ( cd2CondUSCM > MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ) ? TRUE : FALSE ); + BOOL isTPoOutofRange = ( TPoTemp > MAX_DISINFECT_TPO_TEMPERATURE_C ); #ifndef _RELEASE_ if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_DISINFECT_CONDUCTIVITY_CHECK ) ) { isCD2OutofRange = FALSE; } #endif - BOOL isTPoOutofRange = ( TPoTemp > MAX_DISINFECT_TPO_TEMPERATURE_C ); - if ( TRUE != isCD2OutofRange ) + checkPersistentAlarm( ALARM_ID_DG_CHEM_DISINFECT_TARGET_COND_OUT_OF_RANGE, isCD2OutofRange, cd2CondUSCM, MAX_DISINFECT_CONDUCTIVITY_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE, isTPoOutofRange, TPoTemp, MAX_DISINFECT_TPO_TEMPERATURE_C ); + + if ( ( TRUE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_TARGET_COND_OUT_OF_RANGE ) ) || + ( TRUE == isAlarmActive( ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_OUT_OF_RANGE ) ) ) { - minMaxConductivityWaitCounter = 0; + prevChemDisinfectState = chemDisinfectState; + chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; } - else if ( ++minMaxConductivityWaitCounter >= MIN_MAX_CONDUCTIVITY_WAIT_TASK_INT ) - { - alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE; //ALARM_ID_DG_NEW_CON; TODO - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } - else if ( ( TRUE == isTPoOutofRange ) ) - { - alarmDetectedPendingTrigger = ALARM_ID_DG_CHEM_DISINFECT_TARGET_TEMP_TIMEOUT; - chemDisinfectState = DG_CHEM_DISINFECT_STATE_CANCEL_WATER_PATH; - } } } @@ -1682,14 +1653,15 @@ * non-volatile memory. * @details Inputs: disinfectNVOps * @details Outputs: disinfectNVOps + * @param info the type disinfect data to write to the memory (i.e. heat + * disinfect start time) * @return: none *************************************************************************/ -// TODO: this may conflict with heat disinfect? -static void writeDisinfectDataToNV( void ) +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ) { if ( FALSE == disinfectNVOps.hasDisStatusBeenWrittenToNV ) { - disinfectNVOps.hasDisStatusBeenWrittenToNV = setLastDisinfectDate( USAGE_INFO_CHEM_DIS, getRTCTimestamp() ); + disinfectNVOps.hasDisStatusBeenWrittenToNV = setLastDisinfectDate( info, getRTCTimestamp() ); } }