Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -re95b1d3c47166be8a6852818a70b4c6231881b86 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision e95b1d3c47166be8a6852818a70b4c6231881b86) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -57,6 +57,8 @@ #define MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ( 60 * MS_PER_SECOND ) ///< Conductivity sensor error window. #define COND_SENSOR_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity sensor out of range error. +#define INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Inlet water conductivity sensor out of range timeout in milliseconds. +#define INLET_WATER_COND_SENSOR_OUT_OF_RANGE_CLEAR_MS ( 1 * MS_PER_SECOND ) ///< Inlet water conductivity sensor out of range clear in milliseconds. #define EMSTAT_PICO_MEASUREMENT_OFFSET 0x8000000 ///< Emstat measurement offset. // The below Emstat status values come from the MethodScript-v1_2-1.pdf. See page 10 table 4 for further information @@ -192,14 +194,14 @@ setFPGACPiProbeType( COND_CPI_SENSOR_PROBE_TYPE ); setFPGACPoProbeType( COND_CPO_SENSOR_PROBE_TYPE ); - initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR, MAX_CONDUCTIVITY_SENSOR_FAILURES, MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ); - initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD, COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_DG_CPI_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CPO_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CD1_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CD2_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); + initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR, MAX_CONDUCTIVITY_SENSOR_FAILURES, MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ); + initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_CLEAR_MS ); + initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_CLEAR_MS ); + initPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD, COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_CPI_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CPO_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CD1_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CD2_COND_SENSOR_INVALID_CHAR, COND_SENSORS_BAD_CHAR_TIME_OUT_MS, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); @@ -295,22 +297,31 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { - DG_OP_MODE_T opMode = getCurrentOperationMode(); - F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - BOOL isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); - BOOL isConductInWarningRange = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); + DG_OP_MODE_T opMode = getCurrentOperationMode(); + F32 conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + BOOL isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); + BOOL isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); switch( opMode ) { case DG_MODE_GENE: case DG_MODE_FILL: case DG_MODE_DRAI: - isConductTooLow = ( conductivity >= MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? FALSE: TRUE ); - isConductInWarningRange = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + if ( ( conductivity >= MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ) && ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE ) ) ) + { + isConductTooLow = FALSE; + } + // Per PRS 403 checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); + + if ( ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ) && ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) ) + { + isConductTooHigh = FALSE; + } + // Per PRS 404 - checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, isConductInWarningRange, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE, isConductTooHigh, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); break; case DG_MODE_INIT: @@ -322,7 +333,7 @@ if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) { // Per PRS 403 - checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, isConductInWarningRange, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); + checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH, isConductTooHigh, conductivity, MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ); // Per PRS 404 checkPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW, isConductTooLow, conductivity, MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ); } Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r4daa230ef3173ca71bab91c0c28457e6ac341797 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 4daa230ef3173ca71bab91c0c28457e6ac341797) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -54,7 +54,7 @@ #define DRP_CONTROL_MAX_ALLOWED_PPO_PSI 30.0F ///< Drain pump maximum allowed PPo pressure in psi. #define DRP_CONTROL_MAX_ALLOWED_PDR_PSI 40.0F ///< Drain pump maximum allowed PDr pressure in psi. #define DRP_CONTROL_PSI_TO_DAC_P_TERM 0.2F ///< Drain pump psi to DAC conversion. -#define DRP_CONTROL_FLOW_TO_DAC_P_TERM 0.5F ///< Drain pump flow (L/min) to DAC conversion. +#define DRP_CONTROL_FLOW_TO_DAC_P_TERM 100.0F ///< Drain pump flow (L/min) to DAC conversion. #define DRP_CONTROL_PRES_TO_MAX_THRESHOLD_PSI 1.0F ///< Drain pump pressure to maximum pressure threshold in psi. #define DRP_CONTROL_MIN_DAC_CHANGE 1 ///< Drain pump minimum DAC change @@ -66,7 +66,7 @@ #define TOGGLE_PERIOD_RESOLUTION_SECONDS 0.000005F ///< Toggle period to resolution in seconds. #define ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION 4.0F ///< Rotational to toggle period conversion coefficient. -#define DRAIN_PUMP_P_COEFFICIENT 0.5F ///< P term for drain pump delta pressure control. +#define DRAIN_PUMP_P_COEFFICIENT 100.0F //0.5F ///< P term for drain pump delta pressure control. #define DRAIN_PUMP_I_COEFFICIENT 1.0F ///< I term for drain pump delta pressure control. #define MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE 100 ///< Maximum allowed RPM out of range from target RPM in open loop. @@ -672,6 +672,12 @@ isDrainPumpControlInFlowMode = FALSE; } } + else if ( flowSubLPM > NEARLY_ZERO ) + { + // If measured flow if greater than the target flow, adjust the DAC to lower the flow rate + tempDACSet = (U32)( ( flowSubLPM * DRP_CONTROL_FLOW_TO_DAC_P_TERM ) + FLOAT_TO_INT_ROUNDUP_OFFSET ); + drainPumpDACSet -= ( tempDACSet > 0.0F ? tempDACSet : DRP_CONTROL_MIN_DAC_CHANGE ); + } else { // Get the status of the current pressure readings with respect to their maximum pressures @@ -695,14 +701,6 @@ tempDACSet = (U32)( ( fabs(maxPresPSI) * DRP_CONTROL_PSI_TO_DAC_P_TERM ) + FLOAT_TO_INT_ROUNDUP_OFFSET ); drainPumpDACSet += ( tempDACSet > 0.0F ? tempDACSet : DRP_CONTROL_MIN_DAC_CHANGE ); } - - if ( flowSubLPM > NEARLY_ZERO ) - { - // If measured flow if greater than the target flow, adjust the DAC to lower the flow rate - tempDACSet = (U32)( ( flowSubLPM * DRP_CONTROL_FLOW_TO_DAC_P_TERM ) + FLOAT_TO_INT_ROUNDUP_OFFSET ); - drainPumpDACSet -= ( tempDACSet > 0.0F ? tempDACSet : DRP_CONTROL_MIN_DAC_CHANGE ); - } - } // Check the DAC to make sure it is not out the min and max ranges of the drain pump @@ -777,7 +775,7 @@ drainPumpData.pumpDACSet = drainPumpDACSet; drainPumpData.drainPumpState = (U32)drainPumpState; drainPumpData.drainPumpRPM = getDrainPumpMeasuredRPM(); - drainPumpData.trgtOutletPrsr = targetDrainPumpOutletFlowLPM; + drainPumpData.trgtOutletFlowLPM = targetDrainPumpOutletFlowLPM; drainPumpData.drainPumpCurrentA = getDrainPumpMeasuredCurrentA(); drainPumpData.drainPumpDirection = getDrainPumpMeasuredDirection(); Index: firmware/App/Controllers/DrainPump.h =================================================================== diff -u -r4b9ae4e44d44ee6577fec4c8b75aa160fea04cc7 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision 4b9ae4e44d44ee6577fec4c8b75aa160fea04cc7) +++ firmware/App/Controllers/DrainPump.h (.../DrainPump.h) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -43,7 +43,7 @@ U32 pumpDACSet; ///< Drain pump DAC set value. U32 drainPumpState; ///< Drain pump state machine state. U32 drainPumpRPM; ///< Drain pump current RPM. - F32 trgtOutletPrsr; ///< Drain pump target outlet pressure. + F32 trgtOutletFlowLPM; ///< Drain pump target outlet flow in L/min. F32 drainPumpCurrentA; ///< Drain pump current in amps. U32 drainPumpDirection; ///< Drain pump direction. } DRAIN_PUMP_DATA_T; Index: firmware/App/Controllers/Pressures.c =================================================================== diff -u -r4daa230ef3173ca71bab91c0c28457e6ac341797 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Controllers/Pressures.c (.../Pressures.c) (revision 4daa230ef3173ca71bab91c0c28457e6ac341797) +++ firmware/App/Controllers/Pressures.c (.../Pressures.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -62,7 +62,8 @@ #define MAX_INLET_WATER_PRESSURE_WARNING_HIGH_PSIG 80.0F ///< Maximum allowed high pressure value in psig. #define MIN_INLET_WATER_PRESSURE_WARNING_HIGH_PSIG 78.0F ///< Minimum allowed high pressure value in psig. -#define INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for pressure out of range error. +#define INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Persistence period for pressure out of range error in milliseconds. +#define INLET_WATER_PRES_OUT_OF_RANGE_CLEAR_MS ( 1 * MS_PER_SECOND ) ///< Persistence period for pressure out of range clear in milliseconds. #define PRESSURE_OUT_OF_RANGE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Pressure out of range persistence period in milliseconds. #define PRESSURES_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the pressures data is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 10 ///< Data publish counter start count. @@ -150,12 +151,12 @@ msrdPressureSum[ i ] = 0; } - initPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_HIGH_RANGE, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE, INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_PRES_OUT_OF_RANGE_CLEAR_MS ); + initPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_HIGH_RANGE, INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_PRES_OUT_OF_RANGE_CLEAR_MS ); initPersistentAlarm( ALARM_ID_DG_PRESSURE_OUT_OF_RANGE, PRESSURE_OUT_OF_RANGE_TIMEOUT_MS, PRESSURE_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DG_BARO_PRESSURE_OUT_OF_RANGE, PRESSURE_OUT_OF_RANGE_TIMEOUT_MS, PRESSURE_OUT_OF_RANGE_TIMEOUT_MS ); - initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_HIGH, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ); - initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_LOW, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD, INLET_WATER_PRESSURE_PERSISTENCE_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_HIGH, INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_LOW, INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_PRES_OUT_OF_RANGE_TIMEOUT_MS ); } /*********************************************************************//** @@ -182,12 +183,21 @@ case DG_MODE_GENE: case DG_MODE_FILL: case DG_MODE_DRAI: - isPressureTooHigh = ( pressure <= MIN_INLET_WATER_PRESSURE_WARNING_HIGH_PSIG ? FALSE : TRUE ); - isPressureTooLow = ( pressure >= MIN_INLET_WATER_PRESSURE_WARNING_LOW_PSIG ? FALSE : TRUE ); - // Per PRS 841 - checkPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_HIGH_RANGE, isPressureTooHigh, pressure, MAX_INLET_WATER_PRESSURE_WARNING_HIGH_PSIG ); + if ( ( pressure >= MIN_INLET_WATER_PRESSURE_WARNING_LOW_PSIG ) && ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE ) ) ) + { + isPressureTooLow = FALSE; + } + // Per PRS 401 checkPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_LOW_RANGE, isPressureTooLow, pressure, MAX_INLET_WATER_PRESSURE_WARNING_LOW_PSIG ); + + if ( ( pressure <= MIN_INLET_WATER_PRESSURE_WARNING_HIGH_PSIG ) && ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_PRESSURE_IN_HIGH_RANGE ) ) ) + { + isPressureTooHigh = FALSE; + } + + // Per PRS 841 + checkPersistentAlarm( ALARM_ID_INLET_WATER_PRESSURE_IN_HIGH_RANGE, isPressureTooHigh, pressure, MAX_INLET_WATER_PRESSURE_WARNING_HIGH_PSIG ); break; case DG_MODE_INIT: Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r4daa230ef3173ca71bab91c0c28457e6ac341797 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 4daa230ef3173ca71bab91c0c28457e6ac341797) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -60,6 +60,7 @@ #define SHIFT_BITS_BY_2 2U ///< Shift bits by 2 to create a 4 for averaging 4 samples. #define SHIFT_BITS_BY_2_FOR_AVERAGING 2U ///< Shift the ADCs of the temperature sensors by 2 to average them. #define INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Inlet water temperature sensors timeout in milliseconds. +#define INLET_WATER_TEMP_OUT_OF_RANGE_CLEAR_MS ( 1 * MS_PER_SECOND ) ///< Inlet water temperature sensors out of range clear in milliseconds. #define MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE 24.0F ///< Low range minimum water input temperature. #define MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE 26.0F ///< Low range maximum water input temperature. @@ -323,8 +324,8 @@ tempSensors[ TEMPSENSORS_BAROMETRIC_TEMP_SENSOR ].maxAllowedTemp = NON_FLUID_PATH_TEMP_SENSORS_MAX_ALLOWED_DEGREE_C; // Persistent alarms for inlet water high/low temperature - initPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS ); - initPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_TEMP_OUT_OF_RANGE_CLEAR_MS ); + initPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_TEMP_OUT_OF_RANGE_CLEAR_MS ); initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_LOW, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS, INLET_WATER_TEMP_OUT_OF_RANGE_TIMEOUT_MS ); @@ -434,10 +435,19 @@ case DG_MODE_GENE: case DG_MODE_FILL: case DG_MODE_DRAI: - isWaterTempInHighRange = ( temperature <= MIN_WATER_TEMPERATURE_WARNING_HIGH_RANGE ? FALSE : TRUE ); - isWaterTempInLowRange = ( temperature >= MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ? FALSE : TRUE ); + if ( ( temperature <= MIN_WATER_TEMPERATURE_WARNING_HIGH_RANGE ) && ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE ) ) ) + { + isWaterTempInHighRange = FALSE; + } + // Per PRS 406 checkPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_HIGH_RANGE, isWaterTempInHighRange, temperature, MAX_WATER_TEMPERATURE_WARNING_HIGH_RANGE ); + + if ( ( temperature >= MAX_WATER_TEMPERATURE_WARNING_LOW_RANGE ) && ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE ) ) ) + { + isWaterTempInLowRange = FALSE; + } + // Per PRS 405 checkPersistentAlarm( ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE, isWaterTempInLowRange, temperature, MIN_WATER_TEMPERATURE_WARNING_LOW_RANGE ); break; 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() ); } } Index: firmware/App/Modes/ModeChemicalDisinfectFlush.c =================================================================== diff -u -r81769c6bea6ed32d70698fb03ad5823de1814b27 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Modes/ModeChemicalDisinfectFlush.c (.../ModeChemicalDisinfectFlush.c) (revision 81769c6bea6ed32d70698fb03ad5823de1814b27) +++ firmware/App/Modes/ModeChemicalDisinfectFlush.c (.../ModeChemicalDisinfectFlush.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -55,17 +55,8 @@ #define RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. -// Inlet water checks defines -#define MIN_INLET_TEMPERATURE_C 24.0F ///< Minimum water inlet temperature in C. -#define MAX_INLET_TEMPERATURE_C 37.0F ///< Maximum water inlet temperature in C. -#define MAX_INLET_CONDUCTIVITY_US_PER_CM 2000.0F ///< Maximum water inlet conductivity in us/cm -#define MIN_INLET_CONDUCTIVITY_US_PER_CM 100.0F ///< Minimum water inlet conductivity in us/cm -#define MIN_INLET_PRESSURE_PSI 10.0F ///< Minimum water inlet pressure in psi. -#define MAX_INLET_PRESSURE_PSI 80.0F ///< Maximum water inlet pressure in psi. - // Flush drain path state defines #define FLUSH_DRAIN_WAIT_TIME_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. -#define MAX_ALLOWED_FLUSH_DRAIN_PERIODS 2 ///< Number of flush drain periods to wait for inlet water to come in range // Flush circulation path state defines #define RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM 0.8F ///< RO pump target flow rate during flush/fill in L/min. @@ -87,11 +78,14 @@ #define RSRVRS_FILL_TO_FULL_STABLE_TASK_INT ( ( 2 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in task intervals. // Flush disinfectant lines and flush UF defines -#define CONC_PUMP_CP1_FLUSH_SPEED_ML_PER_MIN 40.0 ///< Concentrate pump CP1 speed for flush -#define CONC_PUMP_CP2_FLUSH_SPEED_ML_PER_MIN 40.8 ///< Concentrate pump CP2 speed for flush +#define CONC_PUMP_CP1_FLUSH_SPEED_ML_PER_MIN -40.0F ///< Concentrate pump CP1 speed for flush +#define CONC_PUMP_CP2_FLUSH_SPEED_ML_PER_MIN 40.8F ///< Concentrate pump CP2 speed for flush #define FLUSH_DISINFECTANT_LINE_WAIT_TIME_MS ( 2.5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time to flush disinfectant line in milliseconds. #define FLUSH_UF_WAIT_TIME_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time to flush UF in milliseconds. +// Sample flush R1 to R2 drain R2 defines +#define SAMPLE_FLUSH_WAIT_TIME_MS ( 2.5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Time to wait for sampling flush R1 to R2 drain R2 in milliseconds. + /// Cancellation paths typedef enum Cancellation_modes { @@ -104,34 +98,30 @@ /// Non-volatile write structure typedef struct { - BOOL hasDisFlushStatusBeenWrittenToNV; ///< Boolean flag to indicate whether the disinfect flush status been written to NV or not. - BOOL hasDisFlushCompleteDateBeenWrittenToNV; ///< Boolean flag to indicate whether the disinfect flush complete date been written to NV or not. -} DISINFECT_FLUSH_NV_OPS_T; + BOOL hasDisStatusBeenWrittenToNV; ///< Boolean flag to indicate whether the disinfect status been written to NV or not. +} DISINFECT_NV_OPS_T; // ********** private data ********** -static DG_CHEM_DISINFECT_FLUSH_STATE_T chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_START; ///< Currently active chemical disinfect flush state. -static DG_CHEM_DISINFECT_FLUSH_STATE_T prevChemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_START; ///< Previous active chemical disinfect flush state before alarm. -static DG_CHEM_DISINFECT_FLUSH_UI_STATE_T chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_NOT_RUNNING; ///< Currently active chemical disinfect flush UI state. -static U32 overallChemDisinfectFlushTimer = 0; ///< Chemical disinfect flush cycle total timer. -static U32 stateTimer = 0; ///< Chemical disinfect flush state timer to be used in different states. -static U32 stateTrialCounter = 0; ///< Chemical disinfect flush state trial counter to be used for retries in different states. -static BOOL haveInletWaterChecksPassed = TRUE; ///< Inlet water pressure, temperature, and pressure in range flag -static BOOL isThisLastDrain = FALSE; /// Boolean flag to check whether draining R1 and R2 is at the end of the chemical disinfect flush cycle or in the beginning. -static DG_RESERVOIR_STATUS_T rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 1 status. -static DG_RESERVOIR_STATUS_T rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 2 status. -static U32 waitTimer = 0; ///< Wait timer for reservoir flushing. -static U32 drainTimer = 0; ///< Timer for reservoir draining during flush states -static U32 dataPublishCounter = 0; ///< Chemical disinfect flush data publish counter. -static CANCELLATION_MODE_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. -static U32 rsrvrFillToFullStableTimerCounter = 0; ///< Task interval counter for determining if reservoir is full +static DG_CHEM_DISINFECT_FLUSH_STATE_T chemDisinfectFlushState; ///< Currently active chemical disinfect flush state. +static DG_CHEM_DISINFECT_FLUSH_STATE_T prevChemDisinfectFlushState; ///< Previous active chemical disinfect flush state before alarm. +static DG_CHEM_DISINFECT_FLUSH_UI_STATE_T chemDisinfectFlushUIState; ///< Currently active chemical disinfect flush UI state. +static U32 overallChemDisinfectFlushTimer; ///< Chemical disinfect flush cycle total timer. +static U32 stateTimer; ///< Chemical disinfect flush state timer to be used in different states. +static BOOL isThisLastDrain; ///< Boolean flag to check whether draining R1 and R2 is at the end of the chemical disinfect flush cycle or in the beginning. +static DG_RESERVOIR_STATUS_T rsrvr1Status; ///< Reservoir 1 status. +static DG_RESERVOIR_STATUS_T rsrvr2Status; ///< Reservoir 2 status. +static U32 waitTimer; ///< Wait timer for reservoir flushing. +static U32 drainTimer; ///< Timer for reservoir draining during flush states +static U32 dataPublishCounter; ///< Chemical disinfect flush data publish counter. +static CANCELLATION_MODE_T cancellationMode; ///< Cancellation mode. +static U32 rsrvrFillToFullStableTimerCounter; ///< Task interval counter for determining if reservoir is full static ALARM_ID_T alarmDetectedPendingTrigger; ///< Chemical disinfect flush alarm to raise. static U32 numberOfPostDisinfectRinses; ///< Number of times to rinse the fluid path after chemical disinfect flush. -static DISINFECT_FLUSH_NV_OPS_T disinfectFlushNVOps; ///< Disinfect flush non-volatile memory operations. +static DISINFECT_NV_OPS_T disinfectNVOps; ///< Disinfect non-volatile memory operations. // ********** private function prototypes ********** -//static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushRemoveAcidBottleFromUIState( void ); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushStartState( void ); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushDrainR1State( void ); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushDrainR2State( void ); @@ -140,6 +130,7 @@ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushFlushUFState( void ); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushFlushR2ToR1DrainR1State( void ); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushFlushR1ToR2DrainR2State( void ); +static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushSampleFlushR1ToR2DrainR2State( void ); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCancelModeBasicPathState(void); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCancelModeWaterPathState(void); static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCompleteState( void ); @@ -149,7 +140,7 @@ static DG_RESERVOIR_STATUS_T getRsrvrFillToFullStatus( DG_RESERVOIR_ID_T r, U32 timeout ); static void publishChemicalDisinfectFlushData( void ); static void monitorModeChemicalDisinfectFlush( void ); -static void writeDisinfectFlushDataToNV( void ); +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ); /*********************************************************************//** * @brief @@ -167,21 +158,22 @@ *************************************************************************/ void initChemicalDisinfectFlushMode( void ) { - chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_START; - prevChemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_START; - stateTimer = 0; - isThisLastDrain = FALSE; - stateTrialCounter = 0; - haveInletWaterChecksPassed = TRUE; - rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; - rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - overallChemDisinfectFlushTimer = 0; - cancellationMode = CANCELLATION_MODE_NONE; - rsrvrFillToFullStableTimerCounter = 0; - numberOfPostDisinfectRinses = 0; - chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_NOT_RUNNING; - disinfectFlushNVOps.hasDisFlushCompleteDateBeenWrittenToNV = FALSE; - disinfectFlushNVOps.hasDisFlushStatusBeenWrittenToNV = FALSE; + chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_START; + prevChemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_START; + stateTimer = 0; + isThisLastDrain = FALSE; + rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; + rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; + overallChemDisinfectFlushTimer = 0; + cancellationMode = CANCELLATION_MODE_NONE; + rsrvrFillToFullStableTimerCounter = 0; + numberOfPostDisinfectRinses = 0; + alarmDetectedPendingTrigger = ALARM_ID_NO_ALARM; + chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_NOT_RUNNING; + waitTimer = 0; + drainTimer = 0; + dataPublishCounter = 0; + disinfectNVOps.hasDisStatusBeenWrittenToNV = FALSE; } /*********************************************************************//** @@ -213,6 +205,17 @@ *************************************************************************/ U32 execChemicalDisinfectFlushMode( void ) { + // The inlet pressure shall be checked all the time as long as VPi is open + checkInletWaterPressure(); + + if ( chemDisinfectFlushState != DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_DRAIN ) + { + // Do not check on the inlet water temperature and conductivity until the inlet filters have been flushed + // The initial states are drain reservoirs but in those states VPi is closed so these alarms are not checked + checkInletWaterTemperature(); + checkInletWaterConductivity(); + } + monitorModeChemicalDisinfectFlush(); switch ( chemDisinfectFlushState ) @@ -249,6 +252,10 @@ chemDisinfectFlushState = handleChemicalDisinfectFlushFlushR1ToR2DrainR2State(); break; + case DG_CHEM_DISINFECT_FLUSH_STATE_SAMPLE_FLUSH_R1_TO_R2_DRAIN_R2: + chemDisinfectFlushState = handleChemicalDisinfectFlushSampleFlushR1ToR2DrainR2State(); + break; + case DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_BASIC_PATH: chemDisinfectFlushState = handleChemicalDisinfectFlushCancelModeBasicPathState(); break; @@ -324,11 +331,7 @@ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushStartState( void ) { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R1; - - // Set the chemical disinfect flush state that is published on the UI chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_FLUSH_AFTER_DISINFECT; - - // Start overall chemical disinfect timer overallChemDisinfectFlushTimer = getMSTimerCount(); // Close VPi to prevent wasting water @@ -338,8 +341,8 @@ setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); setValveState( VRD1, VALVE_STATE_OPEN ); setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - stateTimer = getMSTimerCount(); + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + stateTimer = getMSTimerCount(); return state; } @@ -363,22 +366,23 @@ rsrvr1Status = getRsrvrDrainStatus( DG_RESERVOIR_1, DRAIN_WEIGHT_UNCHANGE_TIMEOUT, RSRVRS_INITIAL_FINAL_DRAIN_TIME_OUT_MS ); } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) - { // Done with draining R1 + { + // Done with draining R1 if ( FALSE == isThisLastDrain ) { tareLoadCell( LOAD_CELL_RESERVOIR_1_PRIMARY ); tareLoadCell( LOAD_CELL_RESERVOIR_1_BACKUP ); } setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_OPEN ); - rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R2; - stateTimer = getMSTimerCount(); + rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; + state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R2; + stateTimer = getMSTimerCount(); } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevChemDisinfectFlushState = state; - state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -405,9 +409,10 @@ else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { signalDrainPumpHardStop(); // Done with draining + if ( TRUE == isThisLastDrain ) { - state = DG_CHEM_DISINFECT_FLUSH_STATE_COMPLETE; + state = DG_CHEM_DISINFECT_FLUSH_STATE_COMPLETE; } else { @@ -419,15 +424,14 @@ setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); turnOnUVReactor( INLET_UV_REACTOR ); - stateTrialCounter = 0; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_DRAIN; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_DRAIN; } } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { prevChemDisinfectFlushState = state; - state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_BASIC_PATH; + state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; } return state; @@ -452,34 +456,18 @@ // Check if flush time has elapsed if ( TRUE == didTimeout( stateTimer, FLUSH_DRAIN_WAIT_TIME_MS ) ) { - if (haveInletWaterChecksPassed) - { - // set pumps and valves for next state, flush disinfectant line - setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); - setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - // Set the acid concentrate pump to run at a constant speed during flushing in reverse - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, -1.0 * CONC_PUMP_CP1_FLUSH_SPEED_ML_PER_MIN ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); - // Turn on the bicarb line pump with forward direction, to flush the line that contains acid from the disinfect - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONC_PUMP_CP2_FLUSH_SPEED_ML_PER_MIN ); - requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); - turnOnUVReactor( OUTLET_UV_REACTOR ); - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_DISINFECTANT_LINE; - } - else - { // If the number of failures have not exceeded the limit, try again. - if ( ++stateTrialCounter < MAX_ALLOWED_FLUSH_DRAIN_PERIODS ) - { - stateTimer = getMSTimerCount(); - } - else - { // Couldn't get a good water sample after a couple of trials and the disinfect flush cycle failed - alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE; //TODO: ALARM_ID_DG_NEW_WAT; - prevChemDisinfectFlushState = state; - state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_BASIC_PATH; - } - } + // set pumps and valves for next state, flush disinfectant line + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setROPumpTargetFlowRateLPM( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); + // Set the acid concentrate pump to run at a constant speed during flushing in reverse + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONC_PUMP_CP1_FLUSH_SPEED_ML_PER_MIN ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); + // Turn on the bicarb line pump with forward direction, to flush the line that contains acid from the disinfect + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONC_PUMP_CP2_FLUSH_SPEED_ML_PER_MIN ); + requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); + turnOnUVReactor( OUTLET_UV_REACTOR ); + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_DISINFECTANT_LINE; } return state; @@ -537,13 +525,13 @@ setValveState( VRD1, VALVE_STATE_OPEN ); setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; - drainTimer = getMSTimerCount(); - numberOfPostDisinfectRinses = 0; + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; + drainTimer = getMSTimerCount(); + numberOfPostDisinfectRinses = 0; rsrvrFillToFullStableTimerCounter = 0; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R2_TO_R1_DRAIN_R1; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R2_TO_R1_DRAIN_R1; } return state; @@ -569,7 +557,8 @@ // Check whether draining R1 has timed out if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr1Status ) - { // Do not use the standard drain status function because we are filling and draining at the same time + { + // Do not use the standard drain status function because we are filling and draining at the same time if ( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) < RSRVRS_DRAIN_TARGET_VOLUME_ML ) { rsrvr1Status = DG_RESERVOIR_REACHED_TARGET; @@ -600,7 +589,7 @@ } // Overflow R2 to R1 for an additional period - if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( TRUE == didTimeout( waitTimer, FLUSH_ADDITIONAL_TIME_MS ) ) ) + if ( ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) && ( TRUE == didTimeout( waitTimer, FLUSH_ADDITIONAL_TIME_MS ) ) ) { // Set the valves to flush R1 to R2 and drain R2 setValveState( VRD2, VALVE_STATE_OPEN ); @@ -639,7 +628,8 @@ // Check whether draining R2 has timed out if ( DG_RESERVOIR_ABOVE_TARGET == rsrvr2Status ) - { // Do not use the standard drain status function because we are filling and draining at the same time + { + // Do not use the standard drain status function because we are filling and draining at the same time if ( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) < RSRVRS_DRAIN_TARGET_VOLUME_ML ) { rsrvr2Status = DG_RESERVOIR_REACHED_TARGET; @@ -688,31 +678,21 @@ state = DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R2_TO_R1_DRAIN_R1; } else - { // number of rinse cycles complete + { + // number of rinse cycles complete // Set the valves to drain R1 - setValveState( VPI, VALVE_STATE_CLOSED ); - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VPI, VALVE_STATE_OPEN ); + setValveState( VRF, VALVE_STATE_R1_C_TO_NC ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R2_C_TO_NC ); setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); - setValveState( VRD1, VALVE_STATE_OPEN ); - setValveState( VRD2, VALVE_STATE_CLOSED ); + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_OPEN ); setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM ); - // Because this is the second reservoir drain in this mode, the drain parameters must be reset - initDrainParameters( DG_RESERVOIR_1 ); - initDrainParameters( DG_RESERVOIR_2 ); - rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - // Turn off CP1 and CP2 and ROP - signalROPumpHardStop(); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); - //Turn off UV reactors - turnOffUVReactor( INLET_UV_REACTOR ); - turnOffUVReactor( OUTLET_UV_REACTOR ); - isThisLastDrain = TRUE; - stateTimer = getMSTimerCount(); - state = DG_CHEM_DISINFECT_FLUSH_STATE_DRAIN_R1; + stateTimer = getMSTimerCount(); + state = DG_CHEM_DISINFECT_FLUSH_STATE_SAMPLE_FLUSH_R1_TO_R2_DRAIN_R2; } } @@ -721,6 +701,27 @@ /*********************************************************************//** * @brief + * The handleChemicalDisinfectFlushSampleFlushR1ToR2DrainR2State function + * handles the chemical disinfect flush sample flush R1 to R2 and drain R2 + * state. + * @details Inputs: stateTimer, TODO fill up + * @details Outputs: TODO fill up + * @return next state of the chemical disinfect flush state machine + *************************************************************************/ +static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushSampleFlushR1ToR2DrainR2State( void ) +{ + DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_SAMPLE_FLUSH_R1_TO_R2_DRAIN_R2; + + if ( TRUE == didTimeout( stateTimer, SAMPLE_FLUSH_WAIT_TIME_MS ) ) + { + + } + + return state; +} + +/*********************************************************************//** + * @brief * The handleChemicalDisinfectFlushCancelModeBasicPathState function handles the * chemical disinfect flush cancel mode basic path state. The state sets the state * to complete and raises an alarm. @@ -731,13 +732,9 @@ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCancelModeBasicPathState( void ) { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_BASIC_PATH; + chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_CANCEL_FLUSH; + cancellationMode = CANCELLATION_MODE_BASIC; - // Set the chemical disinfect flush that is published on the UI - chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_CANCEL_FLUSH; - - // Set the cancellation mode - cancellationMode = CANCELLATION_MODE_BASIC; - failChemicalDisinfectFlush(); return state; @@ -755,10 +752,8 @@ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCancelModeWaterPathState( void ) { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; + chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_CANCEL_FLUSH; - // Set the chemical disinfect flush state that is published on the UI - chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_CANCEL_FLUSH; - if ( CANCELLATION_MODE_NONE == cancellationMode ) { // Stop all the actuators first then decide who should run next @@ -829,12 +824,10 @@ static DG_CHEM_DISINFECT_FLUSH_STATE_T handleChemicalDisinfectFlushCompleteState( void ) { DG_CHEM_DISINFECT_FLUSH_STATE_T state = DG_CHEM_DISINFECT_FLUSH_STATE_COMPLETE; + chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_COMPLETE; - // Set the chemical disinfect flush state that is published on the UI - chemDisinfectFlushUIState = CHEM_DISINFECT_FLUSH_UI_STATE_COMPLETE; + writeDisinfectDataToNV( USAGE_INFO_CHEM_FLUSH ); - writeDisinfectFlushDataToNV(); //TODO: is this needed? - stopChemicalDisinfectFlush(); return state; @@ -869,20 +862,20 @@ static DG_RESERVOIR_STATUS_T getRsrvrDrainStatus( DG_RESERVOIR_ID_T r, U32 drainSteadyStateTimeout, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_ABOVE_TARGET; - BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); + BOOL isDrainComplete = hasTargetDrainVolumeBeenReached( r, drainSteadyStateTimeout ); if ( TRUE == isDrainComplete ) { // Set the state timer in case it needs to be used for another timeout check - stateTimer = getMSTimerCount(); - status = DG_RESERVOIR_REACHED_TARGET; + stateTimer = getMSTimerCount(); + status = DG_RESERVOIR_REACHED_TARGET; } else if ( TRUE == didTimeout( stateTimer, timeout ) ) { // Failed to drain on time. Update the previous chemical disinfect state - prevChemDisinfectFlushState = chemDisinfectFlushState; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + prevChemDisinfectFlushState = chemDisinfectFlushState; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_DRAIN_TIMEOUT; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } return status; @@ -902,17 +895,17 @@ static DG_RESERVOIR_STATUS_T getRsrvrFillToFullStatus( DG_RESERVOIR_ID_T r, U32 timeout ) { DG_RESERVOIR_STATUS_T status = DG_RESERVOIR_BELOW_TARGET; - F32 currentVolume = 0.0; - F32 filteredVolume = 0.0; + F32 currentVolume = 0.0F; + F32 filteredVolume = 0.0F; if ( DG_RESERVOIR_1 == r ) { - currentVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + currentVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); filteredVolume = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); } else if ( DG_RESERVOIR_2 == r ) { - currentVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + currentVolume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); filteredVolume = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); } else @@ -934,9 +927,9 @@ else if ( TRUE == didTimeout( stateTimer, timeout ) ) { // Failed to fill on time. Update the previous chemical disinfect state and transition to basic cancellation - prevChemDisinfectFlushState = chemDisinfectFlushState; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; - status = DG_RESERVOIR_NOT_REACHED_TARGET; + prevChemDisinfectFlushState = chemDisinfectFlushState; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_FILL_TIMEOUT; + status = DG_RESERVOIR_NOT_REACHED_TARGET; } else { @@ -991,9 +984,7 @@ *************************************************************************/ static void monitorModeChemicalDisinfectFlush( void ) { - BOOL hasConductivityFailed = TRUE; - BOOL hasInletPressureFailed = TRUE; - BOOL hasInletTemperatureFailed = TRUE; + BOOL areInletWaterAlarmsActive = FALSE; #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_CAPS_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) @@ -1006,68 +997,41 @@ // will not be raising the alarm at end of the cancel water path. The recoverable alarm is raised here in this function U32 ConcCap = (U32)getSwitchStatus( CONCENTRATE_CAP ); U32 DialysateCap = (U32)getSwitchStatus( DIALYSATE_CAP ); - prevChemDisinfectFlushState = chemDisinfectFlushState; + prevChemDisinfectFlushState = chemDisinfectFlushState; chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; alarmDetectedPendingTrigger = ALARM_ID_DG_DIALYSATE_OR_CONC_CAP_NOT_IN_PROPER_POSITION; } } - // In some states, check inlet temperature, inlet pressure, and inlet conductivity. - haveInletWaterChecksPassed= TRUE; + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_HIGH ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_TEMP_TOO_LOW ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_HIGH ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_PRESSURE_TOO_LOW ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_HIGH ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_CLEANING_MODE_INLET_WATER_COND_TOO_LOW ); + areInletWaterAlarmsActive |= isAlarmActive( ALARM_ID_DG_DIALYSATE_TEMPERATURE_SENSORS_OUT_OF_RANGE ); - hasConductivityFailed = ( ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) > MAX_INLET_CONDUCTIVITY_US_PER_CM ) || - ( getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ) < MIN_INLET_CONDUCTIVITY_US_PER_CM ) ); - hasInletPressureFailed = ( ( getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ) < MIN_INLET_PRESSURE_PSI ) || - ( getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_INLET ) > MAX_INLET_PRESSURE_PSI ) ); - hasInletTemperatureFailed = ( ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) < MIN_INLET_TEMPERATURE_C ) || - ( getTemperatureValue( TEMPSENSORS_INLET_PRIMARY_HEATER ) > MAX_INLET_TEMPERATURE_C ) ); -#ifndef _RELEASE_ - if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_DISABLE_WATER_QUALITY_CHECK ) ) + if ( ( TRUE == areInletWaterAlarmsActive ) ) { - hasConductivityFailed = FALSE; + prevChemDisinfectFlushState = chemDisinfectFlushState; + chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; } -#endif - if ( hasInletTemperatureFailed || hasConductivityFailed || hasInletPressureFailed ) - { // Inlet check failed, alarm unless in the start, drain, or flush drain states - haveInletWaterChecksPassed= FALSE; // set flag for flush drain state - switch( chemDisinfectFlushState ) - { - case DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_DISINFECTANT_LINE: - case DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_UF: - case DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R2_TO_R1_DRAIN_R1: - case DG_CHEM_DISINFECT_FLUSH_STATE_FLUSH_R1_TO_R2_DRAIN_R2: - prevChemDisinfectFlushState = chemDisinfectFlushState; - alarmDetectedPendingTrigger = ALARM_ID_INLET_WATER_TEMPERATURE_IN_LOW_RANGE; //TODO: ALARM_ID_NEW_WAT; - chemDisinfectFlushState = DG_CHEM_DISINFECT_FLUSH_STATE_CANCEL_WATER_PATH; - break; - - default: - // The inlet water checks do not apply for other states - break; - } - } } /*********************************************************************//** * @brief * The writeDisinfectDataToNV function writes the disinfect flush data to the * non-volatile memory. - * @details Inputs: disinfectFlushNVOps + * @details Inputs: disFlushNVOps * @details Outputs: disinfectFlushNVOps * @return: none *************************************************************************/ -static void writeDisinfectFlushDataToNV( void ) +static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ) { - // TODO update in the next branch - /*if ( FALSE == disinfectFlushNVOps.hasDisFlushCompleteDateBeenWrittenToNV ) + if ( FALSE == disinfectNVOps.hasDisStatusBeenWrittenToNV ) { - disinfectFlushNVOps.hasDisFlushCompleteDateBeenWrittenToNV = setDisinfectStatus( TRUE ); + disinfectNVOps.hasDisStatusBeenWrittenToNV = setLastDisinfectDate( info, getRTCTimestamp() ); } - - if ( FALSE == disinfectFlushNVOps.hasDisFlushStatusBeenWrittenToNV ) - { - disinfectFlushNVOps.hasDisFlushStatusBeenWrittenToNV = setLastDisinfectDate( USAGE_INFO_CHEMICAL_DISINFECT, getRTCTimestamp() ); - }*/ } /**@}*/ Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -r4a1a7453b6c1bc707bcf20e1b2df02f3980c729c -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 4a1a7453b6c1bc707bcf20e1b2df02f3980c729c) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -963,12 +963,6 @@ return status; } -SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, avgCPo, MAX_CPO_CONDUCTIVITY_ALLOW ); -} -if ( avgRR > MAX_RO_REJECTION_RATIO_ALLOW ) -{ -// Fault alarm per PRS 483 -SET_ALARM_WITH_2_F32_DATA( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, avgRR, MAX_RO_REJECTION_RATIO_ALLOW ); /*********************************************************************//** * @brief @@ -1235,7 +1229,7 @@ { integratedVolumeML.ovData = value; integratedVolumeML.override = OVERRIDE_KEY; - result = TRUE; + result = TRUE; } return result; @@ -1257,7 +1251,7 @@ { integratedVolumeML.override = OVERRIDE_RESET; integratedVolumeML.ovData = integratedVolumeML.ovInitData; - result = TRUE; + result = TRUE; } return result; Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r4daa230ef3173ca71bab91c0c28457e6ac341797 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 4daa230ef3173ca71bab91c0c28457e6ac341797) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -80,7 +80,7 @@ // Fill and heat water #define HEAT_DISINFECT_TARGET_TEMPERATURE_C 82.0F ///< Heat disinfect target water temperature in C. -#define HEAT_DISINFECT_START_TEMPERATURE_C 35.0F //81.0F ///< Heat disinfect minimum acceptable temperature in C. +#define HEAT_DISINFECT_START_TEMPERATURE_C 81.0F ///< Heat disinfect minimum acceptable temperature in C. // R1 to R2 & R2 to R1 heat disinfect circulation #define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.3F ///< Heat disinfect target RO flow rate in L/min. @@ -93,7 +93,8 @@ #define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. #define HEAT_DISINFECT_MAX_TEMP_GRADIENT_C 15.0F ///< Heat disinfect maximum allowed temperature gradient in between hottest and coldest sensors. #define HEAT_DISINFECT_TEMP_GRAD_OUT_RANGE_TIME_MS ( 0.16 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect temperature gradient out of range timeout in milliseconds. -#define HEAT_DISINFECT_TARGET_RO_PUMP_DC 0.4F ///< Heat disinfect target RO pump duty cycle +#define HEAT_DISINFECT_TARGET_RO_PUMP_DC 0.4F ///< Heat disinfect target RO pump duty cycle. +#define HEAT_DISINFECT_REF_RSRVR_TIMEOUT_MS ( 5 * MS_PER_SECOND ) ///< Heat disinfect getting reference reservoirs value timeout in milliseconds. // Mix drain R1 and R2 #define RSRVRS_MIX_DRAIN_TIMEOUT_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 mix drain timeout in ms. @@ -142,8 +143,8 @@ static U32 concentratePumpsPrimeTimer; ///< Concentrate pumps prime timer. static DG_RESERVOIR_STATUS_T rsrvr1Status; ///< Reservoir 1 status. static DG_RESERVOIR_STATUS_T rsrvr2Status; ///< Reservoir 2 status. -static F32 R1HeatDisinfectVol; ///< Reservoir 1 full volume during heat disinfect. -static F32 R2HeatDisinfectVol; ///< Reservoir 2 full volume during heat disinfect. +static F32 rsrvr1RefVolML; ///< Reservoir 1 reference volume in heat disinfect in milliliters. +static F32 rsrvr2RefVolML; ///< Reservoir 2 reference volume in heat disinfect in milliliters. static U32 heatDisinfectTimer; ///< Heat disinfect timer. static BOOL isPartialDisinfectInProgress; ///< Heat disinfect partial complete/in progess flag. static U32 rsrvrsVolMonitorTimer; ///< Reservoir 1 & 2 volume monitor timers during heat disinfect. @@ -195,7 +196,7 @@ * @details Inputs: none * @details Outputs: heatDisinfectState, stateTimer, * stateTrialCounter, areTempSensorsInRange, rsrvr1Status, rsrvr2Status, - * R1HeatDisinfectVol, R2HeatDisinfectVol, overallHeatDisinfectTimer, + * rsrvr1RefVolML, rsrvr2RefVolML, overallHeatDisinfectTimer, * cancellationMode, rsrvrFillStableTimeCounter, prevHeatDisinfectState * isPartialDisinfectInProgress, isDrainPumpOnInMixDrain, heatDisinfectTimer * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime @@ -214,8 +215,8 @@ areTempSensorsInRange = FALSE; rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; - R1HeatDisinfectVol = 0.0F; - R2HeatDisinfectVol = 0.0F; + rsrvr1RefVolML = 0.0F; + rsrvr2RefVolML = 0.0F; overallHeatDisinfectTimer = 0; cancellationMode = CANCELLATION_MODE_NONE; rsrvrFillStableTimeCounter = 0; @@ -926,10 +927,8 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillWithWaterState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER; - // Set the heat disinfect UI state - heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER; - // First reservoir 1 must be full if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { @@ -958,11 +957,6 @@ setHeaterTargetTemperature( DG_TRIMMER_HEATER, HEAT_DISINFECT_TARGET_TEMPERATURE_C ); startHeater( DG_TRIMMER_HEATER ); - // Get the current volumes of R1 & R2. These values will be used to make sure the reservoirs' - // volume does not change more than a certain amount during the actual heat disinfect cycle - R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); - R2HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - stateTimer = getMSTimerCount(); rsrvrsVolMonitorTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2; @@ -1004,6 +998,17 @@ setROPumpTargetDutyCycle( HEAT_DISINFECT_TARGET_RO_PUMP_DC ); } + if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_REF_RSRVR_TIMEOUT_MS ) ) + { + if ( ( rsrvr1RefVolML < NEARLY_ZERO ) && ( rsrvr2RefVolML < NEARLY_ZERO ) ) + { + // Get the current volumes of R1 & R2. These values will be used to make sure the reservoirs' + // volume does not change more than a certain amount during the actual heat disinfect cycle + rsrvr1RefVolML = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + rsrvr2RefVolML = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + } + } + switch ( status ) { case HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT: @@ -1037,6 +1042,8 @@ rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; stateTimer = getMSTimerCount(); + rsrvr1RefVolML = 0.0F; + rsrvr2RefVolML = 0.0F; // Reset the timer for the next disinfect state tempGradOutOfRangeTimer = 0; state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; @@ -1067,10 +1074,8 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectFillR2WithHotWaterState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_TRANSITION_HOT_WATER; - // Set the heat disinfect UI state - heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_TRANSITION_HOT_WATER; - // First reservoir 1 must be partially full if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { @@ -1082,29 +1087,26 @@ if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) { - // Get the current volumes to be monitored during R2 to R1 heat disinfect state - R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); - R2HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - // Set the drain pump to control mode setDrainPumpTargetOutletFlowLPM( HEAT_DISINFECT_TARGET_RO_FLOW_LPM ); // Start the trimmer heater since we are recirculating water and there is flow in the shunt line setHeaterTargetTemperature( DG_TRIMMER_HEATER, HEAT_DISINFECT_TARGET_TEMPERATURE_C ); startHeater( DG_TRIMMER_HEATER ); - state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } } else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevHeatDisinfectState = state; - state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } return state; @@ -1127,6 +1129,17 @@ HEAT_DISINFECT_STATUS_T status = getHeatDisinfectStatus(); heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2; + if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_REF_RSRVR_TIMEOUT_MS ) ) + { + if ( ( rsrvr1RefVolML < NEARLY_ZERO ) && ( rsrvr2RefVolML < NEARLY_ZERO ) ) + { + // Get the current volumes of R1 & R2. These values will be used to make sure the reservoirs' + // volume does not change more than a certain amount during the actual heat disinfect cycle + rsrvr1RefVolML = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + rsrvr2RefVolML = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); + } + } + switch ( status ) { case HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT: @@ -1428,10 +1441,8 @@ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCompleteState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COMPLETE; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COMPLETE; - // Set the heat disinfect UI state - heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COMPLETE; - requestNewOperationMode( DG_MODE_HCOL ); return state; @@ -1599,8 +1610,8 @@ F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT ); F32 loadCellA1 = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); F32 loadCellB1 = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); - BOOL isR1OutOfRange = ( fabs( loadCellA1 - R1HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML ? TRUE : FALSE ); - BOOL isR2OutOfRange = ( fabs( loadCellB1 - R2HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML ? TRUE : FALSE ); + BOOL isR1OutOfRange = ( fabs( loadCellA1 - rsrvr1RefVolML ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML ? TRUE : FALSE ); + BOOL isR2OutOfRange = ( fabs( loadCellB1 - rsrvr2RefVolML ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML ? TRUE : FALSE ); BOOL isGradientOutOfRange = ( fabs( TPoTemp - ThdTemp ) > HEAT_DISINFECT_MAX_TEMP_GRADIENT_C ? TRUE : FALSE ); // Perform check if no pending alarm @@ -1624,22 +1635,25 @@ // Perform check if no pending alarm if ( ALARM_ID_NO_ALARM == alarmDetectedPendingTrigger ) { - // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume - if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) + if ( ( rsrvr1RefVolML > NEARLY_ZERO ) && ( rsrvr2RefVolML > NEARLY_ZERO ) ) { - // If the leak is the first time after a while, set the flag and start the timer - if ( FALSE == areRsrvrsLeaking ) + // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume + if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) { - areRsrvrsLeaking = TRUE; - rsrvrsVolMonitorTimer = getMSTimerCount(); + // If the leak is the first time after a while, set the flag and start the timer + if ( FALSE == areRsrvrsLeaking ) + { + areRsrvrsLeaking = TRUE; + rsrvrsVolMonitorTimer = getMSTimerCount(); + } + // If the volume is out of range and it has timed out, exit + else if ( TRUE == didTimeout( rsrvrsVolMonitorTimer, RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ) ) + { + areRsrvrsLeaking = FALSE; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; + status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; + } } - // If the volume is out of range and it has timed out, exit - else if ( TRUE == didTimeout( rsrvrsVolMonitorTimer, RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ) ) - { - areRsrvrsLeaking = FALSE; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; - status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; - } } // Reservoirs are in range else @@ -1735,8 +1749,8 @@ uiData.heatDisinfectTargetTime = targetDisinfectTime; uiData.heatDisinfectCountdownTime = countDown / 1000; // The count down is converted into seconds since the UI does not work with milliseconds - data.R1FillLevel = R1HeatDisinfectVol; - data.R2FillLevel = R2HeatDisinfectVol; + data.R1FillLevel = rsrvr1RefVolML; + data.R2FillLevel = rsrvr2RefVolML; } else { @@ -1805,6 +1819,8 @@ * 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 *************************************************************************/ static void writeDisinfectDataToNV( DG_USAGE_INFO_ITEMS_T info ) Index: firmware/App/Services/AlarmMgmt.c =================================================================== diff -u -r81769c6bea6ed32d70698fb03ad5823de1814b27 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 81769c6bea6ed32d70698fb03ad5823de1814b27) +++ firmware/App/Services/AlarmMgmt.c (.../AlarmMgmt.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -378,6 +378,8 @@ case DG_MODE_HEAT: case DG_MODE_CHEM: case DG_MODE_SERV: + case DG_MODE_CHFL: + case DG_MODE_HCOL: status = FALSE; break; Index: firmware/App/Services/PIControllers.c =================================================================== diff -u -r5e8f96e11c797bddeddfc009c87f20df3b7a8664 -r5aee05d242962c2f9294577c3ba5015f9342fb83 --- firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 5e8f96e11c797bddeddfc009c87f20df3b7a8664) +++ firmware/App/Services/PIControllers.c (.../PIControllers.c) (revision 5aee05d242962c2f9294577c3ba5015f9342fb83) @@ -169,7 +169,7 @@ if ( controller->direction == CONTROLLER_UNIDIRECTIONAL ) { // Control should always be positive - controller->errorSignal = fabs( referenceSignal ) - ( referenceSignal < 0.0 ? ( measuredSignal * -1.0 ) : measuredSignal ); + controller->errorSignal = fabs( referenceSignal ) - ( referenceSignal < 0.0F ? ( measuredSignal * -1.0F ) : measuredSignal ); } else { @@ -179,9 +179,9 @@ // Limit error sum step size if ( fabs( controller->errorSignal ) > controller->maxErrorSumStep ) { - if ( controller->errorSignal < 0.0 ) + if ( controller->errorSignal < 0.0F ) { - controller->errorSum += ( controller->maxErrorSumStep * -1.0 ); + controller->errorSum += ( controller->maxErrorSumStep * -1.0F ); } else {