Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r224b86c0847207c168d38fa1713a1e9116642267 -r0d94694b64f936805dd6c2f71fde1840bc9c1311 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 224b86c0847207c168d38fa1713a1e9116642267) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 0d94694b64f936805dd6c2f71fde1840bc9c1311) @@ -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" @@ -65,6 +66,13 @@ #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_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 EMSTAT_BOARD_CD1_INDEX 0 ///< Emstat board CD1 index number. +#define EMSTAT_BOARD_CD2_INDEX 1 ///< Emstat board CD2 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. @@ -80,33 +88,46 @@ U08 reserved2[4]; ///< Comma separator and index of current range } EMSTAT_VARIABLE_T; +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 ]; + CONDUCTIVITY_SENSORS_T condSnsr1; ///< Emstat conductivity sensor 1 on the board. + TEMPERATURE_SENSORS_T condSnsr1TempSnsr; ///< Emstat conductivity sensor 1 temperature sensor. + CONDUCTIVITY_SENSORS_T condSnsr2; ///< Emstat conductivity sensor 2 on the board. + TEMPERATURE_SENSORS_T condSnsr2TempSnsr; ///< Emstat conductivity sensor 21 temperature sensor. + U16 fpgaPreviousCount; ///< Emstat FPGA previous count. + U08 fpgaInitialErrorCount; ///< Emstat FPGA initial error count. } EMSTAT_READ_T; #pragma pack(pop) +// ********** private data ********** + /// Emstat boards for CPi/CPo and CD1/CD2 typedef enum EmstatBoards { - CPI_CPO_EMSTAT_BOARD = 0, ///< Emstat CPi/CPo board. - CD1_CD2_EMSTAT_BOARD, ///< Emstat CD1/CD2 board. + 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; -// ********** private data ********** - /// Conductivity sensors' associated temperature sensors static U32 associateTempSensor[ NUM_OF_CONDUCTIVITY_SENSORS ] = { 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 -}; +}; // TODO remove 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. @@ -116,7 +137,7 @@ 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 U32 conductivityDataPublishCounter; ///< Conductivity sensors data publish timer counter. static EMSTAT_READ_T emstatBoardRead[ NUM_OF_EMSTAT_BOARDS ]; ///< EMSTAT board read. static BOOL packageStarted; ///< Flag to indicate the start of a package measurement data. @@ -136,9 +157,13 @@ static void processCPiCPoSensorRead( U32 sensorId, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ); static U32 prefixStrToSIFactor( U08 prefix ); -static void processMeasurementDataPackage( U32 sensorId ); -static void processCD1CD2EmstatSensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ); -static void processEmstatSensorRead( CONDUCTIVITY_SENSORS_T sensor, U16 fpgaReadCount, U08 fpgaErrorCount ); +static void processMeasurementDataPackage( U32 sensorId ); // TODO remove +static void processCD1CD2EmstatSensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ); // TODO remove +static void processNewEmstatSensorRead( CONDUCTIVITY_SENSORS_T sensor, U16 fpgaReadCount, U08 fpgaErrorCount ); // TODO remove + +static void processEmstatBoard( EMSTAT_BOARD_T board ); +static void processEmstatSensorRead( EMSTAT_READ_T* readPackage, U08 emstatByte, U16 fpgaReadCount, U08 fpgaErrorCount ); +static void processEmstatMeasurementDataPackage( U08 boardSensorIndex, EMSTAT_READ_T* readPackage, EMSTAT_VARIABLE_T* receivedPackage ); static F32 getCalibrationAppliedConductivityValue( U32 sensorId, F32 compensatedValue ); /*********************************************************************//** @@ -151,10 +176,10 @@ void initConductivitySensors( void ) { U08 i; - roRejectionRatio = 0.0; - packageIndex = 0U; - packageStarted = FALSE; - conductivityDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; + roRejectionRatio = 0.0; + packageIndex = 0U; + packageStarted = FALSE; + conductivityDataPublishCounter = DATA_PUBLISH_COUNTER_START_COUNT; for ( i = 0; i < NUM_OF_CONDUCTIVITY_SENSORS; i++ ) { @@ -168,11 +193,37 @@ 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; + + // Each Emstat board covers two conductivity sensors + // CPi/CPo Emstat board conductivity sensors and their corresponding temperature sensors + emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].condSnsr1 = CONDUCTIVITYSENSORS_CPI_SENSOR; + emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].condSnsr1TempSnsr = TEMPSENSORS_INLET_PRIMARY_HEATER; + emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].condSnsr2 = CONDUCTIVITYSENSORS_CPO_SENSOR; + emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ].condSnsr2TempSnsr = TEMPSENSORS_OUTLET_PRIMARY_HEATER; + + // CD1/CD2 Emstat board conductivity sensors and their corresponding temperature sensors + emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].condSnsr1 = CONDUCTIVITYSENSORS_CD1_SENSOR; + emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].condSnsr1TempSnsr = TEMPSENSORS_CONDUCTIVITY_SENSOR_1; + emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].condSnsr2 = CONDUCTIVITYSENSORS_CD2_SENSOR; + emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ].condSnsr2TempSnsr = TEMPSENSORS_CONDUCTIVITY_SENSOR_2; + setFPGACPiProbeType( COND_CPI_SENSOR_PROBE_TYPE ); // TODO can we leave this here? setFPGACPoProbeType( COND_CPO_SENSOR_PROBE_TYPE ); // TODO can we leave this here? @@ -205,17 +256,19 @@ processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount(), getFPGACPiFault() ); processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPO_SENSOR, getFPGACPo(), getFPGACPoReadCount(), getFPGACPoErrorCount(), getFPGACPoFault() ); #endif - processCD1CD2EmstatSensorRead( getFPGAEmstatRxFifoCount(), getFPGAEmstatRxErrCount() ); - processEmstatSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGAEmstatCPiCPoRxFifoCount(), getFPGAEmstatCPiCPoRxErrCount() ); // TODO can this be replacing the top function? + processCD1CD2EmstatSensorRead( getFPGAEmstatCD1CD2RxFifoCount(), getFPGAEmstatCD1CD2RxErrCount() ); + //processCD1CD2EmstatSensorRead( getFPGAEmstatCPiCPoRxFifoCount(), getFPGAEmstatCPiCPoRxErrCount() ); + //processNewEmstatSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGAEmstatCD1CD2RxFifoCount(), getFPGAEmstatCPiCPoRxErrCount() ); // TODO can this be replacing the top function? + processNewEmstatSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGAEmstatCPiCPoRxFifoCount(), getFPGAEmstatCPiCPoRxErrCount() ); - if ( ++conductivityDataPublicationTimerCounter >= getU32OverrideValue( &conductivityDataPublishInterval ) ) + if ( ++conductivityDataPublishCounter >= getU32OverrideValue( &conductivityDataPublishInterval ) ) { CONDUCTIVITY_DATA_T data; calcRORejectionRatio(); - conductivityDataPublicationTimerCounter = 0; - data.roRejectionRatio = roRejectionRatio; + conductivityDataPublishCounter = 0; + data.roRejectionRatio = roRejectionRatio; data.cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); data.cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); @@ -362,7 +415,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; } @@ -603,7 +656,7 @@ } } -static void processEmstatSensorRead( CONDUCTIVITY_SENSORS_T sensor, U16 fpgaReadCount, U08 fpgaErrorCount ) +static void processNewEmstatSensorRead( CONDUCTIVITY_SENSORS_T sensor, U16 fpgaReadCount, U08 fpgaErrorCount ) { if ( 0 == fpgaErrorCount ) { @@ -645,6 +698,129 @@ } } +static void processEmstatBoard( EMSTAT_BOARD_T board ) +{ + U08 emstatByte = 0; + U08 fpgaErrorCount = 0; + U16 fpgaReadCount = 0; + + switch ( board ) + { + case EMSTAT_CPI_CPO_BOARD: + emstatByte = getFPGAEmstatCPiCPoByteOut(); + fpgaErrorCount = getFPGAEmstatCPiCPoRxErrCount(); + fpgaReadCount = getFPGAEmstatCPiCPoRxFifoCount(); + processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CPI_CPO_BOARD ], emstatByte, fpgaReadCount, fpgaErrorCount ); + break; + + case EMSTAT_CD1_CD2_BOARD: + emstatByte = getFPGAEmstatCD1CD2OutByte(); + fpgaErrorCount = getFPGAEmstatCD1CD2RxErrCount(); + fpgaReadCount = getFPGAEmstatCD1CD2RxFifoCount(); + processEmstatSensorRead( &emstatBoardRead[ EMSTAT_CD1_CD2_BOARD ], emstatByte, fpgaReadCount, fpgaErrorCount ); + break; + + default: + // Do nothing + // Software fault? + break; + } +} + +static void processEmstatSensorRead( EMSTAT_READ_T* readPackage, U08 emstatByte, U16 fpgaReadCount, U08 fpgaErrorCount ) +{ + switch ( emstatByte ) + { + case 'P': + readPackage->packageStarted = TRUE; + readPackage->packageIndex = 0; + break; + + case ';': + if ( TRUE == readPackage->packageStarted ) + { + processEmstatMeasurementDataPackage( EMSTAT_CPI_OR_CD1_INDEX, readPackage, (EMSTAT_VARIABLE_T*)readPackage->package ); + readPackage->packageIndex = 0; + } + break; + + case '\n': + if ( TRUE == readPackage->packageStarted ) + { + processEmstatMeasurementDataPackage( EMSTAT_CPO_OR_CD2_INDEX, readPackage, (EMSTAT_VARIABLE_T*)readPackage->package ); + readPackage->packageStarted = FALSE; + } + break; + + default: + if ( TRUE == readPackage->packageStarted ) + { + readPackage->package[ readPackage->packageIndex++ ] = emstatByte; + } + break; + } + + if ( getCurrentOperationMode() != DG_MODE_INIT ) + { + if ( ( fpgaReadCount != readPackage->fpgaPreviousCount ) && ( 0 == ( fpgaReadCount & EMSTAT_PICO_FIFO_EMPTY_MASK ) ) && + ( fpgaErrorCount != readPackage->fpgaInitialErrorCount ) ) + { + readPackage->fpgaPreviousCount = fpgaReadCount; + } + else if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR ) ) + { +#ifndef _RELEASE_ + if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_COND_SENSOR_CHECK ) != SW_CONFIG_ENABLE_VALUE ) +#endif + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, CONDUCTIVITYSENSORS_CD1_SENSOR, CONDUCTIVITYSENSORS_CD2_SENSOR ); + } + } + } +} + +static void processEmstatMeasurementDataPackage( U08 boardSensorIndex, EMSTAT_READ_T* readPackage, EMSTAT_VARIABLE_T* receivedPackage ) +{ + CONDUCTIVITY_SENSORS_T sensorId = readPackage->sensors[ boardSensorIndex ].condSnsr; + sensorStatus[ sensorId ] = hexStrToDec( (U08*)&receivedPackage->status, sizeof( receivedPackage->status ) ); + BOOL isSensorStatusGood = EMSTAT_PICO_GOOD_STATUS == sensorStatus[ sensorId ]; + + if ( EMSTAT_PICO_GOOD_STATUS == sensorStatus[ sensorId ] ) + { + U32 prefix = prefixStrToSIFactor( receivedPackage->prefix ); + F32 resistance = ( ( F32 )( hexStrToDec( receivedPackage->value, sizeof( receivedPackage->value ) ) - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); + //F32 temperature = getTemperatureValue( associateTempSensor[ sensorId ] ); // TODO remove + F32 temperature = getTemperatureValue( readPackage->sensors[ boardSensorIndex ].condSnsrTempSnsr ); + F32 conductivity = ( 1.0 / resistance * SIEMENS_TO_MICROSIEMENS_CONVERSION ); + F32 compensatedCond = calcCompensatedConductivity( conductivity, temperature ); + + internalErrorCount[ sensorId ] = 0; + compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); + rawConductivityValues[ sensorId ] = conductivity; + + // Clear the alarm + checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, FALSE, sensorStatus[ sensorId ], EMSTAT_PICO_GOOD_STATUS ); + } + else + { +#ifndef DISABLE_COND_STATUS_CHECK + checkPersistentAlarm( ALARM_ID_DG_CONDUCTIVITY_SENSOR_BAD_STATUS, TRUE, sensorStatus[ sensorId ], EMSTAT_PICO_GOOD_STATUS ); +#endif + } + + if ( EMSTAT_PICO_TIMING_NOT_MET_STATUS == sensorStatus[ sensorId ] ) + { + 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 getCalibrationAppliedConductivityValue function gets the temperature