Index: firmware/App/Controllers/ConductivitySensors.c =================================================================== diff -u -r4bd3bf3483660050d3026f7f9adff43782bfc620 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 4bd3bf3483660050d3026f7f9adff43782bfc620) +++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -44,7 +44,6 @@ #define COND_CPO_SENSOR_PROBE_TYPE 10 ///< 0.1 K cell constant conductivity probe. #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.0F ///< Reference temperature for conductivity sensor. #define COND_SENSOR_REPORT_PERIOD ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Broadcast conductivity values message every second. @@ -145,11 +144,12 @@ 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. +static DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T condSensorsTempCompCalRecord; ///< Conductivity sensors' temperature compensation calibration record. static CAL_DATA_DG_COND_SENSORS_T condSensorCalTable[ NUM_OF_CONDUCTIVITY_SENSORS ]; ///< Conductivity sensors calibration table. // ********** private function prototypes ********** -static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature ); +static F32 calcCompensatedConductivity( U32 sensorID, F32 conductivity, F32 temperature ); static void calcRORejectionRatio( void ); static void processCPiCPoSensorRead( U32 sensorId, U08 emstatBoardSensorIndex, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault ); @@ -307,10 +307,16 @@ *************************************************************************/ SELF_TEST_STATUS_T execConductivitySensorsSelfTest( void ) { - 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 ); + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + BOOL calStatus = FALSE; + calStatus |= getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS, (U08*)&condSensorsCalRecord, sizeof( DG_COND_SENSORS_CAL_RECORD_T ), + NUM_OF_CAL_DATA_COND_SENSORS, ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD ); + calStatus |= getNVRecord2Driver( GET_CAL_CONDUCTIVITY_SENSORS_TEMP_COMP, (U08*)&condSensorsTempCompCalRecord, sizeof( DG_COND_SENSORS_TEMP_COMP_CAL_RECORD_T ), + NUM_OF_CAL_DATA_COND_SENSORS_TEMP_COMP, ALARM_ID_DG_COND_SENSORS_INVALID_TEMP_COMP_CAL_RECORD ); + + result = ( TRUE == calStatus ? SELF_TEST_STATUS_PASSED : SELF_TEST_STATUS_FAILED ); + return result; } @@ -472,14 +478,19 @@ * reference temperature of 25 degree Celsius. * @details Inputs: conductivity, temperature * @details Outputs: none + * @param sensorID the ID of the conductivity sensor * @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( U32 sensorID, F32 conductivity, F32 temperature ) { - // EC = EC_25 * (1 + temp_coef * ( temperature - 25 )) - F32 compensatedCoef = ( 1.0F + ( COND_SENSOR_TEMPERATURE_COEF * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); + F32 gain = condSensorsTempCompCalRecord.condSensorsTempComp[ (CAL_DATA_DG_COND_SENSORS_TEMP_COMP_T)sensorID ].gain; + F32 coeff = condSensorsTempCompCalRecord.condSensorsTempComp[ (CAL_DATA_DG_COND_SENSORS_TEMP_COMP_T)sensorID ].coefficient; + F32 offset = condSensorsTempCompCalRecord.condSensorsTempComp[ (CAL_DATA_DG_COND_SENSORS_TEMP_COMP_T)sensorID ].offset; + F32 compensation = ( gain * coeff ) + offset; + // EC = EC_25 * (1 + compensation * ( temperature - 25 )) + F32 compensatedCoef = ( 1.0F + ( compensation * ( temperature - COND_SENSOR_REFERENCE_TEMPERATURE ) ) ); return conductivity / compensatedCoef; } @@ -530,7 +541,7 @@ // 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 ); + F32 compensatedCond = calcCompensatedConductivity( sensorId, conductivity, temperature ); condSensorStatus[ sensorId ].readCount = fpgaReadCount; condSensorStatus[ sensorId ].internalErrorCount = 0; @@ -715,7 +726,7 @@ 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 ); + F32 compensatedCond = calcCompensatedConductivity( sensorId, conductivity, temperature ); condSensorStatus[ sensorId ].internalErrorCount = 0; condSensorStatus[ sensorId ].compensatedCondValue.data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond ); Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r4bd3bf3483660050d3026f7f9adff43782bfc620 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 4bd3bf3483660050d3026f7f9adff43782bfc620) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -359,18 +359,13 @@ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRAIN_PUMP_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif { -#ifndef _RELEASE_ - if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) -#endif + if ( dirHallSensorErrorCount != lastDirHallSensorErrorCount ) { - if ( dirHallSensorErrorCount != lastDirHallSensorErrorCount ) + if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_DRAIN_PUMP_HALL_SENSOR_ERROR ) ) { - if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_DRAIN_PUMP_HALL_SENSOR_ERROR ) ) - { - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_FPGA_FAULT, MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_FAILURES, dirHallSensorErrorCount ) - } - lastDirHallSensorErrorCount = dirHallSensorErrorCount; + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_FPGA_FAULT, MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_FAILURES, dirHallSensorErrorCount ) } + lastDirHallSensorErrorCount = dirHallSensorErrorCount; } switch( drainPumpState ) @@ -385,19 +380,13 @@ checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ), MIN_DRAIN_PUMP_RPM ); + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, FALSE, getFPGADrainPumpDirection(), DRAIN_PUMP_FORWARD_DIR ); // If the off fault alarm has become active, trigger the safety shutdown if ( TRUE == isAlarmActive( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT ) ) { activateSafetyShutdown(); } - -#ifndef _RELEASE_ - if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) -#endif - { - checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, FALSE, getFPGADrainPumpDirection(), DRAIN_PUMP_FORWARD_DIR ); - } } break; @@ -408,42 +397,26 @@ U32 rpmMaxon = getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ); BOOL isRPMOutOfRange = FALSE; U32 direction = getDrainPumpMeasuredDirection(); - BOOL isDirInvalid = ( direction != DRAIN_PUMP_FORWARD_DIR ? TRUE : FALSE ); + BOOL isDirInvalid = ( ( direction != DRAIN_PUMP_FORWARD_DIR ) && ( rpmMaxon > 0 ) ? TRUE : FALSE ); U32 rpmHallDiff = abs( getDrainPumpTargetRPM() - rpmHall ); U32 rpmMaxonDiff = abs( getDrainPumpTargetRPM() - rpmMaxon ); isRPMOutOfRange |= ( rpmHallDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); + isRPMOutOfRange |= ( rpmMaxonDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); -#ifndef _RELEASE_ - if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) -#endif - { - isRPMOutOfRange |= ( rpmMaxonDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); - } - checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, rpmHall, MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT, FALSE, rpmHall, MIN_DRAIN_PUMP_RPM ); - -#ifndef _RELEASE_ - if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) -#endif - { - checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); - } + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); } break; case DRAIN_PUMP_CONTROL_TO_TARGET_STATE: { U32 direction = getDrainPumpMeasuredDirection(); - BOOL isDirInvalid = ( direction != DRAIN_PUMP_FORWARD_DIR ? TRUE : FALSE ); + U32 rpmMaxon = getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ); + BOOL isDirInvalid = ( ( direction != DRAIN_PUMP_FORWARD_DIR ) && ( rpmMaxon > 0 ) ? TRUE : FALSE ); -#ifndef _RELEASE_ - if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) -#endif - { - checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); - } + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); } break; @@ -455,15 +428,10 @@ break; } -#ifndef _RELEASE_ - if ( getHardwareConfigStatus() != HW_CONFIG_BETA ) -#endif - { - // Check the persistent alarm for the maximum drain pump current - isCurrentOutOfRange = ( currentA > DRAIN_PUMP_MAX_CURRENT_A ? TRUE : FALSE ) | isOffCurrentOut; + // Check the persistent alarm for the maximum drain pump current + isCurrentOutOfRange = ( currentA > DRAIN_PUMP_MAX_CURRENT_A ? TRUE : FALSE ) | isOffCurrentOut; - checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, isCurrentOutOfRange, currentA, DRAIN_PUMP_MAX_CURRENT_A ); - } + checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, isCurrentOutOfRange, currentA, DRAIN_PUMP_MAX_CURRENT_A ); } // Publish drain pump data on interval Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r4bd3bf3483660050d3026f7f9adff43782bfc620 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 4bd3bf3483660050d3026f7f9adff43782bfc620) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -223,6 +223,7 @@ static void adjustTemperatureSensorsRefResistance( void ); static void checkBaroSensorCRC( void ); static void processDialTemperatureData( void ); +static void getCalibrationAppliedTemperatureValue( U32 sesnorIndex, F32* temperature ); /*********************************************************************//** * @brief @@ -388,7 +389,7 @@ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; BOOL calStatus = getNVRecord2Driver( GET_CAL_TEMP_SENSORS, (U08*)&tempSensorCalRecord, sizeof( DG_TEMP_SENSORS_CAL_RECORD_T ), - NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_NO_ALARM ); + NUM_OF_CAL_DATA_TEMP_SENSORS, ALARM_ID_DG_TEMPERATURE_SENSORS_INVALID_CAL_RECORD ); if ( TRUE == calStatus ) { @@ -873,6 +874,7 @@ break; } + getCalibrationAppliedTemperatureValue( sensorIndex, &temperature ); // Update the temperature tempSensors[ sensorIndex ].temperatureValues.data = temperature; } @@ -1197,7 +1199,72 @@ } } +/*********************************************************************//** + * @brief + * The getCalibrationAppliedTemperatureValue function applies the calibration + * values to the provided temperature value + * @details Inputs: tempSensorCalRecord + * @details Outputs: none + * @param sensorIndex Temperature sensor index + * @param temperature pointer to the calculated temperature value + * @return none + *************************************************************************/ +static void getCalibrationAppliedTemperatureValue( U32 sesnorIndex, F32* temperature ) +{ + CAL_DATA_DG_TEMP_SENSORS_T calId; + F32 tempTemperature = *temperature; + switch( sesnorIndex ) + { + case TEMPSENSORS_INLET_PRIMARY_HEATER: + calId = CAL_DATA_INLET_PRIMARY_HEATER_TEMP; + break; + + case TEMPSENSORS_OUTLET_PRIMARY_HEATER: + calId = CAL_DATA_OUTLET_PRIMARY_HEATER_TEMP; + break; + + case TEMPSENSORS_CONDUCTIVITY_SENSOR_1: + calId = CAL_DATA_COND_SENSOR_1_TEMP; + break; + + case TEMPSENSORS_CONDUCTIVITY_SENSOR_2: + calId = CAL_DATA_COND_SENSOR_2_TEMP; + break; + + case TEMPSENSORS_OUTLET_REDUNDANT: + calId = CAL_DATA_OUTLET_REDUNDANT_TEMP; + break; + + case TEMPSENSORS_INLET_DIALYSATE: + calId = CAL_DATA_INLET_DIALYSATE_TEMP; + break; + + case TEMPSENSORS_HEAT_DISINFECT: + calId = CAL_DATA_HEAT_DISINFECT_TEMP; + break; + + case TEMPSENSORS_BAROMETRIC_TEMP_SENSOR: + calId = CAL_DATA_BARMOTERIC_TEMP; + break; + + default: + // Set the calibration temperature value as num of meaning calibration is not needed for the provided sensor + calId = NUM_OF_CAL_DATA_TEMP_SENSORS; + break; + } + + if ( calId != NUM_OF_CAL_DATA_TEMP_SENSORS ) + { + *temperature = pow( tempTemperature, 4 ) * tempSensorCalRecord.tempSensors[ calId ].fourthOrderCoeff + + pow( tempTemperature, 3 ) * tempSensorCalRecord.tempSensors[ calId ].thirdOrderCoeff + + pow( tempTemperature, 2 ) * tempSensorCalRecord.tempSensors[ calId ].secondOrderCoeff + + tempTemperature * tempSensorCalRecord.tempSensors[ calId ].gain + + tempSensorCalRecord.tempSensors[ calId ].offset; + } +} + + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ Index: firmware/App/Controllers/UVReactors.c =================================================================== diff -u -r4bd3bf3483660050d3026f7f9adff43782bfc620 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision 4bd3bf3483660050d3026f7f9adff43782bfc620) +++ firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -137,10 +137,10 @@ setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); } - initPersistentAlarm( ALARM_ID_DG_INLET_UV_REACTOR_NOT_HEALTHY, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ); - initPersistentAlarm( ALARM_ID_DG_OUTLET_UV_REACTOR_NOT_HEALTHY, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ); - initPersistentAlarm( ALARM_ID_DG_INLET_UV_REACTOR_ON_WITH_NO_FLOW, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ); - initPersistentAlarm( ALARM_ID_DG_OUTLET_UV_REACTOR_ON_WITH_NO_FLOW, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_INLET_UV_REACTOR_NOT_HEALTHY, 0, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_OUTLET_UV_REACTOR_NOT_HEALTHY, 0, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_INLET_UV_REACTOR_ON_WITH_NO_FLOW, 0, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_OUTLET_UV_REACTOR_ON_WITH_NO_FLOW, 0, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ); } /*********************************************************************//** Index: firmware/App/Modes/ModeFill.c =================================================================== diff -u -re592fa77b97bb2de9c43dec6e1137b8a4ead0452 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision e592fa77b97bb2de9c43dec6e1137b8a4ead0452) +++ firmware/App/Modes/ModeFill.c (.../ModeFill.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -54,7 +54,7 @@ #define RO_PUMP_800_ML_PER_MIN 800.0F ///< RO pump speed of 800.0 mL/minute. #define TARGET_RO_FLOW_RATE_IN_PAUSE_L 0.8F ///< Target flow rate for RO pump during pause in liters. #define MILLILITERS_PER_LITER 1000.0F ///< One liter is 1000 milliliters -#define ACID_PUMP_20_ML_PER_MIN 20.0F ///< Acid pump speed of 20.0 mL/minute. +#define ACID_PUMP_23_ML_PER_MIN 23.0F ///< Acid pump speed of 23.0 mL/minute. #define BICARB_PUMP_40_ML_PER_MIN 40.0F ///< Bicarb pump speed of 40.0 mL/minute. #define CONCENTRATE_PUMP_40_ML_PER_MIN 40.0F ///< Concentrate pump speed of 40.0 mL/minute. @@ -68,6 +68,8 @@ #define FLOW_INTEGRATED_VOLUME_CHECK_TOLERANCE 0.1F ///< Flow integrated volume has 10% tolerance compare to load cell reading. #define FIVE_PERCENT_FACTOR 0.05F ///< 5.0 / 100.0 used to calculate conductivity within range of -/+ 5%. +#define BICARB_CHECK_TOL_FACTOR 0.2F ///< Bicarb check tolerance factor. +#define ACID_CHECK_TOL_FACTOR 0.1F ///< Acid check tolerance factor. #define RO_PUMP_LOOKUP_TABLE_SIZE 4 ///< Size of array used as RO pump speed lookup table. #define CONCENTRATE_PUMP_PRIME_EXTRA_SPEED_ML_MIN 5.0F ///< Concentrate pump additional speed during priming in mL/min. #define CONCENTRATE_TEST_TIME_OUT_MS ( 30 * MS_PER_SECOND ) ///< Concentrate test time out period in ms. @@ -95,6 +97,16 @@ // ********** private data ********** +/// Fill for calibration check enumeration from dialin +typedef enum dialin_fill_for_cal +{ + DIALIN_FILL_FOR_CAL_PRIME = 0, ///< Dialin fill for calibration prime. + DIALIN_FILL_FOR_CAL_BICARB_CHECK, ///< Dialin fill for calibration bicarb check. + DIALIN_FILL_FOR_CAL_ACID_CHECK, ///< Dialin fill for calibration acid check. + DIALIN_FILL_FOR_CAL_NONE, ///< Dialin fill for calibration none. + NUM_OF_DIALIN_FILL_FOR_CAL ///< Number of dialin fill for calibration. +} DIALIN_FILL_FOR_CAL_CHECK_T; + /// Fill conditions status typedef struct { @@ -156,6 +168,9 @@ // NOTE: This variable should be initialized here because the init function is called every time and then this variable is set to FALSE even if the settings from the // UI wants the RO only mode. static BOOL hasROOnlyModeBeenEnabled = FALSE; ///< Flag to indicate the RO only mode has been set or not. +// NOTE: This variable should be initialized here because the init function is called every time and then it cannot be initialized there. This variable is +// set via Dialin for calibration check purposes only +static DIALIN_FILL_FOR_CAL_CHECK_T dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; ///< Dialin fill for calibration check. static OVERRIDE_F32_T usedAcidVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated acid concentration volume has been used in mL. static OVERRIDE_F32_T usedBicarbVolumeML = { 0.0, 0.0, 0.0, 0.0 }; ///< The integrated bicarb concentration volume has been used in mL. static OVERRIDE_U32_T fillModeDataPublishInterval = { FILL_MODE_DATA_PUB_INTERVAL, @@ -614,6 +629,28 @@ { result = DG_FILL_MODE_STATE_PRODUCE_DIALYSATE; } + + if ( TRUE == isTestingActivated() ) + { + switch ( dialinFillForCalCheck ) + { + case DIALIN_FILL_FOR_CAL_PRIME: + result = DG_FILL_MODE_STATE_PRIME_CONCENTRATE_LINES; + break; + + case DIALIN_FILL_FOR_CAL_BICARB_CHECK: + result = DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY; + break; + + case DIALIN_FILL_FOR_CAL_ACID_CHECK: + result = DG_FILL_MODE_STATE_TEST_ACID_CONDUCTIVITY; + break; + + default: + // Do nothing. This means there is not a request for the fill calibration check so proceed with the normal operations. + break; + } + } setModeFillStateTransition( result ); return result; @@ -701,7 +738,7 @@ SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_BICARB_CHECK_RESULT, averageBicarbConductivity, bicarbCondUSPerCM ) - if ( TRUE == isValueWithinPercentRange( averageBicarbConductivity, bicarbCondUSPerCM, FIVE_PERCENT_FACTOR ) ) + if ( TRUE == isValueWithinPercentRange( averageBicarbConductivity, bicarbCondUSPerCM, BICARB_CHECK_TOL_FACTOR ) ) { isConductivityInRange = TRUE; } @@ -756,18 +793,19 @@ averageAcidConductivity = totalAcidConductivity / acidConductivitySampleCount; pctDiffInConductivity = fabs( 2.0F * ( averageAcidConductivity - averageBicarbConductivity ) / ( averageAcidConductivity + averageBicarbConductivity ) ); - - SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_ACID_CHECK_RESULT, averageAcidConductivity, acidCondUSPerCM ) + // NOTE: CD2 or bicarb conductivity sensor is used for acid check since it is a more accurate sensor. + // CD2 is the downstream of the acid concentrate pump so the acid sensed there. + SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_ACID_CHECK_RESULT, averageBicarbConductivity, acidCondUSPerCM ) SEND_EVENT_WITH_2_F32_DATA( DG_EVENT_COND1_VS_COND2_DIFF_RESULT, pctDiffInConductivity, 0.0F ) - if ( ( TRUE == isValueWithinPercentRange( averageAcidConductivity, acidCondUSPerCM, FIVE_PERCENT_FACTOR ) ) || + if ( ( TRUE == isValueWithinPercentRange( averageBicarbConductivity, acidCondUSPerCM, ACID_CHECK_TOL_FACTOR ) ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) ) ) { hasAcidTestPassed = TRUE; } else { - SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_ACID_CONDUCTIVITY_OUT_OF_RANGE, averageAcidConductivity, acidCondUSPerCM ) + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_ACID_CONDUCTIVITY_OUT_OF_RANGE, averageBicarbConductivity, acidCondUSPerCM ) } if ( ( pctDiffInConductivity < FIVE_PERCENT_FACTOR ) || ( TRUE == getTestConfigStatus( TEST_CONFIG_MIX_WITH_WATER ) ) ) @@ -1058,6 +1096,13 @@ pumpSpeedIndex = 0; setROPumpTargetFlowRateLPM( RO_PUMP_FLUSH_BUBBLES_FLOWS[ pumpSpeedIndex ] / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); flushBubblesStartTime = getMSTimerCount(); + if ( ( DIALIN_FILL_FOR_CAL_PRIME == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) + { + // After prime, the state transitions to flush bubbles. If the cal for check prime was set, transition to Gen Idle and + // set the fill for cal check to none. This is done upon the transition of the next state so then we can transition to Gen Idle. + dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; + requestNewOperationMode( DG_MODE_GENE ); + } break; case DG_FILL_MODE_STATE_TEST_BICARB_CONDUCTIVITY: @@ -1079,7 +1124,7 @@ requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); // Set pumps flow rate to prepare for acid conductivity testing setROPumpTargetFlowRateLPM( RO_PUMP_800_ML_PER_MIN / MILLILITERS_PER_LITER, TARGET_RO_PRESSURE_PSI ); - setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_20_ML_PER_MIN ); + setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_23_ML_PER_MIN ); requestConcentratePumpOn( CONCENTRATEPUMPS_CP1_ACID ); // Set back the conductivity of CD2 calibration table to the normal calibration table @@ -1089,6 +1134,15 @@ bicarbConductivitySampleCount = 0; acidConductivitySampleCount = 0; concentrateTestStartTime = getMSTimerCount(); + if ( ( DIALIN_FILL_FOR_CAL_BICARB_CHECK == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) + { + // After bicarb test, the state transitions to acid test. If the cal for check prime was set, transition to Gen Idle and + // set the fill for cal check to none. This is done upon the transition of the next state so then we can transition to Gen Idle. + // NOTE: If the bicarb test fails, it transitions to fault mode so it automatically exits mode fill so this is only for the situation + // that bicarb test was successful + dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; + requestNewOperationMode( DG_MODE_GENE ); + } break; case DG_FILL_MODE_STATE_PRODUCE_DIALYSATE: @@ -1098,6 +1152,15 @@ requestConcentratePumpOn( CONCENTRATEPUMPS_CP2_BICARB ); concPumpPrimeStartTimeMS = getMSTimerCount(); fillStatus.isThisFirstFill = FALSE; + if ( ( DIALIN_FILL_FOR_CAL_ACID_CHECK == dialinFillForCalCheck ) && ( TRUE == isTestingActivated() ) ) + { + // After acid test, the state transitions to acid test. If the cal for check prime was set, transition to Gen Idle and + // set the fill for cal check to none. This is done upon the transition of the next state so then we can transition to Gen Idle. + // NOTE: If the acid test fails, it transitions to fault mode so it automatically exits mode fill so this is only for the situation + // that bicarb test was successful + dialinFillForCalCheck = DIALIN_FILL_FOR_CAL_NONE; + requestNewOperationMode( DG_MODE_GENE ); + } break; case DG_FILL_MODE_STATE_DELIVER_DIALYSATE: @@ -1458,4 +1521,28 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetModeFillForCal function sets the variable to run mode fill only + * for calibration check + * @details Inputs: none + * @details Outputs: fillForCalCheck + * @param calForCheck the mode that is requested (0 = prime, 1 = bicarb check, + * 2 = acid check) + * @return TRUE if the request is in the range otherwise, FALSE + *************************************************************************/ +BOOL testSetModeFillForCal( U32 calForCheck ) +{ + BOOL result = FALSE; + + if ( ( calForCheck < NUM_OF_DIALIN_FILL_FOR_CAL ) && ( TRUE == isTestingActivated() ) ) + { + dialinFillForCalCheck = (DIALIN_FILL_FOR_CAL_CHECK_T)calForCheck; + result = TRUE; + requestNewOperationMode( DG_MODE_FILL ); + } + + return result; +} + /**@}*/ Index: firmware/App/Modes/ModeFill.h =================================================================== diff -u -r4bd3bf3483660050d3026f7f9adff43782bfc620 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 4bd3bf3483660050d3026f7f9adff43782bfc620) +++ firmware/App/Modes/ModeFill.h (.../ModeFill.h) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -91,6 +91,8 @@ BOOL testSetIntegratedVolumeOverride( F32 value ); BOOL testResetIntegratedVolumeOverride( void ); +BOOL testSetModeFillForCal( U32 calForCheck ); + /**@}*/ #endif Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -r8efe5f03a8067a68a6ca20dfb7ec1b3bfbf5a36b -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 8efe5f03a8067a68a6ca20dfb7ec1b3bfbf5a36b) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -83,7 +83,7 @@ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( DG_GEN_IDLE_MODE_STATE_T* idleState ); static void checkInvalidReservoirFill( void ); -static void publishGenIdleSubstates(); +static void publishGenIdleSubstates( void ); /*********************************************************************//** * @brief Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -r54d18d86b3947c977163f87fc9f07e6799b1f2c9 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 54d18d86b3947c977163f87fc9f07e6799b1f2c9) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -1404,6 +1404,10 @@ handleTestChemDisinfectAcidOverride( message ); break; + case MSG_ID_DG_RUN_MODE_FILL_FOR_CAL_CHECK: + handleTestRunModeFillForCalibrationCheck( message ); + break; + default: // TODO - unrecognized message ID received - ignore break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r54d18d86b3947c977163f87fc9f07e6799b1f2c9 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 54d18d86b3947c977163f87fc9f07e6799b1f2c9) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -5164,4 +5164,32 @@ // respond to request sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); } + +/*********************************************************************//** + * @brief + * The handleTestRunModeFillForCalibrationCheck function handles a request + * to run the mode fill for calibration check (0 = prime, 1 = bicarb test, + * 2 = acid test) + * @details Inputs: none + * @details Outputs: message handled + * @param message a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestRunModeFillForCalibrationCheck( MESSAGE_T* message ) +{ + BOOL result = FALSE; + + if ( sizeof(U32) == message->hdr.payloadLen ) + { + U32 modeFillForCalibrationState; + + memcpy( &modeFillForCalibrationState, message->payload, sizeof(U32) ); + + result = testSetModeFillForCal( modeFillForCalibrationState ); + } + + // respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + /**@}*/ Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r4bd3bf3483660050d3026f7f9adff43782bfc620 -r61c74b7c3a092f9e2900665f1a4f0391f78c5c03 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 4bd3bf3483660050d3026f7f9adff43782bfc620) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 61c74b7c3a092f9e2900665f1a4f0391f78c5c03) @@ -535,6 +535,9 @@ // MSG_ID_DG_CHEM_DISINFECT_ACID_OVERRIDE void handleTestChemDisinfectAcidOverride( MESSAGE_T* message ); +// MSG_ID_DG_RUN_MODE_FILL_FOR_CAL_CHECK +void handleTestRunModeFillForCalibrationCheck( MESSAGE_T* message ); + /**@}*/ #endif