Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r1e2b6058e98720e8e13d452f031af2833fcf44a5 -rfeb93744f73bc0a3d58841bb02bd05c38357f35d --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 1e2b6058e98720e8e13d452f031af2833fcf44a5) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision feb93744f73bc0a3d58841bb02bd05c38357f35d) @@ -8,16 +8,18 @@ * @file ConductivitySensors.c * * @author (last) Quang Nguyen -* @date (last) 13-Jul-2020 +* @date (last) 24-Aug-2020 * * @author (original) Quang Nguyen * @date (original) 13-Jul-2020 * ***************************************************************************/ #include "ConductivitySensors.h" -#include "SystemCommMessages.h" #include "FPGA.h" +#include "PersistentAlarm.h" +#include "SystemCommMessages.h" +#include "TaskGeneral.h" #include "TaskPriority.h" #include "TemperatureSensors.h" #include "Utilities.h" @@ -29,53 +31,100 @@ // ********** private definitions ********** -#define COND_SENSOR_PROBE_TYPE 100 ///< 1K cell constant conductivity probe -#define COND_SENSOR_DECIMAL_CONVERSION 100 ///< Conductivity value from FPGA has two decimal place -#define COND_SENSOR_TEMPERATURE_COEF 0.02 ///< 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_REPORT_PERIOD (1000 / TASK_PRIORITY_INTERVAL) ///< Broadcast conductivity values message every 1000 ms. +#define SIEMENS_TO_MICROSIEMENS_CONVERSION 1000000 ///< Siemens to microSiemens conversion factor. -#define COND_SENSOR_CPI_CPO_MAX_VALUE 2000 ///< Maximum inlet water conductivity -#define COND_SENSOR_CPI_CPO_MIN_VALUE 100 ///< Minimum inlet water conductivity +#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_TEMPERATURE_COEF 0.02 ///< 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_REPORT_PERIOD ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Broadcast conductivity values message every second. -#define MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS 100 ///< New reading every 640 ms, expect to get 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_FAILURE_WINDOW_MS (60 * MS_PER_SECOND) ///< Conductivity sensor error window +#define COND_SENSOR_CPI_CPO_MAX_VALUE 2000 ///< Maximum inlet water conductivity. +#define COND_SENSOR_CPI_CPO_MIN_VALUE 100 ///< Minimum inlet water conductivity. +#define COND_SENSOR_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for conductivity sensor out of range error. +#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_FAILURE_WINDOW_MS ( 60 * MS_PER_SECOND ) ///< Conductivity sensor error window. + +#define RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE 1.0 ///< Out of range value for RO rejection ratio when CPi conductivity is zero. +#define MAX_RO_REJECTION_RATIO_ALLOW 0.1 ///< Maximum RO rejection ratio. +#define MAX_CPO_CONDUCTIVITY_ALLOW 15.0 ///< Maximum CPo sensor conductivity value. +#define RO_REJECTION_RATIO_PERSISTENCE_PERIOD ( 10 * MS_PER_SECOND ) ///< Persistence period for RO rejection ratio. + +#define CONCENTRATE_POST_ACID_MIN_CONDUCTIVITY 11.0 ///< Minimum conductivity after adding acid. +#define CONCENTRATE_POST_ACID_MAX_CONDUCTIVITY 12.0 ///< Maximum conductivity after adding acid. + +#define CONCENTRATE_POST_BICARB_MIN_CONDUCTIVITY 13.0 ///< Minimum conductivity after adding bicarbonate. +#define CONCENTRATE_POST_BICARB_MAX_CONDUCTIVITY 14.0 ///< Maximum conductivity after adding bicarbonate. + +#define POST_ACID_CONDUCTIVITY_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for post-acid concentrate conductivity out of range. +#define POST_BICARB_CONDUCTIVITY_PERSISTENCE_PERIOD ( 5 * MS_PER_SECOND ) ///< Persistence period for post-bicarb concentrate conductivity out of range. + +#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_FIFO_EMPTY_MASK 0x8000 ///< Emstat Pico buffer empty indication bit. + +#pragma pack(push,1) +/// Emstat pico measurement data package structure +typedef struct +{ + U16 type; ///< Measurement variable type + U08 value[7]; ///< Measurement value + U08 prefix; ///< Prefix character for SI prefixes + U08 reserved1; ///< Comma separator + U16 status; ///< Status for measurement data package + U08 reserved2[4]; ///< Comma separator and index of current range +} EMSTAT_VARIABLE_T; +#pragma pack(pop) + // ********** private data ********** /// Conductivity sensors' associated temperature sensors -static U32 associateTempSensor[ NUM_OF_CONDUCTIVITY_SENSORS ] = { - TEMPSENSORS_INLET_PRIMARY_HEATER_TEMP_SENSOR, ///< Inlet temperature sensor - TEMPSENSORS_OUTLET_PRIMARY_HEATER_TEMP_SENSOR, ///< Outlet temperature sensor +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 }; -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 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 roRejectionRatio; ///< Latest RO rejection ratio. static OVERRIDE_U32_T conductivityDataPublishInterval = { COND_SENSOR_REPORT_PERIOD, - COND_SENSOR_REPORT_PERIOD, 0, 0 }; ///< Conductivity sensors publish time interval override -static U32 conductivityDataPublicationTimerCounter = 0; ///< Conductivity sensors data publish timer counter + COND_SENSOR_REPORT_PERIOD, 0, 0 }; ///< Conductivity sensors publish time interval override. +static U32 conductivityDataPublicationTimerCounter = 0; ///< Conductivity sensors data publish timer counter. +static BOOL packageStarted = FALSE; ///< Flag to indicate the start of a package measurement data. +static U08 packageIndex = 0U; ///< Current package measurement data bytes index. +static U08 package[ 50 ]; ///< Storage of package bytes until ready to process. + // ********** private function prototypes ********** -static void processCPiCPoSensorRead( U32 sensorId, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount ); 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 DATA_GET_PROTOTYPE( U32, getConductivityDataPublishInterval ); +static U32 prefixStrToSIFactor( U08 prefix ); +static void processMeasurementDataPackage( U32 sensorId ); +static void processCD1CD2SensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ); +static U32 getConductivityDataPublishInterval( void ); -/************************************************************************* +/*********************************************************************//** * @brief * The initConductivitySensors function initializes the ConductivitySensors module. - * @details - * Inputs : none - * Outputs : ConductivitySensors module initialized + * @details Inputs: none + * @details Outputs: ConductivitySensors module initialized * @return none *************************************************************************/ void initConductivitySensors( void ) { U32 i; + roRejectionRatio = 0.0; for ( i = 0; i < NUM_OF_CONDUCTIVITY_SENSORS; i++ ) { @@ -86,74 +135,128 @@ compensatedConductivityValues[ i ].ovData = 0.0; compensatedConductivityValues[ i ].ovInitData = 0.0; compensatedConductivityValues[ i ].override = OVERRIDE_RESET; - - // TODO: Ability to change probe type -// setFPGAConductivityProbeType( COND_SENSOR_PROBE_TYPE ); } - initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR, - MAX_CONDUCTIVITY_SENSOR_FAILURES, MAX_CONDUCTIVITY_SENSOR_FAILURE_WINDOW_MS ); + 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( PERSISTENT_ALARM_INLET_WATER_HIGH_CONDUCTIVITY, ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY, + FALSE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); + initPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_LOW_CONDUCTIVITY, ALARM_ID_INLET_WATER_LOW_CONDUCTIVITY, + FALSE, COND_SENSOR_PERSISTENCE_PERIOD, COND_SENSOR_PERSISTENCE_PERIOD ); + initPersistentAlarm( PERSISTENT_ALARM_RO_REJECTION_RATIO_OUT_OF_RANGE, ALARM_ID_RO_REJECTION_RATIO_OUT_OF_RANGE, + FALSE, RO_REJECTION_RATIO_PERSISTENCE_PERIOD, RO_REJECTION_RATIO_PERSISTENCE_PERIOD ); + initPersistentAlarm( PERSISTENT_ALARM_POST_ACID_CONDUCTIVITY_OUT_OF_RANGE, ALARM_ID_POST_ACID_CONDUCTIVITY_OUT_OF_RANGE, + TRUE, POST_ACID_CONDUCTIVITY_PERSISTENCE_PERIOD, POST_ACID_CONDUCTIVITY_PERSISTENCE_PERIOD ); + initPersistentAlarm( PERSISTENT_ALARM_POST_BICARB_CONDUCTIVITY_OUT_OF_RANGE, ALARM_ID_POST_BICARB_CONDUCTIVITY_OUT_OF_RANGE, + TRUE, POST_ACID_CONDUCTIVITY_PERSISTENCE_PERIOD, POST_ACID_CONDUCTIVITY_PERSISTENCE_PERIOD ); } -/************************************************************************* +/*********************************************************************//** * @brief * The execConductivitySensors function gets conductivity sensors' latest * readings from FPGA and advertises them over CAN. - * @details - * Inputs : none - * Outputs : Conductivity sensors' latest reading is updated and advertised. + * @details Inputs: none + * @details Outputs: Conductivity sensors' latest reading is updated and advertised. * @return none *************************************************************************/ void execConductivitySensors( void ) { - processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount() ); - processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPO_SENSOR, getFPGACPi(), getFPGACPoReadCount(), getFPGACPoErrorCount() ); + processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount(), getFPGACPiFault() ); + processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPO_SENSOR, getFPGACPo(), getFPGACPoReadCount(), getFPGACPoErrorCount(), getFPGACPoFault() ); + processCD1CD2SensorRead( getFPGAEmstatRxFifoCount(), getFPGAEmstatRxErrCount() ); if ( ++conductivityDataPublicationTimerCounter >= getConductivityDataPublishInterval() ) { + CONDUCTIVITY_DATA_T data; + + calcRORejectionRatio(); + conductivityDataPublicationTimerCounter = 0; - broadcastConductivityData( getConductivityValue(CONDUCTIVITYSENSORS_CPI_SENSOR), - getConductivityValue(CONDUCTIVITYSENSORS_CPO_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 ); + + broadcastConductivityData( &data ); } + } -/************************************************************************* +/*********************************************************************//** * @brief - * The checkInletWaterConductivity checks inlet water conductivity value + * The checkInletWaterConductivity function checks inlet water conductivity value * and triggers an alarm when conductivity value is out of allowed range. - * @details - * Inputs : none - * Outputs : Trigger alarms when conductivity is out of allowed range - * @param state : Operational state of DG + * @details Inputs: CPi sensor conductivity + * @details Outputs: Trigger alarms when conductivity is out of allowed range * @return none *************************************************************************/ -void checkInletWaterConductivity( U32 state ) +void checkInletWaterConductivity( void ) { - F32 const conductivity = getConductivityValue(CONDUCTIVITYSENSORS_CPI_SENSOR); - if ( conductivity > COND_SENSOR_CPI_CPO_MAX_VALUE ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_INLET_WATER_HIGH_CONDUCTIVITY, conductivity, state ); - } + F32 const conductivity = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + BOOL const isCondTooHigh = ( conductivity > COND_SENSOR_CPI_CPO_MAX_VALUE ); + BOOL const isCondTooLow = ( conductivity < COND_SENSOR_CPI_CPO_MIN_VALUE ); - if ( conductivity < COND_SENSOR_CPI_CPO_MIN_VALUE ) - { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_INLET_WATER_LOW_CONDUCTIVITY, conductivity, state ); - } + // TODO add the right limit values + checkPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_HIGH_CONDUCTIVITY, isCondTooHigh, conductivity, 0 ); + checkPersistentAlarm( PERSISTENT_ALARM_INLET_WATER_LOW_CONDUCTIVITY, isCondTooLow, conductivity, 0 ); } -/************************************************************************* +/*********************************************************************//** * @brief + * The checkRORejectionRatio function checks RO rejection ratio and outlet water + * conductivity. The function triggers an alarm when RO rejection ratio or + * outlet water conductivity is out of allowed range for period of time. + * @details Inputs: roRejectionRatio, CPo sensor conductivity + * @details Outputs: Triggered alarm + * @return none + *************************************************************************/ +void checkRORejectionRatio( void ) +{ +#ifndef DISABLE_DIALYSATE_CHECK + F32 const cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + BOOL const isRORejectionRatioOutOfRange = ( roRejectionRatio > MAX_RO_REJECTION_RATIO_ALLOW ) || ( cpo >= MAX_CPO_CONDUCTIVITY_ALLOW ); + + // TODO add the right limit values + checkPersistentAlarm( PERSISTENT_ALARM_RO_REJECTION_RATIO_OUT_OF_RANGE, isRORejectionRatioOutOfRange, roRejectionRatio, 0 ); +#endif +} + +/*********************************************************************//** + * @brief + * The checkConcentrateConductivity function checks concentrate conductivity + * after adding acid and bicarbonate and triggers an alarm when conductivity + * is out of allowed range. + * @details Inputs: CD1 and CD2 sensor conductivity + * @details Outputs: Trigger alarms when conductivity is out of allowed range + * @return none + *************************************************************************/ +void checkConcentrateConductivity( void ) +{ + F32 const postAcidConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD1_SENSOR ); + F32 const postBicarbonateConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR ); + BOOL const isPostAcidConductivityOutOfRange = ( postAcidConductivity <= CONCENTRATE_POST_ACID_MIN_CONDUCTIVITY ) || ( postAcidConductivity >= CONCENTRATE_POST_ACID_MAX_CONDUCTIVITY ); + BOOL const isPostBicarbConductivityOutOfRange = ( postBicarbonateConductivity <= CONCENTRATE_POST_BICARB_MIN_CONDUCTIVITY ) || ( postBicarbonateConductivity >= CONCENTRATE_POST_BICARB_MAX_CONDUCTIVITY ); + + // TODO add the right limit values + checkPersistentAlarm( PERSISTENT_ALARM_POST_ACID_CONDUCTIVITY_OUT_OF_RANGE, isPostAcidConductivityOutOfRange, postAcidConductivity, 0 ); + checkPersistentAlarm( PERSISTENT_ALARM_POST_BICARB_CONDUCTIVITY_OUT_OF_RANGE, isPostBicarbConductivityOutOfRange, postBicarbonateConductivity, 0 ); +} + +/*********************************************************************//** + * @brief * The getConductivityValue function gets the compensated conductivity * value for a given conductivity sensor id. - * @details - * Inputs : compensatedConductivityValues[] - * Outputs : none - * @param sensorId : Id of conductivity sensor to get conductivity value + * @details Inputs: compensatedConductivityValues[] + * @details Outputs: none + * @param sensorId conductivity sensor id * @return compensated conductivity *************************************************************************/ F32 getConductivityValue( U32 sensorId ) { - F32 result = 0; + F32 result = 0.0; if ( sensorId < NUM_OF_CONDUCTIVITY_SENSORS ) { @@ -174,45 +277,65 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The calcCompensatedConductivity function calculates the compensated * conductivity based on given temperature and conductivity taken at * reference temperature of 25 Celcius. - * @details - * Inputs : temperature - * Outputs : none - * @param conductivity : Conductivity value - * @param temperature : Temperature to compensate conductivity with + * @details Inputs: conductivity, temperature + * @details Outputs: none + * @param conductivity conductivity value + * @param temperature temperature to compensate conductivity with * @return compensated conductivity based on temperature *************************************************************************/ -static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature) +static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ) { // EC = EC_25 * (1 + temp_coef * (temperature - 25)) - F32 const compensatedCoef = ( 1 + ( COND_SENSOR_TEMPERATURE_COEF * (temperature - COND_SENSOR_REFERENCE_TEMPERATURE) ) ); + F32 const compensatedCoef = ( 1.0 + ( COND_SENSOR_TEMPERATURE_COEF * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); return conductivity * compensatedCoef; } -/************************************************************************* +/*********************************************************************//** * @brief + * The calcRORejectionRatio function calculates the RO rejection ratio using + * the CPi sensor conductivity value and CPo sensor conductivity value. + * @details Inputs: CPi sensor conductivity, CPo sensor conductivity + * @details Outputs: RO rejection ratio + * @return none + *************************************************************************/ +static void calcRORejectionRatio( void ) +{ + F32 const cpi = getConductivityValue( CONDUCTIVITYSENSORS_CPI_SENSOR ); + F32 const cpo = getConductivityValue( CONDUCTIVITYSENSORS_CPO_SENSOR ); + + roRejectionRatio = RO_REJECTION_RATIO_OUT_OF_RANGE_VALUE; + + if ( fabs(cpi) >= NEARLY_ZERO ) + { + roRejectionRatio = cpo / cpi; + } +} + +/*********************************************************************//** + * @brief * The processCPiCPoSensorRead function checks if there is an error in FPGA * and FPGA read count. If there is any error in the FPGA error, it raises an * alarm. If the read count has changed, the new reading will be processed. - * @details - * Inputs : none - * Outputs : none - * @param sensorId : Conductivity sensor id to process - * @param fgpaRead : FPGA conductivity reading value - * @param fpgaReadCount : FPGA read count - * @param fpgaErrorCount : FPGA error count + * @details Inputs: none + * @details Outputs: none + * @param sensorId Conductivity sensor id to process + * @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 ) +static void processCPiCPoSensorRead( U32 sensorId, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ) { - if ( fpgaErrorCount == 0 ) + if ( ( fpgaErrorCount == 0 ) && ( fpgaSensorFault == 0 ) ) { - if ( (readCount[ sensorId ] != fpgaReadCount) ) + if ( ( readCount[ sensorId ] != fpgaReadCount ) ) { F32 const temperature = getTemperatureValue( associateTempSensor[ sensorId ] ); F32 const conductivity = ( (F32)( fgpaRead ) / COND_SENSOR_DECIMAL_CONVERSION ); @@ -238,13 +361,136 @@ } } -/************************************************************************* +/*********************************************************************//** * @brief + * The prefixStrToSIFactor function returns SI factor based on a given ascii prefix. + * @details Inputs: none + * @details Outputs: none + * @param prefix ascii value of the prefix + * @return SI factor of the given ascii prefix + *************************************************************************/ +static U32 prefixStrToSIFactor( U08 prefix ) +{ + U32 result; + + switch ( prefix ) + { + case 'm': + result = 1000; + break; + + case 'u': + result = 1000000; + break; + + default: + result = 1; + break; + } + + return result; +} + +/*********************************************************************//** + * @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 + * @return none + *************************************************************************/ +static void processMeasurementDataPackage( U32 sensorId ) +{ + EMSTAT_VARIABLE_T const * const measurementPtr = (EMSTAT_VARIABLE_T *)&package; + + if ( EMSTAT_PICO_GOOD_STATUS == hexStrToDec( (U08 *)&measurementPtr->status, sizeof( measurementPtr->status ) ) ) + { + U32 const prefix = prefixStrToSIFactor( measurementPtr->prefix ); + F32 const resistance = ( ( F32 )( hexStrToDec( measurementPtr->value, sizeof( measurementPtr->value ) ) - EMSTAT_PICO_MEASUREMENT_OFFSET ) / prefix ); + F32 const temperature = getTemperatureValue( associateTempSensor[ sensorId ] ); + F32 const conductivity = ( 1 / resistance * SIEMENS_TO_MICROSIEMENS_CONVERSION ); + + internalErrorCount[ sensorId ] = 0; + compensatedConductivityValues[ sensorId ].data = calcCompensatedConductivity( conductivity, temperature ); + } + else + { + ++internalErrorCount[ sensorId ]; + if ( internalErrorCount[ sensorId ] > MAX_ALLOWED_UNCHANGED_CONDUCTIVITY_READS ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, sensorId ); + } + } +} + +/*********************************************************************//** + * @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. + * @details Inputs: none + * @details Outputs: none + * @param fpgaReadCount FPGA read count for rx fifo + * @param fpgaErrorCount FPGA error count + * @return none + *************************************************************************/ +static void processCD1CD2SensorRead( U16 fpgaReadCount, U08 fpgaErrorCount ) +{ + if ( fpgaErrorCount == 0 ) + { + if ( ( fpgaReadCount > 0 ) && ( ( fpgaReadCount & EMSTAT_PICO_FIFO_EMPTY_MASK ) == 0 ) ) + { + U08 const emstatByte = getFPGAEmstatOutByte(); + + switch ( emstatByte ) + { + case 'P': + packageStarted = TRUE; + packageIndex = 0; + break; + + case ';': + if ( packageStarted ) + { + processMeasurementDataPackage( CONDUCTIVITYSENSORS_CD1_SENSOR ); + packageIndex = 0; + } + break; + + case '\n': + if ( packageStarted ) + { + processMeasurementDataPackage( CONDUCTIVITYSENSORS_CD2_SENSOR ); + packageStarted = FALSE; + } + break; + + default: + if ( packageStarted ) + { + package[ packageIndex++ ] = emstatByte; + } + break; + } + } + } + else + { + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_CONDUCTIVITY_SENSOR_ERROR ) ) + { + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_CONDUCTIVITY_SENSOR_FAULT, CONDUCTIVITYSENSORS_CD1_SENSOR ); + } + } +} + +/*********************************************************************//** + * @brief * The getConductivityDataPublishInterval function gets the conductivity * data publication interval. - * @details - * Inputs : conductivityDataPublishInterval - * Outputs : none + * @details Inputs: conductivityDataPublishInterval + * @details Outputs: none * @return the current conductivity data publication interval (in ms/task interval). *************************************************************************/ static U32 getConductivityDataPublishInterval( void ) @@ -265,15 +511,14 @@ *************************************************************************/ -/************************************************************************* +/*********************************************************************//** * @brief * The testSetConductivityOverride function overrides the compensated * conductivity value of given sensor id. - * @details - * Inputs : compensatedConductivityValues[] - * Outputs : compensatedConductivityValues[] - * @param sensorId : Id of conductivity sensor to get conductivity value - * @param value : override compensated conductivity value + * @details Inputs: compensatedConductivityValues[] + * @details Outputs: compensatedConductivityValues[] + * @param sensorId conductivity sensor id + * @param value override compensated conductivity value * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetConductivityOverride( U32 sensorId, F32 value ) @@ -293,14 +538,13 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief - * The testResetConductivityOverride function resets the override of the \n + * The testResetConductivityOverride function resets the override of the * conductivity sensor value. - * @details - * Inputs : compensatedConductivityValues[] - * Outputs : compensatedConductivityValues[] - * @param sensorId : Id of the conductivity sensor to override. + * @details Inputs: compensatedConductivityValues[] + * @details Outputs: compensatedConductivityValues[] + * @param sensorId conductivity sensor id * @return TRUE if reset successful, FALSE if not *************************************************************************/ BOOL testResetConductivityOverride( U32 sensorId ) @@ -320,14 +564,13 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testSetConductivityDataPublishIntervalOverride function overrides * the conductivity data publish interval. - * @details - * Inputs : conductivityDataPublishInterval - * Outputs : conductivityDataPublishInterval - * @param value : override conductivity data publish interval with (in ms) + * @details Inputs: conductivityDataPublishInterval + * @details Outputs: conductivityDataPublishInterval + * @param value override conductivity data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetConductivityDataPublishIntervalOverride( U32 interval_ms ) @@ -344,13 +587,12 @@ return result; } -/************************************************************************* +/*********************************************************************//** * @brief * The testResetConductivityDataPublishIntervalOverride function resets * the override of the conductivity data publish interval. - * @details - * Inputs : conductivityDataPublishInterval - * Outputs : conductivityDataPublishInterval + * @details Inputs: conductivityDataPublishInterval + * @details Outputs: conductivityDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetConductivityDataPublishIntervalOverride( void )