Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r56ba1b163b0cbf6953638065b2108f745b17ec8f -rc7471bcaa802b31c4af8f4e7879f5632d946b357 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 56ba1b163b0cbf6953638065b2108f745b17ec8f) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision c7471bcaa802b31c4af8f4e7879f5632d946b357) @@ -8,7 +8,7 @@ * @file ConductivitySensors.c * * @author (last) Dara Navaei -* @date (last) 02-Feb-2023 +* @date (last) 28-Mar-2023 * * @author (original) Quang Nguyen * @date (original) 13-Jul-2020 @@ -20,6 +20,7 @@ #include "FPGA.h" #include "NVDataMgmt.h" #include "MessageSupport.h" +#include "ModeFill.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" @@ -52,8 +53,11 @@ #define MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 200.0F ///< Maximum allowed low conductivity value in uS/cm. #define MIN_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM 220.0F ///< Minimum allowed low conductivity value in uS/cm. +#define MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 100.0F ///< Maximum RO only mode high conductivity value in uS/cm. +#define MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM 90.0F ///< Minimum RO only mode high conductivity value in uS/cm. + #define MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< New reading every 800 ms, expect to get valid new reading in 1s. -#define MAX_CONDUCTIVITY_SENSOR_FAILURES 5 ///< maximum number of conductivity sensor errors within window period before alarm. +#define MAX_CONDUCTIVITY_SENSOR_FAILURES 2 ///< maximum number of conductivity sensor errors within window period before alarm. #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. @@ -74,6 +78,9 @@ #define EMSTAT_CPI_OR_CD1_INDEX 0 ///< Emstat board CPi index number. #define EMSTAT_CPO_OR_CD2_INDEX 1 ///< Emstat board CPo index number. +#define EMSTAT_PACKAGE_BUFFER_SIZE 50 ///< EmStat package buffer size +#define EMSTAT_RX_FIFO_COUNT_MASK 0x7FFF ///< EmStat Rx fifo count mask + #define DATA_PUBLISH_COUNTER_START_COUNT 40 ///< Data publish counter start count. #define COND_SENSOR_BAD_STATUS_PERSISTENCE_PERIOD ( 1 * MS_PER_SECOND ) ///< Conductivity sensor bad status persistence period. #define COND_SENSORS_FPGA_ERROR_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Conductivity sensors FPGA error timeout in milliseconds. @@ -104,7 +111,7 @@ { BOOL packageStarted; ///< Emstat package started flag. U08 packageIndex; ///< Emstat package index number. - U08 package[ 50 ]; ///< Emstat read buffer package. + U08 package[ EMSTAT_PACKAGE_BUFFER_SIZE ]; ///< Emstat read buffer package. EMSTAT_COND_SENSORS_T sensors[ EMSTAT_NUM_OF_SENSORS_PER_BOARD ]; ///< Emstat conductivity and corresponding temperature sensors. } EMSTAT_READ_T; @@ -113,9 +120,11 @@ { U08 readCount; ///< Conductivity sensor FPGA read count (For V3). U32 internalErrorCount; ///< Conductivity sensor internal error count. + U32 badCharErrorCount; ///< Conductivity sensor bad char error count OVERRIDE_F32_T compensatedCondValue; ///< Conductivity sensor compensated value F32 rawCondValue; ///< Conductivity sensor raw value. U32 sensorStatus; ///< Conductivity sensor status. + U32 rawEmstatCondValue; ///< Conductivity sensor from Emstat. } COND_SENSOR_STATUS_T; #pragma pack(pop) @@ -182,6 +191,7 @@ emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CPO_SENSOR; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrTempSnsr = TEMPSENSORS_OUTLET_PRIMARY_HEATER; emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrHex2StrAlarm = ALARM_ID_DG_CPO_COND_SENSOR_INVALID_CHAR; + // CD1/CD2 Emstat board conductivity sensors and their corresponding temperature sensors emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CD1_SENSOR; emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsrTempSnsr = TEMPSENSORS_CONDUCTIVITY_SENSOR_1; @@ -197,11 +207,6 @@ 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_CLEAR_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_LOW_RANGE, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_CLEAR_MS, INLET_WATER_COND_SENSOR_OUT_OF_RANGE_TIMEOUT_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 ); @@ -299,9 +304,20 @@ { 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 ); + BOOL isConductTooLow = FALSE; + BOOL isConductTooHigh = FALSE; + if ( FALSE == isROOnlyModeEnabled() ) + { + isConductTooLow = ( conductivity < MAX_COND_SENSOR_CPI_WARNING_LOW_US_PER_CM ? TRUE : FALSE ); + isConductTooHigh = ( conductivity > MAX_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? TRUE : FALSE ); + } + else + { + isConductTooLow = FALSE; + isConductTooHigh = ( conductivity > MAX_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? TRUE : FALSE ); + } + switch( opMode ) { case DG_MODE_GENE: @@ -317,7 +333,14 @@ if ( TRUE == isAlarmActive( ALARM_ID_INLET_WATER_CONDUCTIVITY_IN_HIGH_RANGE ) ) { - isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + if ( FALSE == isROOnlyModeEnabled() ) + { + isConductTooHigh = ( conductivity <= MIN_COND_SENSOR_CPI_WARNING_HIGH_US_PER_CM ? FALSE : TRUE ); + } + else + { + isConductTooHigh = ( conductivity <= MIN_RO_ONLY_COND_SENSOR_CPI_HIGH_US_PER_CM ? FALSE : TRUE ); + } } // Per PRS 404 @@ -328,6 +351,7 @@ case DG_MODE_STAN: case DG_MODE_FLUS: case DG_MODE_HEAT: + case DG_MODE_HCOL: case DG_MODE_CHEM: case DG_MODE_CHFL: if ( VALVE_STATE_OPEN == getValveStateName( VPI ) ) @@ -514,24 +538,34 @@ static void processEmstatBoard( EMSTAT_BOARD_T board ) { U08 emstatByte = 0; - U08 fpgaErrorCount = 0; + U16 rxFifoCount = 0; switch ( board ) { case EMSTAT_CPI_CPO_BOARD: - emstatByte = getFPGAEmstatCPiCPoByteOut(); - fpgaErrorCount = getFPGAEmstatCPiCPoRxErrCount(); + // Check for continuous incoming bytes + rxFifoCount = getFPGAEmstatCPiCPoRxFifoCount() & EMSTAT_RX_FIFO_COUNT_MASK; + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_CPI_CPO_COND_SENSORS, rxFifoCount ); - checkFPGAPersistentErrorCountAlarm( FPGA_PERS_ERROR_CPI_CPO_COND_SENSORS, fpgaErrorCount ); - processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ], emstatByte ); + // Only process the sensor read if there is a new byte + if ( 0 != rxFifoCount ) + { + emstatByte = getFPGAEmstatCPiCPoByteOut(); + processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ], emstatByte ); + } break; case EMSTAT_CD1_CD2_BOARD: - emstatByte = getFPGAEmstatCD1CD2OutByte(); - fpgaErrorCount = getFPGAEmstatCD1CD2RxErrCount(); + // Check for continuous incoming bytes + rxFifoCount = getFPGAEmstatCD1CD2RxFifoCount() & EMSTAT_RX_FIFO_COUNT_MASK; + checkFPGAPersistentAlarms( FPGA_PERS_ERROR_CD1_CD2_COND_SENSORS, rxFifoCount ); - checkFPGAPersistentErrorCountAlarm( FPGA_PERS_ERROR_CD1_CD2_COND_SENSORS, fpgaErrorCount ); - processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ], emstatByte ); + // Only process the sensor read if there is a new byte + if ( 0 != rxFifoCount) + { + emstatByte = getFPGAEmstatCD1CD2OutByte(); + processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ], emstatByte ); + } break; default: @@ -578,7 +612,10 @@ default: if ( TRUE == readPackage->packageStarted ) { - readPackage->package[ readPackage->packageIndex++ ] = emstatByte; + if ( readPackage->packageIndex < EMSTAT_PACKAGE_BUFFER_SIZE ) + { + readPackage->package[ readPackage->packageIndex++ ] = emstatByte; + } } break; } @@ -597,6 +634,7 @@ *************************************************************************/ static void processEmstatMeasurementDataPackets( U08 boardSensorIndex, EMSTAT_READ_T* readPackage, EMSTAT_VARIABLE_T* receivedPackets ) { + CONDUCTIVITY_SENSORS_T sensorId = readPackage->sensors[ boardSensorIndex ].condSnsr; BOOL convStatus = hexStrToDec( (U08*)&receivedPackets->status, &condSensorStatus[ sensorId ].sensorStatus, sizeof( receivedPackets->status ) ); BOOL isSensorStatusBad = ( EMSTAT_PICO_STATUS_TIMING_NOT_MET == condSensorStatus[ sensorId ].sensorStatus ? TRUE : FALSE ); @@ -606,8 +644,9 @@ if ( FALSE == isSensorStatusBad ) { U32 prefix = prefixStrToSIFactor( receivedPackets->prefix ); - convStatus = hexStrToDec( receivedPackets->value, &condSensorStatus[ sensorId ].sensorStatus, sizeof( receivedPackets->value ) ); - F32 resistance = ( ( F32 )( condSensorStatus[ sensorId ].sensorStatus - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); + convStatus = hexStrToDec( receivedPackets->value, &condSensorStatus[ sensorId ].rawEmstatCondValue, sizeof( receivedPackets->value ) ); + + F32 resistance = ( ( F32 )( condSensorStatus[ sensorId ].rawEmstatCondValue - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); F32 temperature = getTemperatureValue( readPackage->sensors[ boardSensorIndex ].condSnsrTempSnsr ); F32 conductivity = ( 1.0F / resistance ) * SIEMENS_TO_MICROSIEMENS_CONVERSION; F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); @@ -619,15 +658,23 @@ isConvNotValid = ( TRUE == convStatus ? FALSE : TRUE ); // Check the conductivity sensors bad status alarm - checkPersistentAlarm( badHexAlarm, isConvNotValid, isConvNotValid, COND_SENSORS_BAD_CHAR_TIME_OUT_MS ); - checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, isSensorStatusBad, condSensorStatus[ sensorId ].sensorStatus, - EMSTAT_PICO_STATUS_TIMING_NOT_MET ); + if ( TRUE == isConvNotValid ) + { + if ( ++condSensorStatus[ sensorId ].badCharErrorCount > MAX_CONDUCTIVITY_SENSOR_FAILURES ) + { + SET_ALARM_WITH_1_U32_DATA( badHexAlarm, sensorId ); + } + } + else + { + condSensorStatus[ sensorId ].badCharErrorCount = 0; + } if ( EMSTAT_PICO_STATUS_TIMING_NOT_MET == condSensorStatus[ sensorId ].sensorStatus ) { if ( ++condSensorStatus[ sensorId ].internalErrorCount > MAX_CONDUCTIVITY_SENSOR_FAILURES ) { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, sensorId ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, sensorId, condSensorStatus[ sensorId ].sensorStatus ); } } else