Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r852597f3be2578331b0b947b38969b3c9553f889 -r87ebf31788a90216c65e0264e2b8cb21d25e5b9b --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 852597f3be2578331b0b947b38969b3c9553f889) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 87ebf31788a90216c65e0264e2b8cb21d25e5b9b) @@ -8,7 +8,7 @@ * @file ConductivitySensors.c * * @author (last) Dara Navaei -* @date (last) 14-Jun-2022 +* @date (last) 03-Aug-2022 * * @author (original) Quang Nguyen * @date (original) 13-Jul-2020 @@ -20,6 +20,7 @@ #include "FPGA.h" #include "NVDataMgmt.h" #include "MessageSupport.h" +#include "OperationModes.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" @@ -39,9 +40,9 @@ #define COND_CPI_SENSOR_PROBE_TYPE 100 ///< 1 K cell constant conductivity probe. #define COND_CPO_SENSOR_PROBE_TYPE 10 ///< 0.1 K cell constant conductivity probe. -#define COND_SENSOR_DECIMAL_CONVERSION 100 ///< Conductivity value from FPGA has two decimal place. +#define COND_SENSOR_DECIMAL_CONVERSION 100.0F ///< Conductivity value from FPGA has two decimal place. #define COND_SENSOR_TEMPERATURE_COEF 0.02F ///< Linear temperature coefficient of variation at 25 Celcius for fresh water. -#define COND_SENSOR_REFERENCE_TEMPERATURE 25 ///< Reference temperature for conductivity sensor. +#define COND_SENSOR_REFERENCE_TEMPERATURE 25.0F ///< Reference temperature for conductivity sensor. #define COND_SENSOR_REPORT_PERIOD ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Broadcast conductivity values message every second. #define MAX_COND_SENSOR_CPI_WARNING_HIGH 2000.0F ///< Maximum allowed high conductivity value. @@ -56,15 +57,25 @@ #define RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE 1.0F ///< Out of range value for RO rejection ratio when CPi conductivity is zero. #define MAX_RO_REJECTION_RATIO_ALLOW 0.10F ///< Maximum RO rejection ratio. -#define MAX_CPO_CONDUCTIVITY_ALLOW 30.0 ///< Maximum CPo sensor conductivity value. +#define MAX_CPO_CONDUCTIVITY_ALLOW 30.0F ///< Maximum CPo sensor conductivity value. #define COND_SENSOR_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity sensor out of range error. #define RO_REJECTION_RATIO_PERSISTENCE_PERIOD ( 10 * MS_PER_SECOND ) ///< Persistence period for RO rejection ratio. -#define EMSTAT_PICO_MEASUREMENT_OFFSET 0x8000000 ///< Measurement offset for emstat pico measurement data. -#define EMSTAT_PICO_GOOD_STATUS 0x10 ///< Measurement good status. -#define EMSTAT_PICO_TIMING_NOT_MET_STATUS 0x11 ///< Measurement takes too long status. -#define EMSTAT_PICO_FIFO_EMPTY_MASK 0x8000 ///< Emstat Pico buffer empty indication bit. +#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 +// The first hex value is the status ID meaning that all of these are the status of the sensor. The second hex value is the content. +#define EMSTAT_PICO_STATUS_OK 0x10 ///< Emstat measurement good status. +#define EMSTAT_PICO_STATUS_TIMING_NOT_MET 0x11 ///< Emstat measurement takes too long status. +#define EMSTAT_PICO_STATUS_95_PCT_OF_MAX_ADC 0x12 ///< Emstat measurement overload, >95% of max ADC value status. +#define EMSTAT_PICO_STATUS_2_PCT_OF_MAX_ADC 0x14 ///< Emstat measurement underload, <2% of max ADC value status. +#define EMSTAT_PICO_STATUS_80_PCT_OF_MAX_ADC 0x18 ///< Emstat measurement overload warning, >80% of max ADC value status. + +#define EMSTAT_PICO_FIFO_EMPTY_MASK 0x8000 ///< Emstat buffer empty indication bit. +#define EMSTAT_NUM_OF_SENSORS_PER_BOARD 2 ///< Emstat Pico number of sensors per board. +#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 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. @@ -79,44 +90,64 @@ U16 status; ///< Status for measurement data package U08 reserved2[4]; ///< Comma separator and index of current range } EMSTAT_VARIABLE_T; + +/// Emstat conductivity sensor and its corresponding temperature sensor +typedef struct +{ + CONDUCTIVITY_SENSORS_T condSnsr; ///< Emstat conductivity sensor 1 on the board. + TEMPERATURE_SENSORS_T condSnsrTempSnsr; ///< Emstat conductivity sensor 1 temperature sensor. +} EMSTAT_COND_AND_TEMP_T; + +/// Emstat board structure +typedef struct +{ + BOOL packageStarted; ///< Emstat package started flag. + U08 packageIndex; ///< Emstat package index number. + U08 package[ 50 ]; ///< Emstat read buffer package. + EMSTAT_COND_AND_TEMP_T sensors[ EMSTAT_NUM_OF_SENSORS_PER_BOARD ]; ///< Emstat conductivity and corresponding temperature sensors + U16 fpgaPreviousCount; ///< Emstat FPGA previous count. + U08 fpgaPreviousErrorCount; ///< Emstat FPGA previous error count. +} EMSTAT_READ_T; + +/// Conductivity sensors structure +typedef struct +{ + U08 readCount; ///< Conductivity sensor FPGA read count. + U32 internalErrorCount; ///< Conductivity sensor internal error count. + OVERRIDE_F32_T compensatedCondValue; ///< Conductivity sensor compensated value + F32 rawCondValue; ///< Conductivity sensor raw value. + U32 sensorStatus; ///< Conductivity sensor status. +} COND_SENSOR_STATUS_T; #pragma pack(pop) // ********** private data ********** -/// Conductivity sensors' associated temperature sensors -static U32 associateTempSensor[ NUM_OF_CONDUCTIVITY_SENSORS ] = +/// Emstat boards for CPi/CPo and CD1/CD2 +typedef enum EmstatBoards { - TEMPSENSORS_INLET_PRIMARY_HEATER, ///< Inlet temperature sensor - TEMPSENSORS_OUTLET_PRIMARY_HEATER, ///< Outlet temperature sensor - TEMPSENSORS_CONDUCTIVITY_SENSOR_1, ///< Post-acid temperature sensor - TEMPSENSORS_CONDUCTIVITY_SENSOR_2, ///< Post-bicarbonate temperature sensor -}; + EMSTAT_CPI_CPO_BOARD = 0, ///< Emstat CPi/CPo board. + EMSTAT_CD1_CD2_BOARD, ///< Emstat CD1/CD2 board. + NUM_OF_EMSTAT_BOARDS ///< Number of Emstat boards. +} EMSTAT_BOARD_T; -static U08 readCount[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Read count for conductivity readings. -static U32 internalErrorCount[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Internal error count for conductivity readings. -static OVERRIDE_F32_T compensatedConductivityValues[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Latest compensated conductivity values. -static F32 rawConductivityValues[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Latest raw conductivity values. -static F32 roRejectionRatio; ///< Latest RO rejection ratio. -static U32 sensorStatus[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Latest sensor hardware status. - static OVERRIDE_U32_T conductivityDataPublishInterval = { COND_SENSOR_REPORT_PERIOD, COND_SENSOR_REPORT_PERIOD, 0, 0 }; ///< Conductivity sensors publish time interval override. -static U32 conductivityDataPublicationTimerCounter; ///< Conductivity sensors data publish timer counter. - -static BOOL packageStarted; ///< Flag to indicate the start of a package measurement data. -static U08 packageIndex; ///< Current package measurement data bytes index. -static U08 package[ 50 ]; ///< Storage of package bytes until ready to process. +static F32 roRejectionRatio; ///< Latest RO rejection ratio. +static U32 condDataPublishCounter; ///< Conductivity sensors data publish timer counter. +static EMSTAT_READ_T emstatBoardRead[ NUM_OF_EMSTAT_BOARDS ]; ///< EMSTAT board read. +static COND_SENSOR_STATUS_T condSensorStatus[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Conductivity sensors status. static DG_COND_SENSORS_CAL_RECORD_T condSensorsCalRecord; ///< Conductivity sensors' calibration record. // ********** private function prototypes ********** static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ); static void calcRORejectionRatio( void ); -static void processCPiCPoSensorRead( U32 sensorId, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ); +static void processCPiCPoSensorRead( U32 sensorId, U08 emstatBoardSensorIndex, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ); static U32 prefixStrToSIFactor( U08 prefix ); -static void processMeasurementDataPackage( U32 sensorId ); -static void processCD1CD2SensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ); +static void processEmstatBoard( EMSTAT_BOARD_T board ); +static void processEmstatSensorRead( EMSTAT_READ_T* readPackage, U08 emstatByte, U16 fpgaReadCount, U08 fpgaErrorCount ); +static void processEmstatMeasurementDataPackets( U08 boardSensorIndex, EMSTAT_READ_T* readPackage, EMSTAT_VARIABLE_T* receivedPackets ); static F32 getCalibrationAppliedConductivityValue( U32 sensorId, F32 compensatedValue ); /*********************************************************************//** @@ -128,36 +159,44 @@ *************************************************************************/ void initConductivitySensors( void ) { - U32 i; + U08 i; + roRejectionRatio = 0.0; + condDataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; - roRejectionRatio = 0.0; - packageIndex = 0U; - packageStarted = FALSE; - conductivityDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; - for ( i = 0; i < NUM_OF_CONDUCTIVITY_SENSORS; i++ ) { - readCount[ i ] = 0; - internalErrorCount[ i ] = 0; - rawConductivityValues[ i ] = 0.0; - - compensatedConductivityValues[ i ].data = 0.0; - compensatedConductivityValues[ i ].ovData = 0.0; - compensatedConductivityValues[ i ].ovInitData = 0.0; - compensatedConductivityValues[ i ].override = OVERRIDE_RESET; - + memset( &condSensorStatus[ i ], 0x0, sizeof( COND_SENSOR_STATUS_T ) ); benignPolynomialCalRecord( &condSensorsCalRecord.condSensors[ i ] ); } + // Reset all the read packages of the Emstat boards + for ( i = 0; i < NUM_OF_EMSTAT_BOARDS; i++ ) + { + memset( &emstatBoardRead[ i ], 0x0, sizeof( EMSTAT_BOARD_T ) ); + } + + // Each Emstat board covers two conductivity sensors + // CPi/CPo Emstat board conductivity sensors and their corresponding temperature sensors + emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CPI_SENSOR; + emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ EMSTAT_CPI_OR_CD1_INDEX ].condSnsrTempSnsr = TEMPSENSORS_INLET_PRIMARY_HEATER; + 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; + // 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; + emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsr = CONDUCTIVITYSENSORS_CD2_SENSOR; + emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].sensors[ EMSTAT_CPO_OR_CD2_INDEX ].condSnsrTempSnsr = TEMPSENSORS_CONDUCTIVITY_SENSOR_2; + + // For V3 conductivity sensors 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_RO_REJECTION_RATIO_OUT_OF_RANGE, RO_REJECTION_RATIO_PERSISTENCE_PERIOD, RO_REJECTION_RATIO_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_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); + 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_RO_REJECTION_RATIO_OUT_OF_RANGE, RO_REJECTION_RATIO_PERSISTENCE_PERIOD, RO_REJECTION_RATIO_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_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); } /*********************************************************************//** @@ -178,34 +217,38 @@ NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); } - processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount(), getFPGACPiFault() ); - processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPO_SENSOR, getFPGACPo(), getFPGACPoReadCount(), getFPGACPoErrorCount(), getFPGACPoFault() ); - processCD1CD2SensorRead( getFPGAEmstatRxFifoCount(), getFPGAEmstatRxErrCount() ); +#ifndef _RELEASE_ + if ( SW_CONFIG_ENABLE_VALUE == getSoftwareConfigStatus( SW_CONFIG_ENABLE_V3_SYSTEM ) ) + { + processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, EMSTAT_CPI_OR_CD1_INDEX, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount(), getFPGACPiFault() ); + processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPO_SENSOR, EMSTAT_CPO_OR_CD2_INDEX, getFPGACPo(), getFPGACPoReadCount(), getFPGACPoErrorCount(), getFPGACPoFault() ); + } + else +#endif + { + processEmstatBoard( EMSTAT_CPI_CPO_BOARD ); + } + processEmstatBoard( EMSTAT_CD1_CD2_BOARD ); - if ( ++conductivityDataPublicationTimerCounter >= getU32OverrideValue( &conductivityDataPublishInterval ) ) + if ( ++condDataPublishCounter >= getU32OverrideValue( &conductivityDataPublishInterval ) ) { CONDUCTIVITY_DATA_T data; calcRORejectionRatio(); - - conductivityDataPublicationTimerCounter = 0; - data.roRejectionRatio = roRejectionRatio; - - data.cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - data.cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); - data.cd1 = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); - data.cd2 = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); - - data.cpiRaw = rawConductivityValues[ CONDUCTIVITYSENSORS_CPI_SENSOR ]; - data.cpoRaw = rawConductivityValues[ CONDUCTIVITYSENSORS_CPO_SENSOR ]; - data.cd1Raw = rawConductivityValues[ CONDUCTIVITYSENSORS_CD1_SENSOR ]; - data.cd2Raw = rawConductivityValues[ CONDUCTIVITYSENSORS_CD2_SENSOR ]; - - data.cpiSensorStatus = sensorStatus[ CONDUCTIVITYSENSORS_CPI_SENSOR ]; - data.cpoSensorStatus = sensorStatus[ CONDUCTIVITYSENSORS_CPO_SENSOR ]; - data.cd1SensorStatus = sensorStatus[ CONDUCTIVITYSENSORS_CD1_SENSOR ]; - data.cd2SensorStatus = sensorStatus[ CONDUCTIVITYSENSORS_CD2_SENSOR ]; - + data.roRejectionRatio = roRejectionRatio; + data.cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + data.cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + data.cd1 = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); + data.cd2 = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + data.cpiRaw = condSensorStatus[ CONDUCTIVITYSENSORS_CPI_SENSOR ].rawCondValue; + data.cpoRaw = condSensorStatus[ CONDUCTIVITYSENSORS_CPO_SENSOR ].rawCondValue; + data.cd1Raw = condSensorStatus[ CONDUCTIVITYSENSORS_CD1_SENSOR ].rawCondValue; + data.cd2Raw = condSensorStatus[ CONDUCTIVITYSENSORS_CD2_SENSOR ].rawCondValue; + data.cpiSensorStatus = condSensorStatus[ CONDUCTIVITYSENSORS_CPI_SENSOR ].sensorStatus; + data.cpoSensorStatus = condSensorStatus[ CONDUCTIVITYSENSORS_CPO_SENSOR ].sensorStatus; + data.cd1SensorStatus = condSensorStatus[ CONDUCTIVITYSENSORS_CD1_SENSOR ].sensorStatus; + data.cd2SensorStatus = condSensorStatus[ CONDUCTIVITYSENSORS_CD2_SENSOR ].sensorStatus; + condDataPublishCounter = 0; broadcastData( MSG_ID_DG_CONDUCTIVITY_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&data, sizeof( CONDUCTIVITY_DATA_T ) ); } } @@ -220,20 +263,10 @@ *************************************************************************/ SELF_TEST_STATUS_T execConductivitySensorsSelfTest( void ) { - SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - - BOOL calStatus = getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( condSensorsCalRecord ), + BOOL calStatus = getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( condSensorsCalRecord ), NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); + SELF_TEST_STATUS_T result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); - if ( TRUE == calStatus ) - { - result = SELF_TEST_STATUS_PASSED; - } - else - { - result = SELF_TEST_STATUS_FAILED; - } - return result; } @@ -294,15 +327,15 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_RO_RATIO_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif { - F32 cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); - BOOL isRORectionOutOfRange = ( roRejectionRatio > MAX_RO_REJECTION_RATIO_ALLOW ? TRUE : FALSE ); - BOOL isCPoOutOfRange = ( cpo >= MAX_CPO_CONDUCTIVITY_ALLOW ? TRUE : FALSE ); + F32 cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + BOOL isRORejectionOutOfRange = ( roRejectionRatio > MAX_RO_REJECTION_RATIO_ALLOW ? TRUE : FALSE ); + BOOL isCPoOutOfRange = ( cpo >= MAX_CPO_CONDUCTIVITY_ALLOW ? TRUE : FALSE ); // Fault alarm per PRS 483 checkPersistentAlarm( ALARM_ID_DG_OUTLET_PRIMARY_CONDUCTIVITY_OUT_OF_RANGE, isCPoOutOfRange, cpo, MAX_CPO_CONDUCTIVITY_ALLOW ); // Fault alarm per PRS 483 - checkPersistentAlarm( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, isRORectionOutOfRange, roRejectionRatio, MAX_RO_REJECTION_RATIO_ALLOW ); + checkPersistentAlarm( ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, isRORejectionOutOfRange, roRejectionRatio, MAX_RO_REJECTION_RATIO_ALLOW ); } } @@ -321,7 +354,10 @@ if ( sensorId < NUM_OF_CONDUCTIVITY_SENSORS ) { - result = getF32OverrideValue( &compensatedConductivityValues[ sensorId ] ); + // NOTE: the compensated value is set into a local variable and then passed to the override function + // to prevent memory failure + OVERRIDE_F32_T value = condSensorStatus[ sensorId ].compensatedCondValue; + result = getF32OverrideValue( &value ); } else { @@ -345,7 +381,7 @@ static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ) { // EC = EC_25 * (1 + temp_coef * ( temperature - 25 )) - F32 const compensatedCoef = ( 1.0 + ( COND_SENSOR_TEMPERATURE_COEF * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); + F32 compensatedCoef = ( 1.0 + ( COND_SENSOR_TEMPERATURE_COEF * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); return conductivity / compensatedCoef; } @@ -360,15 +396,16 @@ *************************************************************************/ static void calcRORejectionRatio( void ) { - F32 const cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); - F32 const cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + F32 cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + F32 cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); roRejectionRatio = RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE; if ( fabs(cpi) >= NEARLY_ZERO ) { roRejectionRatio = cpo / cpi; } + } /*********************************************************************//** @@ -379,31 +416,33 @@ * @details Inputs: none * @details Outputs: none * @param sensorId Conductivity sensor id to process + * @param emstatBoardSensorIndex the sensor index number on an EMSTAT board * @param fgpaRead FPGA conductivity reading value * @param fpgaReadCount FPGA read count * @param fpgaErrorCount FPGA error count * @param fpgaSensorFault FPGA sensor fault * @return none *************************************************************************/ -static void processCPiCPoSensorRead( U32 sensorId, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ) +static void processCPiCPoSensorRead( U32 sensorId, U08 emstatBoardSensorIndex, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ) { if ( ( 0 == fpgaErrorCount ) && ( 0 == fpgaSensorFault ) ) { - if ( ( readCount[ sensorId ] != fpgaReadCount ) ) + if ( ( condSensorStatus[ sensorId ].readCount != fpgaReadCount ) ) { - F32 temperature = getTemperatureValue( associateTempSensor[ sensorId ] ); - F32 conductivity = ( (F32)( fgpaRead ) / COND_SENSOR_DECIMAL_CONVERSION ); + // The corresponding temperature sensor of a conductivity sensor is maintained in the EMSTAT boards' structure since the + // EMSTAT sensors will be the permanent sensors from DVT onward. + F32 temperature = getTemperatureValue( emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].sensors[ emstatBoardSensorIndex ].condSnsrTempSnsr ); + F32 conductivity = ( (F32)( fgpaRead ) / COND_SENSOR_DECIMAL_CONVERSION ); F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); - readCount[ sensorId ] = fpgaReadCount; - internalErrorCount[ sensorId ] = 0; - compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); - rawConductivityValues[ sensorId ] = conductivity; // store raw conductivity data from CPi and CPo + condSensorStatus[ sensorId ].readCount = fpgaReadCount; + condSensorStatus[ sensorId ].internalErrorCount = 0; + condSensorStatus[ sensorId ].compensatedCondValue.data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + condSensorStatus[ sensorId ].rawCondValue = conductivity; // store raw conductivity data from CPi and CPo } else { - ++internalErrorCount[ sensorId ]; - if ( internalErrorCount[ sensorId ] > MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS ) + if ( ++condSensorStatus[ sensorId ].internalErrorCount > MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS ) { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_COND_SENSOR_CHECK ) != SW_CONFIG_ENABLE_VALUE ) @@ -416,7 +455,7 @@ } else { - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR ) ) + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR ) ) // TODO remove time windowed { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_COND_SENSOR_CHECK ) != SW_CONFIG_ENABLE_VALUE ) @@ -460,110 +499,97 @@ /*********************************************************************//** * @brief - * The processMeasurementDataPackage function processes incoming measurement data - * package variables from Emstat Pico and convert it to conductivity. The conductivity - * value is then compensated based on associating temperature sensor's value. - * @details Inputs: none - * @details Outputs: none - * @param sensorId Conductivity sensor id to process + * The processEmstatBoard function processes the Emsat boards + * @details Inputs: emstatBoardRead + * @details Outputs: emstatBoardRead + * @param board the enum of the Emstat board * @return none *************************************************************************/ -static void processMeasurementDataPackage( U32 sensorId ) +static void processEmstatBoard( EMSTAT_BOARD_T board ) { - EMSTAT_VARIABLE_T const * const measurementPtr = (EMSTAT_VARIABLE_T *)&package; - U32 status = hexStrToDec( (U08 *)&measurementPtr->status, sizeof( measurementPtr->status ) ); - sensorStatus[ sensorId ] = status; + U08 emstatByte = 0; + U08 fpgaErrorCount = 0; + U16 fpgaReadCount = 0; - if ( EMSTAT_PICO_GOOD_STATUS == status ) + switch ( board ) { - U32 prefix = prefixStrToSIFactor( measurementPtr->prefix ); - F32 resistance = ( ( F32 )( hexStrToDec( measurementPtr->value, sizeof( measurementPtr->value ) ) - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); - F32 temperature = getTemperatureValue( associateTempSensor[ sensorId ] ); - F32 conductivity = ( 1.0 / resistance * SIEMENS_TO_MICROSIEMENS_CONVERSION ); - F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); + case EMSTAT_CPI_CPO_BOARD: + emstatByte = getFPGAEmstatCPiCPoByteOut(); + fpgaErrorCount = getFPGAEmstatCPiCPoRxErrCount(); + fpgaReadCount = getFPGAEmstatCPiCPoRxFifoCount(); + processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ], emstatByte, fpgaReadCount, fpgaErrorCount ); + break; - internalErrorCount[ sensorId ] = 0; - compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); - rawConductivityValues[ sensorId ] = conductivity; // store raw conductivity data from CD1 and CD2 + case EMSTAT_CD1_CD2_BOARD: + emstatByte = getFPGAEmstatCD1CD2OutByte(); + fpgaErrorCount = getFPGAEmstatCD1CD2RxErrCount(); + fpgaReadCount = getFPGAEmstatCD1CD2RxFifoCount(); + processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ], emstatByte, fpgaReadCount, fpgaErrorCount ); + break; - // Clear the alarm - checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, FALSE, status, EMSTAT_PICO_GOOD_STATUS ); + default: + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_EMSTAT_CONDUCTIVITY_BOARD_SELECTED, board ); + break; } - else - { -#ifndef DISABLE_COND_STATUS_CHECK - checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, TRUE, status, EMSTAT_PICO_GOOD_STATUS ); -#endif - } - - if ( EMSTAT_PICO_TIMING_NOT_MET_STATUS == status ) - { - if ( ++internalErrorCount[ sensorId ] > MAX_CONDUCTIVITY_SENSOR_FAILURES ) - { - SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, sensorId ); - } - } - else - { - internalErrorCount[ sensorId ] = 0; - } } /*********************************************************************//** * @brief - * The processCD1CD2SensorRead function checks if there is an error with Emstat - * conductivity sensors. If there is any error with the Emstat conductivity sensors, - * it raises an alarm. If the read count has changed, the new reading will be processed. + * The processEmstatSensorRead function processes the Emsat boards' data + * that is received from the boards * @details Inputs: none * @details Outputs: none - * @param fpgaReadCount FPGA read count for rx fifo - * @param fpgaErrorCount FPGA error count + * @param read package the structure of each Emstat board + * @param emstatByte the received byte from the sensor + * @param fpgaReadCount the FPGA read count + * @param fpgaErrorCount the FGPA error count * @return none *************************************************************************/ -static void processCD1CD2SensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ) +static void processEmstatSensorRead( EMSTAT_READ_T* readPackage, U08 emstatByte, U16 fpgaReadCount, U08 fpgaErrorCount ) { - if ( fpgaErrorCount == 0 ) + switch ( emstatByte ) { - if ( ( fpgaReadCount > 0 ) && ( ( fpgaReadCount & EMSTAT_PICO_FIFO_EMPTY_MASK ) == 0 ) ) - { - U08 const emstatByte = getFPGAEmstatOutByte(); + case 'P': + readPackage->packageStarted = TRUE; + readPackage->packageIndex = 0; + break; - switch ( emstatByte ) + case ';': + if ( TRUE == readPackage->packageStarted ) { - case 'P': - packageStarted = TRUE; - packageIndex = 0; - break; + processEmstatMeasurementDataPackets( EMSTAT_CPI_OR_CD1_INDEX, readPackage, (EMSTAT_VARIABLE_T*)readPackage->package ); + readPackage->packageIndex = 0; + } + break; - case ';': - if ( packageStarted ) - { - processMeasurementDataPackage( CONDUCTIVITYSENSORS_CD1_SENSOR ); - packageIndex = 0; - } - break; + case '\n': + if ( TRUE == readPackage->packageStarted ) + { + processEmstatMeasurementDataPackets( EMSTAT_CPO_OR_CD2_INDEX, readPackage, (EMSTAT_VARIABLE_T*)readPackage->package ); + readPackage->packageStarted = FALSE; + } + break; - case '\n': - if ( packageStarted ) - { - processMeasurementDataPackage( CONDUCTIVITYSENSORS_CD2_SENSOR ); - packageStarted = FALSE; - } - break; - - default: - if ( packageStarted ) - { - package[ packageIndex++ ] = emstatByte; - } - break; + default: + if ( TRUE == readPackage->packageStarted ) + { + readPackage->package[ readPackage->packageIndex++ ] = emstatByte; } - } + break; } - else + +#ifndef DISABLE_FPGA_ALARMS_UNTIL_THE_NEW_PERSISTENT + // Only process the FPGA error and count values if the DG Software is not in the POST mode + if ( getCurrentOperationMode() != DG_MODE_INIT ) { - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR ) ) + if ( ( fpgaReadCount != readPackage->fpgaPreviousCount ) && ( 0 == ( fpgaReadCount & EMSTAT_PICO_FIFO_EMPTY_MASK ) ) && + ( fpgaErrorCount != readPackage->fpgaPreviousErrorCount ) ) { + // Everything is fine update the previous read with the current read + readPackage->fpgaPreviousCount = fpgaReadCount; + } + else if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR ) ) // TODO remove time windowed + { #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_COND_SENSOR_CHECK ) != SW_CONFIG_ENABLE_VALUE ) #endif @@ -572,10 +598,58 @@ } } } +#endif } /*********************************************************************//** * @brief + * The processEmstatMeasurementDataPackets function processes the Emsat boards' + * received data packets. + * @details Inputs: condSensorStatus, + * @details Outputs: condSensorStatus + * @param boardSenosrIndex the sensor index on each board (i.e CPi = 0 & CPo = 1 + * in EMSTAT_CPI_CPO_BOARD) + * @param read package the structure of each Emstat board + * @return none + *************************************************************************/ +static void processEmstatMeasurementDataPackets( U08 boardSensorIndex, EMSTAT_READ_T* readPackage, EMSTAT_VARIABLE_T* receivedPackets ) +{ + CONDUCTIVITY_SENSORS_T sensorId = readPackage->sensors[ boardSensorIndex ].condSnsr; + condSensorStatus[ sensorId ].sensorStatus = hexStrToDec( (U08*)&receivedPackets->status, sizeof( receivedPackets->status ) ); + BOOL isSensorStatusBad = ( EMSTAT_PICO_STATUS_TIMING_NOT_MET == condSensorStatus[ sensorId ].sensorStatus ? TRUE : FALSE ); + + if ( FALSE == isSensorStatusBad ) + { + U32 prefix = prefixStrToSIFactor( receivedPackets->prefix ); + F32 resistance = ( ( F32 )( hexStrToDec( receivedPackets->value, sizeof( receivedPackets->value ) ) - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); + F32 temperature = getTemperatureValue( readPackage->sensors[ boardSensorIndex ].condSnsrTempSnsr ); + F32 conductivity = ( 1.0 / resistance ) * SIEMENS_TO_MICROSIEMENS_CONVERSION; + F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); + + condSensorStatus[ sensorId ].internalErrorCount = 0; + condSensorStatus[ sensorId ].compensatedCondValue.data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + condSensorStatus[ sensorId ].rawCondValue = conductivity; + } + + // Check the conductivity sensors bad status alarm + checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, isSensorStatusBad, condSensorStatus[ sensorId ].sensorStatus, + EMSTAT_PICO_STATUS_TIMING_NOT_MET ); + + 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 ); + } + } + else + { + condSensorStatus[ sensorId ].internalErrorCount = 0; + } +} + +/*********************************************************************//** + * @brief * The getCalibrationAppliedConductivityValue function gets the temperature * compensated conductivity value and applies calibration to it. * @details Inputs: condSensorsCalRecord @@ -590,7 +664,7 @@ F32 conductivity = pow(compensatedValue, 4) * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].fourthOrderCoeff + pow(compensatedValue, 3) * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].thirdOrderCoeff + pow(compensatedValue, 2) * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].secondOrderCoeff + - compensatedValue * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].gain + + compensatedValue * condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].gain + condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].offset; return conductivity; } @@ -605,8 +679,8 @@ * @brief * The testSetConductivityOverride function overrides the compensated * conductivity value of given sensor id. - * @details Inputs: compensatedConductivityValues[] - * @details Outputs: compensatedConductivityValues[] + * @details Inputs: none + * @details Outputs: condSensorStatus * @param sensorId conductivity sensor id * @param value override compensated conductivity value * @return TRUE if override successful, FALSE if not @@ -617,11 +691,11 @@ if ( sensorId < NUM_OF_CONDUCTIVITY_SENSORS ) { - if ( isTestingActivated() ) + if ( TRUE == isTestingActivated() ) { - result = TRUE; - compensatedConductivityValues[ sensorId ].ovData = value; - compensatedConductivityValues[ sensorId ].override = OVERRIDE_KEY; + result = TRUE; + condSensorStatus[ sensorId ].compensatedCondValue.ovData = value; + condSensorStatus[ sensorId ].compensatedCondValue.override = OVERRIDE_KEY; } } @@ -632,8 +706,8 @@ * @brief * The testResetConductivityOverride function resets the override of the * conductivity sensor value. - * @details Inputs: compensatedConductivityValues[] - * @details Outputs: compensatedConductivityValues[] + * @details Inputs: none + * @details Outputs: condSensorStatus * @param sensorId conductivity sensor id * @return TRUE if reset successful, FALSE if not *************************************************************************/ @@ -643,11 +717,11 @@ if ( sensorId < NUM_OF_CONDUCTIVITY_SENSORS ) { - if ( isTestingActivated() ) + if ( TRUE == isTestingActivated() ) { - result = TRUE; - compensatedConductivityValues[ sensorId ].ovData = compensatedConductivityValues[ sensorId ].ovInitData; - compensatedConductivityValues[ sensorId ].override = OVERRIDE_RESET; + result = TRUE; + condSensorStatus[ sensorId ].compensatedCondValue.ovData = condSensorStatus[ sensorId ].compensatedCondValue.ovInitData; + condSensorStatus[ sensorId ].compensatedCondValue.override = OVERRIDE_RESET; } }