Index: firmware/.launches/DG.launch
===================================================================
diff -u -rf3aae110ab3efde68897d0224f799dc039ac84f5 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/.launches/DG.launch (.../DG.launch) (revision f3aae110ab3efde68897d0224f799dc039ac84f5)
+++ firmware/.launches/DG.launch (.../DG.launch) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -1,5 +1,11 @@
+
+
+
+
+
+
@@ -17,4 +23,5 @@
+
Index: firmware/App/Controllers/ConductivitySensors.c
===================================================================
diff -u -r5adaa0ae1236d34fca1fc8def7fa107ec470115e -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision 5adaa0ae1236d34fca1fc8def7fa107ec470115e)
+++ firmware/App/Controllers/ConductivitySensors.c (.../ConductivitySensors.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -14,6 +14,7 @@
* @date (original) 13-Jul-2020
*
***************************************************************************/
+#include // Used for calculating the polynomial calibration equation.
#include "ConductivitySensors.h"
#include "FPGA.h"
@@ -106,17 +107,20 @@
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.
+static DG_COND_SENSORS_CAL_RECORD_T condSensorsCalRecord; ///< Conductivity sensors' calibration record.
// ********** private function prototypes **********
-static F32 calcCompensatedConductivity( F32 conductivity, F32 temperature);
+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 U32 prefixStrToSIFactor( U08 prefix );
static void processMeasurementDataPackage( U32 sensorId );
static void processCD1CD2SensorRead( U16 fpgaReadCount, U08 fpgaErrorCount );
static U32 getConductivityDataPublishInterval( void );
+static BOOL processCalibrationData( void );
+static F32 getCalibrationAppliedConductivityValue( U32 sensorId, F32 compensatedValue );
/*********************************************************************//**
* @brief
@@ -155,11 +159,19 @@
* The execConductivitySensors function gets conductivity sensors' latest
* readings from FPGA and advertises them over CAN.
* @details Inputs: none
- * @details Outputs: Conductivity sensors' latest reading is updated and advertised.
+ * @details Outputs: Conductivity sensors' latest reading is updated and
+ * advertised.
* @return none
*************************************************************************/
void execConductivitySensors( void )
{
+ // Check if a new calibration is available
+ if ( TRUE == isNewCalibrationRecordAvailable() )
+ {
+ // Get the new calibration data and check its validity
+ processCalibrationData();
+ }
+
processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPI_SENSOR, getFPGACPi(), getFPGACPiReadCount(), getFPGACPiErrorCount(), getFPGACPiFault() );
processCPiCPoSensorRead( CONDUCTIVITYSENSORS_CPO_SENSOR, getFPGACPo(), getFPGACPoReadCount(), getFPGACPoErrorCount(), getFPGACPoFault() );
processCD1CD2SensorRead( getFPGAEmstatRxFifoCount(), getFPGAEmstatRxErrCount() );
@@ -179,7 +191,32 @@
broadcastConductivityData( &data );
}
+}
+/*********************************************************************//**
+ * @brief
+ * The execConductivitySensorsSelfTest function executes the conductivity
+ * sensors' self-test.
+ * @details Inputs: none
+ * @details Outputs: none
+ * @return PressuresSelfTestResult (SELF_TEST_STATUS_T)
+ *************************************************************************/
+SELF_TEST_STATUS_T execConductivitySensorsSelfTest( void )
+{
+ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS;
+
+ BOOL calStatus = processCalibrationData();
+
+ if ( TRUE == calStatus )
+ {
+ result = SELF_TEST_STATUS_PASSED;
+ }
+ else
+ {
+ result = SELF_TEST_STATUS_FAILED;
+ }
+
+ return result;
}
/*********************************************************************//**
@@ -264,7 +301,8 @@
BOOL isDialysateConductivityInRange( void )
{
F32 const bicarbConductivity = getConductivityValue( CONDUCTIVITYSENSORS_CD2_SENSOR );
- BOOL const isConductivityInRange = isAcidConductivityInRange() && ( MIN_DIALYSATE_CONDUCTIVITY <= bicarbConductivity ) && ( bicarbConductivity <= MAX_DIALYSATE_CONDUCTIVITY );
+ BOOL const isConductivityInRange = isAcidConductivityInRange() && ( MIN_DIALYSATE_CONDUCTIVITY <= bicarbConductivity ) &&
+ ( bicarbConductivity <= MAX_DIALYSATE_CONDUCTIVITY );
return isConductivityInRange;
}
@@ -357,15 +395,17 @@
*************************************************************************/
static void processCPiCPoSensorRead( U32 sensorId, U32 fgpaRead, U08 fpgaReadCount, U08 fpgaErrorCount, U08 fpgaSensorFault )
{
- if ( ( fpgaErrorCount == 0 ) && ( fpgaSensorFault == 0 ) )
+ if ( ( 0 == fpgaErrorCount ) && ( 0 == fpgaSensorFault ) )
{
if ( ( readCount[ sensorId ] != fpgaReadCount ) )
{
F32 const temperature = getTemperatureValue( associateTempSensor[ sensorId ] );
F32 const conductivity = ( (F32)( fgpaRead ) / COND_SENSOR_DECIMAL_CONVERSION );
+ F32 const compensatedCond = calcCompensatedConductivity( conductivity, temperature );
+
readCount[ sensorId ] = fpgaReadCount;
internalErrorCount[ sensorId ] = 0;
- compensatedConductivityValues[ sensorId ].data = calcCompensatedConductivity( conductivity, temperature );
+ compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond );
}
else
{
@@ -439,9 +479,10 @@
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 );
+ F32 const compensatedCond = calcCompensatedConductivity( conductivity, temperature );
internalErrorCount[ sensorId ] = 0;
- compensatedConductivityValues[ sensorId ].data = calcCompensatedConductivity( conductivity, temperature );
+ compensatedConductivityValues[ sensorId ].data = getCalibrationAppliedConductivityValue( sensorId, compensatedCond );
}
else
{
@@ -537,7 +578,69 @@
return result;
}
+/*********************************************************************//**
+ * @brief
+ * The processCalibrationData function gets the calibration data and makes
+ * sure it is valid by checking the calibration date. The calibration date
+ * should not be 0.
+ * @details Inputs: none
+ * @details Outputs: condSensorsCalRecord
+ * @return TRUE if the calibration record is valid, otherwise FALSE
+ *************************************************************************/
+static BOOL processCalibrationData( void )
+{
+ BOOL status = TRUE;
+ U32 sensor;
+ // Get the calibration record from NVDataMgmt
+ DG_COND_SENSORS_CAL_RECORD_T calData = getDGConducitivitySensorsCalibrationRecord();
+
+ for ( sensor = 0; sensor < NUM_OF_CAL_DATA_COND_SENSORS; sensor++ )
+ {
+#ifndef SKIP_CAL_CHECK
+ // Check if the calibration data that was received from NVDataMgmt is legitimate
+ // The calibration date item should not be zero. If the calibration date is 0,
+ // then the data is not stored in the NV memory or it was corrupted.
+ if ( 0 == calData.condSensors[ sensor ].calibrationTime )
+ {
+ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_COND_SENSORS_INVALID_CAL_RECORD, (U32)sensor );
+ status = FALSE;
+ }
+#endif
+
+ // The calibration data was valid, update the local copy
+ condSensorsCalRecord.condSensors[ sensor ].fourthOrderCoeff = calData.condSensors[ sensor ].fourthOrderCoeff;
+ condSensorsCalRecord.condSensors[ sensor ].thirdOrderCoeff = calData.condSensors[ sensor ].thirdOrderCoeff;
+ condSensorsCalRecord.condSensors[ sensor ].secondOrderCoeff = calData.condSensors[ sensor ].secondOrderCoeff;
+ condSensorsCalRecord.condSensors[ sensor ].gain = calData.condSensors[ sensor ].gain;
+ condSensorsCalRecord.condSensors[ sensor ].offset = calData.condSensors[ sensor ].offset;
+ }
+
+ return status;
+}
+
+/*********************************************************************//**
+ * @brief
+ * The getCalibrationAppliedConductivityValue function gets the temperature
+ * compensated conductivity value and applies calibration to it.
+ * @details Inputs: condSensorsCalRecord
+ * @details Outputs: none
+ * @param sensorId which is the conductivity sensor ID
+ * @param compensatedValue which is the temperature compensated conductivity
+ * value of the conductivity sensor
+ * @return the calibration applied conductivity value
+ *************************************************************************/
+static F32 getCalibrationAppliedConductivityValue( U32 sensorId, F32 compensatedValue )
+{
+ 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 +
+ condSensorsCalRecord.condSensors[ (CAL_DATA_DG_COND_SENSORS_T)sensorId ].offset;
+ return conductivity;
+}
+
+
/*************************************************************************
* TEST SUPPORT FUNCTIONS
*************************************************************************/
Index: firmware/App/Controllers/Fans.c
===================================================================
diff -u -ra8bb1da29825b5d666333629fda871652d16229a -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Controllers/Fans.c (.../Fans.c) (revision a8bb1da29825b5d666333629fda871652d16229a)
+++ firmware/App/Controllers/Fans.c (.../Fans.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -32,9 +32,11 @@
#define FANS_SELF_TEST_WAIT_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Fans self test wait time for the fans to get to RPM.
#define FANS_SELF_TEST_TARGET_PWM 0.5 ///< Fans self test target PWM for testing the fans are running.
#define FANS_MAX_ALLOWED_RPM_OUT_OF_RANGE_INTERVAL ( 3 * MS_PER_SECOND ) ///< Fans max allowed RPM out of range time interval.
-#define FANS_MAX_ALLOWED_RPM 5000 ///< Fans max allowed RPM value.
+#define FANS_MAX_ALLOWED_RPM 5500 ///< Fans max allowed RPM value.
#define FANS_MIN_ALLOWED_RPM 150 ///< Fans max allowed RPM value.
#define FANS_MONITOR_INTERVAL_COUNT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Fans monitor time interval in counts.
+#define FANS_MIN_RPM_OUT_OF_RANGE_TOL 0.25 ///< Fans min RPM out of range tolerance.
+#define FANS_MAX_RPM_OUT_OF_RANGE_TOL 0.5 ///< Fans max RPM out of range tolerance.
/// Fans self test states
typedef enum fans_Self_Test
@@ -61,12 +63,11 @@
} FAN_STATUS_T;
static FAN_STATUS_T fansStatus; ///< Fans status.
-static SELF_TEST_STATUS_T fansSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS; ///< Fans self test result.
-static FANS_SELF_TEST_STATES_T fansSelfTestState = FANS_SELF_TEST_START_STATE; ///< Fans self test state.
static FANS_EXEC_STATES_T fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST_STATE; ///< Fans exec state.
static U32 fansControlCounter = 0; ///< Fans control interval counter.
static U32 fansPublishCounter = 0; ///< Fans data publish interval counter.
static U32 fansMonitorCounter = 0; ///< Fans monitor interval counter.
+static BOOL isPOSTComplete = FALSE; ///< Flag that indicates whether POST is complete or not.
/// Temperature to duty cycle conversion slope (duty cycle not in percent)
static const F32 SLOPE = ( FANS_MAX_DUTY_CYCLE - FANS_MIN_DUTY_CYCLE ) / ( MAX_ALLOWED_AMBINET_TEMPERATURE - MIN_ALLOWED_AMBIENT_TEMPERATURE );
@@ -76,9 +77,6 @@
static OVERRIDE_U32_T fansPublishInterval = { FANS_DATA_PUBLISH_INTERVAL, FANS_DATA_PUBLISH_INTERVAL, 0, 0 }; ///< Fans publish time interval override
-static FANS_SELF_TEST_STATES_T handleSelfTestStart( void );
-static FANS_SELF_TEST_STATES_T handleSelfTestCheckRPM( void );
-
static FANS_EXEC_STATES_T handleExecStateWaitForPOST( void );
static FANS_EXEC_STATES_T handleExecStateRun( void );
@@ -93,22 +91,20 @@
/*********************************************************************//**
* @brief
* The initFans function initializes the fans module.
- * @details Inputs: fansExecState, fansSelfTestReslt, fansSelfTestState,
- * fansStatus, fansControlCounter, fansPublishCounter
- * @details Outputs: fansExecState, fansSelfTestReslt, fansSelfTestState,
- * fansStatus, fansControlCounter, fansPublishCounter
+ * @details Inputs: fansExecState, fansStatus, fansControlCounter,
+ * fansPublishCounter
+ * @details Outputs: fansExecState, fansStatus, fansControlCounter,
+ * fansPublishCounter
* @return none
*************************************************************************/
void initFans( void )
{
// Initialize the variables
fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST_STATE;
- fansSelfTestResult = SELF_TEST_STATUS_IN_PROGRESS;
- fansSelfTestState = FANS_SELF_TEST_START_STATE;
- fansExecState = FANS_EXEC_STATE_WAIT_FOR_POST_STATE;
fansControlCounter = 0;
fansPublishCounter = 0;
fansMonitorCounter = 0;
+ isPOSTComplete = FALSE;
// Initialize a persistent alarm for fans RPM out of range
initPersistentAlarm( ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE, FANS_MAX_ALLOWED_RPM_OUT_OF_RANGE_INTERVAL, FANS_MAX_ALLOWED_RPM_OUT_OF_RANGE_INTERVAL );
@@ -117,34 +113,21 @@
/*********************************************************************//**
* @brief
* The execFansSelfTest function executes the fans self test.
- * @details Inputs: fansSelfTestState, fansSelfTestReslt
- * @details Outputs: fansSelfTestState, fansSelfTestReslt
+ * @details Inputs: none
+ * @details Outputs: isPOSTComplete
* @return Status of self test
*************************************************************************/
SELF_TEST_STATUS_T execFansSelfTest( void )
{
- switch ( fansSelfTestState )
- {
- case FANS_SELF_TEST_START_STATE:
- fansSelfTestState = handleSelfTestStart();
- break;
+ SELF_TEST_STATUS_T status = SELF_TEST_STATUS_IN_PROGRESS;
- case FANS_SELF_TEST_CHECK_RPM_STATE:
- fansSelfTestState = handleSelfTestCheckRPM();
- break;
+ // TODO implement the calibration processing function.
+ // It returns a pass for now
- case FAN_SELF_TEST_COMPLETE_STATE:
- // Done with POST. Do nothing
- break;
+ isPOSTComplete = TRUE;
+ status = SELF_TEST_STATUS_PASSED;
- default:
- // Wrong state called
- SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_FAN_INVALID_SELF_TEST_STATE, fansSelfTestState );
- fansSelfTestState = FAN_SELF_TEST_COMPLETE_STATE;
- break;
- }
-
- return fansSelfTestResult;
+ return status;
}
/*********************************************************************//**
@@ -157,7 +140,7 @@
void execFans( void )
{
// Monitor the fans
- monitorFans();
+ //monitorFans(); TODO uncomment. this is to investigate why the fans RPM are out of range
switch ( fansExecState )
{
@@ -205,69 +188,6 @@
/*********************************************************************//**
* @brief
- * The handleSelfTestStart function handles the start state of the fans'
- * self test.
- * @details Inputs: none
- * @details Outputs: none
- * @return next state of self test
- *************************************************************************/
-static FANS_SELF_TEST_STATES_T handleSelfTestStart( void )
-{
- FANS_SELF_TEST_STATES_T state = FANS_SELF_TEST_CHECK_RPM_STATE;
-
- // Set the fans to the target PWM for the next stage
- setInletFansDutyCycle( FANS_SELF_TEST_TARGET_PWM );
- setOutletFansDutyCycle( FANS_SELF_TEST_TARGET_PWM );
- state = FANS_SELF_TEST_CHECK_RPM_STATE;
-
- return state;
-}
-
-/*********************************************************************//**
- * @brief
- * The handleSelfTestCheckRPM function handles the check RPM state of the
- * fans' self test.
- * @details Inputs: fansStatus
- * @details Outputs: none
- * @return next state of self test
- *************************************************************************/
-static FANS_SELF_TEST_STATES_T handleSelfTestCheckRPM( void )
-{
- FANS_SELF_TEST_STATES_T state = FANS_SELF_TEST_CHECK_RPM_STATE;
-
- FAN_NAMES_T fan;
-
- // Wait for the fans to run for a certain period of time before checking their RPM
- if ( ++fansControlCounter > FANS_SELF_TEST_WAIT_INTERVAL )
- {
- // Assuming the test will pass
- fansSelfTestResult = SELF_TEST_STATUS_PASSED;
-
- convertTogglePeriod2RPM();
-
- // Loop through all the fans to check their RPM. They should be above the specified RPM
- for( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ )
- {
- if ( fansStatus.rpm[ fan ] < MIN_TARGET_RPM_IN_SELF_TEST )
- {
- SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE, fan, fansStatus.rpm[ fan ] );
-
- fansSelfTestResult = SELF_TEST_STATUS_FAILED;
- }
- }
-
- // Turn off the fans, done with self test
- setInletFansDutyCycle( 0.0 );
- setOutletFansDutyCycle( 0.0 );
-
- state = FAN_SELF_TEST_COMPLETE_STATE;
- }
-
- return state;
-}
-
-/*********************************************************************//**
- * @brief
* The handleFansExecStateStart function handles the start state of the
* fans exec state machine.
* @details Inputs: none
@@ -279,7 +199,7 @@
FANS_EXEC_STATES_T state = FANS_EXEC_STATE_WAIT_FOR_POST_STATE;
// Wait for the self test to finish before starting the fans
- if ( fansSelfTestState == FAN_SELF_TEST_COMPLETE_STATE )
+ if ( TRUE == isPOSTComplete )
{
// Start the fans with minimum PWM. The control will decide the next PWM automatically.
setInletFansDutyCycle( FANS_MIN_DUTY_CYCLE );
@@ -313,10 +233,6 @@
// Get the maximum temperature among all the thermistors and temperature sensors to run fan from the hottest temperature
F32 temperature = getMaximumTemperature();
- //TODO REMOVE FOR TESTING
- temperature = getThermistorTemperatureValue( THERMISTOR_ONBOARD_NTC );
- //TODO REMOVE FOR TESTING only
-
// Solve the linear equation to calculate the duty cycle from temperature
F32 dutyCycle = ( SLOPE * ( temperature - MIN_ALLOWED_AMBIENT_TEMPERATURE ) ) + FANS_MIN_DUTY_CYCLE;
@@ -477,11 +393,18 @@
if ( ++fansMonitorCounter >= FANS_MONITOR_INTERVAL_COUNT )
{
+ // The RPM is expected to be 5500 @ 100% duty cycle
+ // The nominal RPM = duty cycle * 5500 / 1.0
+ // The RPM tolerance is -25% to +50% of the nominal RPM
+ F32 fansNominalRPM = fansStatus.targetDutyCycle * FANS_MAX_ALLOWED_RPM;
+ F32 fansMinAllowedRPM = fansNominalRPM - ( fansNominalRPM * FANS_MIN_RPM_OUT_OF_RANGE_TOL );
+ F32 fansMaxAllowedRPM = fansNominalRPM - ( fansNominalRPM * FANS_MAX_RPM_OUT_OF_RANGE_TOL );
+
convertTogglePeriod2RPM();
for ( fan = FAN_INLET_1; fan < NUM_OF_FANS_NAMES; fan++ )
{
- BOOL const fanRpmOutOfRange = ( fansStatus.rpm[ fan ] >= FANS_MAX_ALLOWED_RPM ) || ( fansStatus.rpm[ fan ] <= FANS_MIN_ALLOWED_RPM );
+ BOOL const fanRpmOutOfRange = ( fansStatus.rpm[ fan ] < fansMinAllowedRPM ) || ( fansStatus.rpm[ fan ] > fansMaxAllowedRPM );
checkPersistentAlarm( ALARM_ID_DG_FAN_RPM_OUT_OF_RANGE, fanRpmOutOfRange, fansStatus.rpm[ fan ], FANS_MAX_ALLOWED_RPM );
}
Index: firmware/App/Controllers/Heaters.c
===================================================================
diff -u -r97e0100921ccad633b39b509a93a7237e4d80446 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision 97e0100921ccad633b39b509a93a7237e4d80446)
+++ firmware/App/Controllers/Heaters.c (.../Heaters.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -890,7 +890,7 @@
{
BOOL result = FALSE;
- if ( isTestingActivated() )
+ if ( TRUE == isTestingActivated() )
{
U32 interval = value / TASK_PRIORITY_INTERVAL;
@@ -914,7 +914,7 @@
{
BOOL result = FALSE;
- if ( isTestingActivated() )
+ if ( TRUE == isTestingActivated() )
{
result = TRUE;
heatersDataPublishInterval.override = OVERRIDE_RESET;
Index: firmware/App/Controllers/ROPump.c
===================================================================
diff -u -r5a36a768d11cc597a36b894c1fb3a5e5590130f1 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision 5a36a768d11cc597a36b894c1fb3a5e5590130f1)
+++ firmware/App/Controllers/ROPump.c (.../ROPump.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -21,9 +21,10 @@
#include "mibspi.h"
#include "FPGA.h"
+#include "NVDataMgmt.h"
#include "OperationModes.h"
-#include "PIControllers.h"
#include "PersistentAlarm.h"
+#include "PIControllers.h"
#include "Pressures.h"
#include "ROPump.h"
#include "SafetyShutdown.h"
@@ -131,6 +132,7 @@
static S32 measuredFlowReadingsSum = 0; ///< Raw flow reading sums for averaging.
static U32 flowFilterCounter = 0; ///< Flow filtering counter.
+static DG_FLOW_SENSORS_CAL_RECORD_T flowSensorsCalRecord; ///< Flow sensors calibration record.
// ********** private function prototypes **********
@@ -145,6 +147,7 @@
static void stopROPump( void );
static void publishROPumpData( void );
static U32 getPublishROPumpDataInterval( void );
+static BOOL processCalibrationData( void );
/*********************************************************************//**
* @brief
@@ -331,20 +334,38 @@
BOOL isPressureMax = actualPressure >= MAX_ALLOWED_MEASURED_PRESSURE_PSI;
checkPersistentAlarm( ALARM_ID_RO_PUMP_PRESSURE_OUT_OF_RANGE, isPressureMax, actualPressure, MAX_ALLOWED_MEASURED_PRESSURE_PSI );
+ // Check if a new calibration is available
+ if ( TRUE == isNewCalibrationRecordAvailable() )
+ {
+ // Get the new calibration data and check its validity
+ processCalibrationData();
+ }
+
// Read flow at the control set
if ( ++flowFilterCounter >= FLOW_SAMPLES_TO_AVERAGE )
{
- F32 avgROFlow = (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER;
+ U32 sensor;
+ F32 flow = RO_FLOW_ADC_TO_LPM_FACTOR / ( (F32)measuredFlowReadingsSum * FLOW_AVERAGE_MULTIPLIER );
+
// If the flow is less than a certain value, FPGA will return 0xFFFF meaning that
// the flow is 0. Otherwise, convert the count to flow rate in mL/min
- if ( ( roFlowReading == FLOW_SENSOR_ZERO_READING ) || ( roFlowReading == 0 ) )
+ if ( ( FLOW_SENSOR_ZERO_READING == roFlowReading ) || ( 0 == roFlowReading ) )
{
measuredROFlowRateLPM.data = 0.0;
}
else
{
- measuredROFlowRateLPM.data = RO_FLOW_ADC_TO_LPM_FACTOR / avgROFlow;
+ // Right now there is only one flow sensor but a for loop is used here to be able to automatically accommodate
+ // the future flow sensors
+ for( sensor = 0; sensor < NUM_OF_CAL_DATA_FLOW_SENSORS; sensor++ )
+ {
+ measuredROFlowRateLPM.data = pow(flow, 4) * flowSensorsCalRecord.flowSensors[ sensor ].fourthOrderCoeff +
+ pow(flow, 3) * flowSensorsCalRecord.flowSensors[ sensor ].thirdOrderCoeff +
+ pow(flow, 2) * flowSensorsCalRecord.flowSensors[ sensor ].secondOrderCoeff +
+ flow * flowSensorsCalRecord.flowSensors[ sensor ].gain +
+ flowSensorsCalRecord.flowSensors[ sensor ].offset;
+ }
}
measuredFlowReadingsSum = 0;
@@ -368,7 +389,6 @@
checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_UPPER_RANGE, isFlowOutOfUpperRange, currentFlow, targetFlow );
checkPersistentAlarm( ALARM_ID_FLOW_RATE_OUT_OF_LOWER_RANGE, isFlowOutOfLowerRange, currentFlow, targetFlow );
}
-#endif
// If the pump is off and PPi + 5psi < PPo for a certain period of time, activate safety shutdown
if ( FALSE == isROPumpOn )
@@ -384,6 +404,7 @@
activateSafetyShutdown();
}
}
+#endif
// Publish RO pump data on interval
publishROPumpData();
@@ -449,6 +470,31 @@
/*********************************************************************//**
* @brief
+ * The execROPumpSelfTest function executes the RO pump's self-test.
+ * @details Inputs: none
+ * @details Outputs: none
+ * @return PressuresSelfTestResult (SELF_TEST_STATUS_T)
+ *************************************************************************/
+SELF_TEST_STATUS_T execROPumpSelfTest( void )
+{
+ SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS;
+
+ BOOL calStatus = processCalibrationData();
+
+ if ( TRUE == calStatus )
+ {
+ result = SELF_TEST_STATUS_PASSED;
+ }
+ else
+ {
+ result = SELF_TEST_STATUS_FAILED;
+ }
+
+ return result;
+}
+
+/*********************************************************************//**
+ * @brief
* The isROPumpRunning function returns the on/off status of RO pump.
* @details Inputs: isROPumpOn
* @details Outputs: none
@@ -462,6 +508,51 @@
/*********************************************************************//**
* @brief
+ * The getTargetROPumpFlowRate function gets the current target RO pump
+ * flow rate.
+ * @details Inputs: targetROPumpFlowRate
+ * @details Outputs: targetROPumpFlowRate
+ * @return the current target RO flow rate (in L/min).
+ *************************************************************************/
+F32 getTargetROPumpFlowRate( void )
+{
+ return targetROPumpFlowRate;
+}
+
+/*********************************************************************//**
+ * @brief
+ * The getMeasuredROFlowRate function gets the measured RO pump flow rate.
+ * @details Inputs: measuredROFlowRateLPM
+ * @details Outputs: measuredROFlowRateLPM
+ * @return the current RO pump flow rate (in L/min).
+ *************************************************************************/
+F32 getMeasuredROFlowRate( void )
+{
+ F32 result = measuredROFlowRateLPM.data;
+
+ if ( OVERRIDE_KEY == measuredROFlowRateLPM.override )
+ {
+ result = measuredROFlowRateLPM.ovData;
+ }
+
+ return result;
+}
+
+/*********************************************************************//**
+ * @brief
+ * The getTargetROPumpPressure function gets the current target RO pump
+ * pressure.
+ * @details Inputs: targetROPumpPressure
+ * @details Outputs: targetROPumpPressure
+ * @return the current target RO targetROPumpPressure in psi.
+ *************************************************************************/
+F32 getTargetROPumpPressure( void )
+{
+ return targetROPumpMaxPressure;
+}
+
+/*********************************************************************//**
+ * @brief
* The handleROPumpOffState function handles the RO pump off state of the
* controller state machine.
* @details Inputs: roPumpControlMode, roPumpPWMDutyCyclePctSet,
@@ -717,51 +808,48 @@
/*********************************************************************//**
* @brief
- * The getTargetROPumpFlowRate function gets the current target RO pump
- * flow rate.
- * @details Inputs: targetROPumpFlowRate
- * @details Outputs: targetROPumpFlowRate
- * @return the current target RO flow rate (in L/min).
+ * The processCalibrationData function gets the calibration data and makes
+ * sure it is valid by checking the calibration date. The calibration date
+ * should not be 0.
+ * @details Inputs: none
+ * @details Outputs: flowSensorsCalRecord
+ * @return TRUE if the calibration record is valid, otherwise FALSE
*************************************************************************/
-F32 getTargetROPumpFlowRate( void )
+static BOOL processCalibrationData( void )
{
- return targetROPumpFlowRate;
-}
+ BOOL status = TRUE;
+ U32 sensor;
-/*********************************************************************//**
- * @brief
- * The getMeasuredROFlowRate function gets the measured RO pump flow rate.
- * @details Inputs: measuredROFlowRateLPM
- * @details Outputs: measuredROFlowRateLPM
- * @return the current RO pump flow rate (in L/min).
- *************************************************************************/
-F32 getMeasuredROFlowRate( void )
-{
- F32 result = measuredROFlowRateLPM.data;
+ // Get the calibration record from NVDataMgmt
+ DG_FLOW_SENSORS_CAL_RECORD_T calData = getDGFlowSensorsCalibrationRecord();
- if ( OVERRIDE_KEY == measuredROFlowRateLPM.override )
+ for ( sensor = 0; sensor < NUM_OF_CAL_DATA_FLOW_SENSORS; sensor++ )
{
- result = measuredROFlowRateLPM.ovData;
+#ifndef SKIP_CAL_CHECK
+ // Check if the calibration data that was received from NVDataMgmt is legitimate
+ // The calibration date item should not be zero. If the calibration date is 0,
+ // then the flow sensors data is not stored in the NV memory or it was corrupted.
+ if ( 0 == calData.flowSensors[ sensor ].calibrationTime )
+ {
+
+ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_FLOW_SENSORS_INVALID_CAL_RECORD, (U32)sensor );
+ status = FALSE;
+ }
+#endif
+
+ // The calibration data was valid, update the local copy
+ flowSensorsCalRecord.flowSensors[ sensor ].fourthOrderCoeff = calData.flowSensors[ sensor ].fourthOrderCoeff;
+ flowSensorsCalRecord.flowSensors[ sensor ].thirdOrderCoeff = calData.flowSensors[ sensor ].thirdOrderCoeff;
+ flowSensorsCalRecord.flowSensors[ sensor ].secondOrderCoeff = calData.flowSensors[ sensor ].secondOrderCoeff;
+ flowSensorsCalRecord.flowSensors[ sensor ].gain = calData.flowSensors[ sensor ].gain;
+ flowSensorsCalRecord.flowSensors[ sensor ].offset = calData.flowSensors[ sensor ].offset;
}
- return result;
+ return status;
}
/*********************************************************************//**
* @brief
- * The getTargetROPumpPressure function gets the current target RO pump
- * pressure.
- * @details Inputs: targetROPumpPressure
- * @details Outputs: targetROPumpPressure
- * @return the current target RO targetROPumpPressure in psi.
- *************************************************************************/
-F32 getTargetROPumpPressure( void )
-{
- return targetROPumpMaxPressure;
-}
-
-/*********************************************************************//**
- * @brief
* The publishROPumpData function publishes RO pump data at the set interval.
* @details Inputs: roPumpDataPublicationTimerCounter
* @details Outputs: roPumpDataPublicationTimerCounter
@@ -785,6 +873,7 @@
}
}
+
/*************************************************************************
* TEST SUPPORT FUNCTIONS
*************************************************************************/
Index: firmware/App/Controllers/UVReactors.c
===================================================================
diff -u -r2fff37fa585181917705645494549b5fd4a4d522 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision 2fff37fa585181917705645494549b5fd4a4d522)
+++ firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -48,7 +48,7 @@
{
UV_REACTOR_STATE_T execState; ///< UV reactor executive state
PIN_SIGNAL_STATE_T pinSignalState; ///< UV reactor pin signal state
- SWITCH_STATES_T switchState; ///< UV reactor turn on/turn off state
+ UV_REACTOR_STATES_T switchState; ///< UV reactor turn on/turn off state
U32 reactorEnablePin; ///< UV reactor enable pin of GIO port A
U32 reactorHealthStatusPin; ///< UV reactor status pin of N2HET1
OVERRIDE_U32_T healthStatus; ///< UV reactor current health status
Index: firmware/App/DGCommon.h
===================================================================
diff -u -rb93d59e35abc7a815cb108831ffca93635321028 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/DGCommon.h (.../DGCommon.h) (revision b93d59e35abc7a815cb108831ffca93635321028)
+++ firmware/App/DGCommon.h (.../DGCommon.h) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -51,7 +51,7 @@
// #define DISABLE_RO_RATIO_CHECK 1
#define DISABLE_COND_SENSOR_CHECK 1
#define DISABLE_MIXING 1
- #define DISABLE_WATER_QUALITY_CHECK 1
+// #define DISABLE_WATER_QUALITY_CHECK 1
#define DISABLE_RTC_CONFIG 1
//#define V_2_SYSTEM 1
#define THD_USING_TRO_CONNECTOR 1
Index: firmware/App/Modes/ModeFlush.c
===================================================================
diff -u -r2fff37fa585181917705645494549b5fd4a4d522 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision 2fff37fa585181917705645494549b5fd4a4d522)
+++ firmware/App/Modes/ModeFlush.c (.../ModeFlush.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -15,6 +15,7 @@
*
***************************************************************************/
+#include "ConcentratePumps.h"
#include "DrainPump.h"
#include "Heaters.h"
#include "LoadCell.h"
@@ -39,33 +40,36 @@
// General defines
#define FLUSH_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Mode flush data publish interval in counts.
-#define RO_PUMP_TARGET_FLOW_RATE_LPM 0.8 ///< RO pump target flow rate during flush/fill in L/min. TODO original flow was 0.8
-#define RO_PUMP_MAX_PRESSURE_PSI 130 ///< Maximum RO pump pressure during flush/fill states in psi.
-#define DRAIN_PUMP_TARGET_RPM 2200 ///< Drain pump target RPM during drain.
+#define RO_PUMP_TARGET_FLOW_RATE_LPM 0.8 ///< RO pump target flow rate during flush/fill in L/min.
+#define RO_PUMP_MAX_PRESSURE_PSI 130 ///< Maximum RO pump pressure during flush/fill states in psi.
+#define DRAIN_PUMP_TARGET_RPM 2200 ///< Drain pump target RPM during drain.
// Drain R1 & R2 states defines
-#define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout.
+#define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 6 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout.
// Flush drain path state defines
-#define FLUSH_DRAIN_WAIT_TIME_MS ( 1 * 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo original time is 2 minutes
+#define FLUSH_DRAIN_WAIT_TIME_MS ( 2 * 60 * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds.
// Flush dialysate state defines
#define FLUSH_DIALYSATE_WAIT_TIME_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Flush dialysate wait time in milliseconds.
// Flush concentrate straws state defines
-#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 0.5 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds. TODO original time is 3 minutes
+#define FLUSH_CONCENTRATE_STRAWS_TIME_MS ( 3 * 60 * MS_PER_SECOND ) ///< Flush concentrate straws wait time in milliseconds.
+#define ACID_PUMP_SPEED_ML_PER_MIN -30.0 ///< Acid pump speed in mL/min.
+// The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during flush
+#define BICARB_PUMP_SPEED_ML_PER_MIN 30.6 ///< Bicarb pump speed in mL/min.
// Flush and drain R1 and R2 state defines
-#define RSRVRS_FULL_VOL_ML 1650.0 ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900
-#define RSRVRS_PARTIAL_FILL_VOL_ML 500.0 ///< Reservoirs 1 & 2 partial volume in mL.
+#define RSRVRS_FULL_VOL_ML 1800.0 ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900
+#define RSRVRS_PARTIAL_FILL_VOL_ML 500.0 ///< Reservoirs 1 & 2 partial volume in mL.
#define RSRVRS_FULL_STABLE_TIME_COUNT ( ( 4 * MS_PER_SECOND ) / TASK_GENERAL_INTERVAL ) ///< Reservoirs 1 & 2 full stable time in counts.
-#define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms. TODO original value was 5 minutes
+#define RSRVRS_FILL_UP_TIMEOUT_MS ( 5 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 full fill up timeout in ms.
#define RSRVRS_PARTIAL_FILL_TIMEOUT_MS ( 2 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 partial fill up timeout in ms.
-#define RSRVRS_DRAIN_TIMEOUT_MS ( 3 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. TODO original value was 2 minutes
-#define FINAL_DRAIN_RO_PUMP_FLOW_LPM 0.6 ///< Final drain RO pump flow rate in L/min. This is used to flush the drain line during drain.
+#define RSRVRS_DRAIN_TIMEOUT_MS ( 3 * 60 * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms.
+#define FINAL_DRAIN_RO_PUMP_FLOW_LPM 0.6 ///< Final drain RO pump flow rate in L/min. This is used to flush the drain line during drain.
// Flush drain line state defines
-#define FLUSH_DRAIN_LINE_VOLUME_L 0.1 ///< Water volume to flush in liters.
+#define FLUSH_DRAIN_LINE_VOLUME_L 0.1 ///< Water volume to flush in liters.
#define FLUSH_DRAIN_LINE_TIMEOUT_MS ( 1 * 60 * MS_PER_SECOND ) ///< Flush drain lines timeout in milliseconds.
// Flush circulation state defines
@@ -78,6 +82,7 @@
static DG_FLUSH_STATE_T flushState = DG_FLUSH_STATE_START; ///< Current active flush state.
static DG_FLUSH_STATE_T prevFlushState = DG_FLUSH_STATE_START; ///< Previous flush state.
+static DG_FLUSH_UI_STATE_T flushUIState = FLUSH_UI_STATE_NOT_RUNNING; ///< Current UI flush state.
static U32 rsrvrFillStableTimeCounter = 0; ///< Reservoirs fill stable time counter.
static U32 overallFlushElapsedTimeStart = 0; ///< Overall flush mode elapsed time start.
static U32 stateTimerStart = 0; ///< State timer start.
@@ -126,6 +131,7 @@
// Initialize the variables
flushState = DG_FLUSH_STATE_START;
prevFlushState = DG_FLUSH_STATE_START;
+ flushUIState = FLUSH_UI_STATE_NOT_RUNNING;
rsrvrFillStableTimeCounter = 0;
overallFlushElapsedTimeStart = 0;
isThisInitialDrain = TRUE;
@@ -308,6 +314,7 @@
setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM );
+ flushUIState = FLUSH_UI_STATE_DRAIN_DEVICE;
stateTimerStart = getMSTimerCount();
rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET;
state = DG_FLUSH_STATE_DRAIN_R1;
@@ -409,10 +416,12 @@
#else
setValveState( VPD, VALVE_STATE_OPEN_C_TO_NO );
#endif
+ setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO );
setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO );
setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO );
setROPumpTargetFlowRate( FINAL_DRAIN_RO_PUMP_FLOW_LPM, RO_PUMP_MAX_PRESSURE_PSI );
+ flushUIState = FLUSH_UI_STATE_FLUSH_RECIRCULATION_PATH;
state = DG_FLUSH_STATE_FLUSH_CIRCULATION_DRAIN_LINE;
}
@@ -474,7 +483,14 @@
if ( TRUE == didTimeout( stateTimerStart, FLUSH_DIALYSATE_WAIT_TIME_MS ) )
{
- // TODO turn on the concentrate pumps
+ // Turn the pumps on in reverse
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN );
+
+ // Turn on the concentrate pumps
+ requestConcentratePumpsOn( CONCENTRATEPUMPS_CP1_ACID );
+ requestConcentratePumpsOn( CONCENTRATEPUMPS_CP2_BICARB );
+
stateTimerStart = getMSTimerCount();
state = DG_FLUSH_STATE_FLUSH_CONCENTRATE_STRAWS;
@@ -498,14 +514,18 @@
if ( TRUE == didTimeout( stateTimerStart, FLUSH_CONCENTRATE_STRAWS_TIME_MS ) )
{
- // TODO turn off the concentrate pumps
+ // Done with flushing the concentrate pumps line
+ requestConcentratePumpsOff( CONCENTRATEPUMPS_CP1_ACID );
+ requestConcentratePumpsOff( CONCENTRATEPUMPS_CP2_BICARB );
+
setValveState( VPO, VALVE_STATE_FILL_C_TO_NC );
setValveState( VRF, VALVE_STATE_R1_C_TO_NC );
setValveState( VRI, VALVE_STATE_R2_C_TO_NC );
stateTimerStart = getMSTimerCount();
rsrvr1Status = DG_RESERVOIR_BELOW_TARGET;
rsrvr2Status = DG_RESERVOIR_BELOW_TARGET;
+ flushUIState = FLUSH_UI_STATE_FLUSH_RESERVOIRS;
state = DG_FLUSH_STATE_FLUSH_R1_TO_R2;
}
@@ -660,6 +680,7 @@
stateTimerStart = getMSTimerCount();
isThisInitialDrain = FALSE;
rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET;
+ flushUIState = FLUSH_UI_STATE_DRAIN_RESERVOIRS;
state = DG_FLUSH_STATE_DRAIN_R1;
}
// Check if reservoir 1 fill timed out
@@ -710,7 +731,6 @@
#endif
setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC );
setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC );
- setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO );
setROPumpTargetFlowRate( RO_PUMP_TARGET_FLOW_RATE_LPM, RO_PUMP_MAX_PRESSURE_PSI );
stateTimerStart = getMSTimerCount();
@@ -774,7 +794,7 @@
if ( TRUE == didTimeout( stateTimerStart, FLUSH_WITH_FRESH_WATER_WAIT_TIME_MS ) )
{
deenergizeActuators();
-
+ flushUIState = FLUSH_UI_STATE_COMPLETE;
state = DG_FLUSH_STATE_COMPLETE;
}
@@ -798,6 +818,8 @@
// deenergize all the actuators
failFlushMode();
+ flushUIState = FLUSH_UI_STATE_CANCEL_FLUSH;
+
return state;
}
@@ -841,6 +863,8 @@
// Start the drain pump
setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM );
+ flushUIState = FLUSH_UI_STATE_CANCEL_FLUSH;
+
// Start the timer for drain timeout
stateTimerStart = getMSTimerCount();
}
@@ -1026,6 +1050,7 @@
data.overallElapsedTime = calcTimeSince( overallFlushElapsedTimeStart );
data.stateElapsedTime = calcTimeSince( stateTimerStart );
data.drainLineVolume = flushLinesVolumeL;
+ data.flushUIState = (U32)flushUIState;
broadcastFlushData( &data );
Index: firmware/App/Modes/ModeHeatDisinfect.c
===================================================================
diff -u -r2fff37fa585181917705645494549b5fd4a4d522 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 2fff37fa585181917705645494549b5fd4a4d522)
+++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -64,7 +64,9 @@
#define FLUSH_CICRCULATION_WAIT_TIME_MS ( 30 * MS_PER_SECOND ) ///< Flush/rinse circulation path wait time in milliseconds. TODO original time was 30 seconds
#define MAX_FLUSH_CIRC_TEMP_SENSOR_DIFF_C 50.0 ///< Maximum flush circulation temperature difference tolerance in C. TODO original difference was 3.0 degrees
#define NUM_OF_TEMP_SENSORS_TO_AVG 4.0 ///< Number of temperature sensors to average to check the difference.
-#define CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN -30.0 ///< Concentrate pumps reverse speed in mL/min.
+#define ACID_PUMP_SPEED_ML_PER_MIN -30.0 ///< Acid concentrate pump speed in mL/min.
+// The bicarb pump is 2% faster than the acid pump to create a flow from acid to bicarb line during heat disinfect
+#define BICARB_PUMP_SPEED_ML_PER_MIN 30.6 ///< Bicarb concentrate pump speed in mL/min.
// Flush and drain R1 and R2
#define RSRVRS_FULL_VOL_ML 1750.0 ///< Reservoirs 1 & 2 full volume in mL. TODo original value was 1900
@@ -118,7 +120,8 @@
/// Heat disinfect status
typedef enum Heat_disinfect_status
{
- HEAT_DISINFECT_IN_PROGRESS = 0, ///< Heat disinfect in progress.
+ HEAT_DISINFECT_HEAT_UP_IN_PROGRESS = 0, ///< Heat disinfect in progress.
+ HEAT_DISINFECT_DISINFECT_IN_PROGRESS, ///< Heat disinfect disinfect in progress.
HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT, ///< Heat disinfect reservoirs leak timeout.
HEAT_DISINFECT_HEAT_UP_TIMEOUT, ///< Heat disinfect heat up timeout.
HEAT_DISINFECT_COMPLETE, ///< Heat disinfect complete.
@@ -153,6 +156,7 @@
static U32 ROFCirculationTimer = 0; ///< RO filter circulation timer.
static U32 ROFCoolingTimer = 0; ///< RO filter cooling timer.
static BOOL hasROFCirculationBeenStarted = FALSE; ///< Flag to indicate the water in RO filter has been recirculated.
+static U32 targetDisinfectTime = 0; ///< Target disinfect time.
// ********** private function prototypes **********
@@ -196,8 +200,8 @@
* R1HeatDisinfectVol, R2HeatDisinfectVol, overallHeatDisinfectTimer,
* cancellationMode, rsrvrFillStableTimeCounter, prevHeatDisinfectState
* isPartialDisinfectInProgress, isDrainPumpOnInMixDrain,
- * hasROFCirculationBeenStarted, ROFCirculationTimer,
- * ROFCirculationCoolingCounter, concentratePumpsPrimeTimer
+ * hasROFCirculationBeenStarted, ROFCirculationTimer, targetDisinfectTime
+ * ROFCirculationCoolingCounter, concentratePumpsPrimeTimer,
* @return none
*************************************************************************/
void initHeatDisinfectMode( void )
@@ -222,6 +226,7 @@
ROFCoolingTimer = 0;
hasROFCirculationBeenStarted = FALSE;
concentratePumpsPrimeTimer = 0;
+ targetDisinfectTime = 0;
}
/*********************************************************************//**
@@ -700,8 +705,8 @@
areTempSensorsInRange = TRUE;
#ifndef IGNORE_CONC_PUMP_IN_HEAT_DISINFECT
// Turn the pumps on in reverse
- setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN );
- setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, ACID_PUMP_SPEED_ML_PER_MIN );
// Turn on the concentrate pumps
requestConcentratePumpsOn( CONCENTRATEPUMPS_CP1_ACID );
@@ -719,7 +724,7 @@
rsrvr1Status = DG_RESERVOIR_BELOW_TARGET;
rsrvr2Status = DG_RESERVOIR_BELOW_TARGET;
- // Done with priming the concentrate pumps line
+ // Done with flushing the concentrate pumps line
requestConcentratePumpsOff( CONCENTRATEPUMPS_CP1_ACID );
requestConcentratePumpsOff( CONCENTRATEPUMPS_CP2_BICARB );
@@ -1122,6 +1127,10 @@
state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH;
break;
+ case HEAT_DISINFECT_DISINFECT_IN_PROGRESS:
+ heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_1;
+ break;
+
case HEAT_DISINFECT_COMPLETE:
requestConcentratePumpsOff( CONCENTRATEPUMPS_CP1_ACID );
@@ -1145,9 +1154,9 @@
state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER;
break;
- case HEAT_DISINFECT_IN_PROGRESS:
+ case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS:
default:
- // Do nothing, heat disinfect is in progress
+ heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER;
break;
}
@@ -1221,6 +1230,7 @@
{
DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1;
HEAT_DISINFECT_STATUS_T status = getHeatDisinfectStatus();
+ heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2;
switch ( status )
{
@@ -1237,7 +1247,7 @@
state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS;
break;
- case HEAT_DISINFECT_IN_PROGRESS:
+ case HEAT_DISINFECT_HEAT_UP_IN_PROGRESS:
default:
// Do nothing heat disinfect is in progress.
break;
@@ -1628,8 +1638,8 @@
setDrainPumpTargetRPM( DRAIN_PUMP_TARGET_RPM );
#ifndef IGNORE_CONC_PUMP_IN_HEAT_DISINFECT
// Turn the pumps on in reverse
- setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN );
- setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, ACID_PUMP_SPEED_ML_PER_MIN );
// Turn on the concentrate pumps
requestConcentratePumpsOn( CONCENTRATEPUMPS_CP1_ACID );
@@ -1964,7 +1974,7 @@
*************************************************************************/
static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void )
{
- HEAT_DISINFECT_STATUS_T status = HEAT_DISINFECT_IN_PROGRESS;
+ HEAT_DISINFECT_STATUS_T status = HEAT_DISINFECT_HEAT_UP_IN_PROGRESS;
F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER );
F32 ThdTemp = getTemperatureValue( TEMPSENSORS_HEAT_DISINFECT );
@@ -1984,7 +1994,7 @@
// If the volume is out of range and it has timed out, exit
else if ( TRUE == didTimeout( rsrvrsVolMonitorTimer, RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ) )
{
- areRsrvrsLeaking = FALSE;
+ areRsrvrsLeaking = FALSE;
alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT;
status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT;
}
@@ -2002,7 +2012,7 @@
// Keep reseting the disinfect timer so the elapsed time is always 0 until disinfect truly starts
heatDisinfectTimer = getMSTimerCount();
isPartialDisinfectInProgress = FALSE;
- heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER;
+ targetDisinfectTime = 0;
if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_START_TEMP_TIMOUT_MS ) )
{
@@ -2016,32 +2026,37 @@
// The temperature of the coldest spot is in range to start the disinfect timer
heatDisinfectTimer = getMSTimerCount();
isPartialDisinfectInProgress = TRUE;
+ targetDisinfectTime = HEAT_DISINFECT_TIME_MS;
+ status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS;
- // Set the heat disinfect UI state
+ // In disinfect R1 to R2, concentrate pumps are also run
if ( DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 == heatDisinfectState )
{
- heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_1;
#ifndef IGNORE_CONC_PUMP_IN_HEAT_DISINFECT
// Turn the pumps on in reverse
- setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN );
- setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, CONC_PUMPS_REVERSE_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP1_ACID, ACID_PUMP_SPEED_ML_PER_MIN );
+ setConcentratePumpTargetSpeed( CONCENTRATEPUMPS_CP2_BICARB, BICARB_PUMP_SPEED_ML_PER_MIN );
// During R1 to R2 disinfect, the concentrate pumps turn on
requestConcentratePumpsOn( CONCENTRATEPUMPS_CP1_ACID );
requestConcentratePumpsOn( CONCENTRATEPUMPS_CP2_BICARB );
#endif
}
- else
- {
- heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2;
- }
}
+ else if ( ( TRUE == isPartialDisinfectInProgress ) && ( ThdTemp > HEAT_DISINFECT_START_TEMPERATURE_C ) )
+ {
+ status = HEAT_DISINFECT_DISINFECT_IN_PROGRESS;
+ }
// If heat disinfect temperature has been reached, check if this stage of heat disinfect is done
if ( ( TRUE == isPartialDisinfectInProgress ) && ( TRUE == didTimeout( heatDisinfectTimer, HEAT_DISINFECT_TIME_MS ) ) )
{
// Done with this stage of heat disnfect. Reset the variables
- status = HEAT_DISINFECT_COMPLETE;
+ // Target disinfect time is the time that is published to the UI and when there is
+ // no disinfect count down, this variable is set to 0. When the target time is 0, the UI
+ // hides the timer on the UI disinfect screen
+ targetDisinfectTime = 0;
+ status = HEAT_DISINFECT_COMPLETE;
isPartialDisinfectInProgress = FALSE;
}
@@ -2073,8 +2088,12 @@
if ( ( DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 == heatDisinfectState ) ||
( DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1 == heatDisinfectState ) )
{
- uiData.heatDisinfectTargetTime = HEAT_DISINFECT_TIME_MS;
- uiData.heatDisinfectCountdownTime = HEAT_DISINFECT_TIME_MS - calcTimeSince( heatDisinfectTimer );
+ // If the disinfect target time is 0, meaning the actual disinfect has not started, set the count down to 0, otherwise, publish
+ // the actual value
+ U32 countDown = ( HEAT_DISINFECT_TIME_MS == targetDisinfectTime ? ( targetDisinfectTime - calcTimeSince( heatDisinfectTimer) ) : 0 );
+
+ uiData.heatDisinfectTargetTime = targetDisinfectTime;
+ uiData.heatDisinfectCountdownTime = countDown / 1000; // The count down is converted into seconds since the UI does not work with milliseconds
data.R1FillLevel = R1HeatDisinfectVol;
data.R2FillLevel = R2HeatDisinfectVol;
}
Index: firmware/App/Modes/ModeInitPOST.c
===================================================================
diff -u -r2fff37fa585181917705645494549b5fd4a4d522 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 2fff37fa585181917705645494549b5fd4a4d522)
+++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -16,6 +16,8 @@
***************************************************************************/
#include "Accel.h"
+#include "ConcentratePumps.h"
+#include "ConductivitySensors.h"
#include "CPLD.h"
#include "DrainPump.h"
#include "Fans.h"
@@ -26,6 +28,8 @@
#include "NVDataMgmt.h"
#include "OperationModes.h"
#include "Pressures.h"
+#include "Reservoirs.h"
+#include "ROPump.h"
#include "RTC.h"
#include "SystemCommMessages.h"
#include "TemperatureSensors.h"
@@ -98,10 +102,6 @@
#ifdef SKIP_POST
postState = DG_POST_STATE_COMPLETED;
#endif
-#ifdef DONT_SKIP_NV_POST
- // Only run NVDataMgmt POST
- postState = DG_POST_STATE_NVDATAMGMT;
-#endif
break;
case DG_POST_STATE_FW_COMPATIBILITY:
@@ -129,14 +129,12 @@
postState = handlePOSTStatus( testStatus );
break;
+ // NOTE: all the actuators and sensors must execute their POST after NVDataMgmt
+ // NVDataMgmt must load all the calibration data into RAM so the actuators
+ // can query their corresponding calibration values successfully
case DG_POST_STATE_TEMPERATURE_SENSORS:
-#ifdef DONT_SKIP_NV_POST
- // Skip the rest of the POSTs
- postState = DG_POST_STATE_COMPLETED;
-#else
testStatus = execTemperatureSensorsSelfTest();
postState = handlePOSTStatus( testStatus );
-#endif
break;
case DG_POST_STATE_ACCELEROMETER:
@@ -153,29 +151,46 @@
postState = handlePOSTStatus( testStatus );
break;
-#ifdef _VECTORCAST_
- case DG_POST_DRAIN_PUMP:
+ case DG_POST_STATE_RO_PUMP:
+ testStatus = execROPumpSelfTest();
+ postState = handlePOSTStatus( testStatus );
+ break;
+
+ case DG_POST_STATE_DRAIN_PUMP:
testStatus = execDrainPumpSelfTest();
postState = handlePOSTStatus( testStatus );
break;
-// To be able to run integration test in VectorCAST.
-// Not all the fans and thermistors have been implemented so POST might fail
- case DG_POST_STATE_THERMISTORS:
- testStatus = execThermistorsSelfTest();
+
+ case DG_POST_STATE_CONCENTRATE_PUMPS:
+ testStatus = execConcenratePumpsSelfTest();
postState = handlePOSTStatus( testStatus );
break;
- case DG_POST_STATE_FANS:
- testStatus = execFansSelfTest();
+ case DG_POST_STATE_CONDUCTIVITY_SENSORS:
+ testStatus = execConductivitySensorsSelfTest();
postState = handlePOSTStatus( testStatus );
break;
+ case DG_POST_STATE_RESERVOIRS:
+ testStatus = execReservoirsSelfTest();
+ postState = handlePOSTStatus( testStatus );
+ break;
+
case DG_POST_STATE_UV_REACTORS:
testStatus = execUVReactorsSelfTest();
postState = handlePOSTStatus( testStatus );
break;
-#endif
+ case DG_POST_STATE_THERMISTORS:
+ testStatus = execThermistorsSelfTest();
+ postState = handlePOSTStatus( testStatus );
+ break;
+
+ case DG_POST_STATE_FANS:
+ testStatus = execFansSelfTest();
+ postState = handlePOSTStatus( testStatus );
+ break;
+
case DG_POST_STATE_WATCHDOG:
testStatus = execWatchdogTest();
postState = handlePOSTStatus( testStatus );
@@ -184,7 +199,8 @@
// Should be last POST (and last POST test must be a test that completes in a single call)
case DG_POST_STATE_LOAD_CELL:
testStatus = execLoadCellsSelfTest();
- handlePOSTStatus( testStatus ); // ignoring return value because last test
+ handlePOSTStatus( testStatus );
+ // Ignoring return value because last test
if ( TRUE == tempPOSTPassed )
{
postState = DG_POST_STATE_COMPLETED;
Index: firmware/App/Modes/ModeRecirculate.c
===================================================================
diff -u -rc2fe204db1b8926994b5eee78afa1b516c97d02c -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Modes/ModeRecirculate.c (.../ModeRecirculate.c) (revision c2fe204db1b8926994b5eee78afa1b516c97d02c)
+++ firmware/App/Modes/ModeRecirculate.c (.../ModeRecirculate.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -93,6 +93,10 @@
setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO );
setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO );
setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO );
+#ifndef V_2_SYSTEM
+ setValveStateDelayed( VRD1, VALVE_STATE_CLOSED, 0 );
+ setValveStateDelayed( VRD2, VALVE_STATE_CLOSED, 0 );
+#endif
signalDrainPumpHardStop();
requestConcentratePumpsOff( CONCENTRATEPUMPS_CP1_ACID );
@@ -105,7 +109,7 @@
// NOTE: The target flow rate should be set prior to setting the start primary heater
// because the initial guess in the heaters driver needs the target flow to calculate
// the new PWMs for the main and small primary heaters
- setROPumpTargetFlowRate( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI );
+ setROPumpTargetFlowRate( TARGET_FLUSH_LINES_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI );
startPrimaryHeater();
#ifndef _VECTORCAST_
Index: firmware/App/Services/AlarmMgmtSWFaults.h
===================================================================
diff -u -r8b0c842f94e3c94cecf62f0f913e429def8e5efa -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision 8b0c842f94e3c94cecf62f0f913e429def8e5efa)
+++ firmware/App/Services/AlarmMgmtSWFaults.h (.../AlarmMgmtSWFaults.h) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -63,11 +63,11 @@
SW_FAULT_ID_PI_CTRL_INVALID_SIGNAL,
SW_FAULT_ID_NVDATAMGMT_EXEC_INVALID_STATE,
SW_FAULT_ID_NVDATAMGMT_INVALID_SELF_TEST_STATE,
- SW_FAULT_ID_TEMPERATURE_SENSORS_INVALID_SELF_TEST_STATE, // 35
- SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE,
+ SW_FAULT_ID_TEMPERATURE_SENSORS_EXEC_INVALID_STATE, // 35
SW_FAULT_ID_HEATERS_SELF_TEST_INVALID_STATE,
SW_FAULT_ID_HEATERS_PRIMARY_HEATER_EXEC_INVALID_STATE,
- SW_FAULT_ID_HEATERS_TRIMMER_HEATER_EXEC_INVALID_STATE,
+ SW_FAULT_ID_HEATERS_TRIMMER_HEATER_EXEC_INVALID_STATE,
+ SW_FAULT_ID_DG_PRESSURES_INVALID_SELF_TEST_STATE,
SW_FAULT_ID_VALVES_INVALID_VALVE_STATE_NAME, // 40
SW_FAULT_ID_VALVES_INVALID_VALVE_ID,
SW_FAULT_ID_CAN_PARITY_ERROR,
@@ -89,10 +89,10 @@
SW_FAULT_ID_UV_REACTORS_INVALID_EXEC_STATE,
SW_FAULT_ID_UV_REACTORS_INVALID_SELF_TEST_STATE,
SW_FAULT_ID_THERMISTORS_INVALID_EXEC_STATE, // 60
- SW_FAULT_ID_THERMISTORS_INVALID_SELF_TEST_STATE,
SW_FAULT_ID_INVALID_THERMISTOR_SELECTED,
SW_FAULT_ID_FAN_INVALID_EXEC_STATE,
- SW_FAULT_ID_FAN_INVALID_SELF_TEST_STATE,
+ SW_FAULT_ID_DG_CHEM_DISINFECT_INVALID_EXEC_STATE,
+ SW_FAULT_ID_DG_INVALID_SWITCH_ID,
SW_FAULT_ID_INVALID_FAN_SELECTED, // 65
SW_FAULT_ID_RO_PUMP_INVALID_EXEC_STATE,
SW_FAULT_ID_RO_PUMP_INVALID_FLOW_RATE_SET,
@@ -124,7 +124,6 @@
SW_FAULT_ID_INVALID_VOLTAGE_MONITOR_STATE,
SW_FAULT_ID_INVALID_MONITORED_VOLTAGE_ID,
SW_FAULT_ID_INVALID_LOAD_CELL_ID, // 95
- SW_FAULT_ID_DG_CHEM_DISINFECT_INVALID_EXEC_STATE,
NUM_OF_SW_FAULT_IDS
} SW_FAULT_ID_T;
Index: firmware/App/Services/FPGA.c
===================================================================
diff -u -r5a36a768d11cc597a36b894c1fb3a5e5590130f1 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/FPGA.c (.../FPGA.c) (revision 5a36a768d11cc597a36b894c1fb3a5e5590130f1)
+++ firmware/App/Services/FPGA.c (.../FPGA.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -79,6 +79,11 @@
#define FPGA_FLUIDLEAK_STATE_MASK 0x0004 ///< Bit mask for fluid leak detector.
+#define FLUID_DOOR_SWITCH_MASK 0x08 ///< Fluid door switch bit mask.
+#define DIALYSATE_CAP_SWITCH_MASK 0x10 ///< Dialysate cap switch bit mask.
+#define CONCENTRATE_CAP_SWITCH_MASK 0x1A ///< Concentrate cap switch bit mask.
+#define FPGA_POWER_STATUS_MASK 0x40 ///< FPGA power status bit mask.
+
// FPGA header struct.
#pragma pack(push,1)
typedef struct
@@ -245,6 +250,7 @@
static void startDMAReceiptOfReadResp( void );
static void consumeUnexpectedData( void );
+static void monitorFPGAPowerStatus( void );
/*********************************************************************//**
* @brief
@@ -922,6 +928,11 @@
}
}
+static void monitorFPGAPowerStatus( void )
+{
+ BOOL isFPGAPowered = (BOOL)( fpgaSensorReadings.fpgaGPIO & FPGA_POWER_STATUS_MASK );
+}
+
/*********************************************************************//**
* @brief
* The setFPGAValveStates function sets the DG valve states with a 16-bit
@@ -1843,4 +1854,43 @@
return ( 0 == noFluidLeakDetected ? FALSE : TRUE );
}
+/*********************************************************************//**
+ * @brief
+ * The getFPGAGFluidDoorStatus function gets the FPGA fluid door status
+ * bit.
+ * @details Inputs: fpgaSensorReadings
+ * @details Outputs: none
+ * @return fluid door status bit
+ *************************************************************************/
+U08 getFPGAGFluidDoorStatus( void )
+{
+ return ( fpgaSensorReadings.fpgaGPIO & FLUID_DOOR_SWITCH_MASK );
+}
+
+/*********************************************************************//**
+ * @brief
+ * The getFPGADialysateCapStatus function gets the FPGA dialysate cap status
+ * bit.
+ * @details Inputs: fpgaSensorReadings
+ * @details Outputs: none
+ * @return dialysate cap status bit
+ *************************************************************************/
+U08 getFPGADialysateCapStatus( void )
+{
+ return ( fpgaSensorReadings.fpgaGPIO & DIALYSATE_CAP_SWITCH_MASK );
+}
+
+/*********************************************************************//**
+ * @brief
+ * The getFPGAConcentrateCapStatus function gets the FPGA concentrate cap
+ * status bit.
+ * @details Inputs: fpgaSensorReadings
+ * @details Outputs: none
+ * @return concentrate cap status bit
+ *************************************************************************/
+U08 getFPGAConcentrateCapStatus( void )
+{
+ return ( fpgaSensorReadings.fpgaGPIO & CONCENTRATE_CAP_SWITCH_MASK );
+}
+
/**@}*/
Index: firmware/App/Services/FPGA.h
===================================================================
diff -u -r5a36a768d11cc597a36b894c1fb3a5e5590130f1 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/FPGA.h (.../FPGA.h) (revision 5a36a768d11cc597a36b894c1fb3a5e5590130f1)
+++ firmware/App/Services/FPGA.h (.../FPGA.h) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -134,8 +134,12 @@
U16 getFPGATimerCount( void );
-BOOL noFPGAFluidLeakDetected( void);
+BOOL noFPGAFluidLeakDetected( void );
+U08 getFPGAGFluidDoorStatus( void );
+U08 getFPGADialysateCapStatus( void );
+U08 getFPGAConcentrateCapStatus( void );
+
/**@}*/
#endif
Index: firmware/App/Services/SystemComm.c
===================================================================
diff -u -rc55d371408bdf962de525a47bc8541d5b43414a3 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision c55d371408bdf962de525a47bc8541d5b43414a3)
+++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -249,14 +249,6 @@
{
canTransmit( canREG1, lastCANPacketSentChannel, lastCANPacketSent );
}
-#ifdef DEBUG_ENABLED
- {
- char debugStr[100];
- strcpy( debugStr, "SystemComm-DG resend Last Frame.\n" );
- sendDebugData( (U08*)debugStr, strlen(debugStr) );
- sendDebugDataToUI( (U08*)debugStr );
- }
-#endif
}
// we must be only node on CAN bus - nobody is ACKing our transmitted frames
else
@@ -265,11 +257,6 @@
canXmitRetryCtr = MAX_XMIT_RETRIES;
signalCANXmitsCompleted(); // clear pending xmit flag
clearCANXmitBuffers(); // clear xmit buffers - nothing is going out right now
-#ifdef DEBUG_ENABLED
- char debugStr[100];
- strcpy( debugStr, "SystemComm-DG is only node.\n" );
- sendDebugData( (U08*)debugStr, strlen(debugStr) );
-#endif
} // end - are we retrying xmit or are we alone on CAN bus
} // end - pending xmit timeout?
} // end - transmit in progress or not
@@ -567,13 +554,12 @@
else
{
signalCANXmitsCompleted();
- // TODO - shouldn't get here, but let's see if we do
- SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)mBox )
+ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_CAN_TX_FAULT, (U32)mBox )
}
}
else
- { // TODO - shouldn't get here - just testing - set first data to new s/w fault enum later
- SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, (U32)buffer, (U32)dataSize )
+ {
+ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_CAN_MESSAGE_SIZE, (U32)dataSize )
}
}
@@ -839,9 +825,7 @@
if ( TRUE == didTimeout( timeOfLastHDCheckIn, HD_COMM_TIMEOUT_IN_MS ) )
{
hdIsCommunicating = FALSE;
-#ifndef DEBUG_ENABLED
- activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT ); // TODO - add this alarm if we're in middle of a treatment? or if in a mode that comm loss would impact badly?
-#endif
+ activateAlarmNoData( ALARM_ID_HD_COMM_TIMEOUT );
}
}
@@ -860,14 +844,6 @@
{
SET_ALARM_WITH_1_U32_DATA( ALARM_ID_COMM_TOO_MANY_BAD_CRCS, 2 ); // 2 for DG
}
-#ifdef DEBUG_ENABLED
- {
- char debugStr[100];
-
- strcpy( debugStr, "SystemComm-DG-Bad Msg CRC.\n" );
- sendDebugDataToUI( (U08*)debugStr );
- }
-#endif
}
/*********************************************************************//**
@@ -1057,6 +1033,10 @@
handleUIClockSyncRequest( message );
break;
+ case MSG_ID_HD_DG_POST_RESULT_REQUEST:
+ handleDGPOSTResultRequest( message );
+ break;
+
case MSG_ID_UI_REQUEST_SERVICE_INFO:
handleDGServiceScheduleRequest( message );
break;
@@ -1288,6 +1268,10 @@
handleSetFluidLeakStateDetectorOverrideRequest( message );
break;
+ case MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE:
+ handleFilterFlushTimePeriodOverride(message);
+ break;
+
default:
// TODO - unrecognized message ID received - ignore
break;
Index: firmware/App/Services/SystemCommMessages.c
===================================================================
diff -u -rc2fe204db1b8926994b5eee78afa1b516c97d02c -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision c2fe204db1b8926994b5eee78afa1b516c97d02c)
+++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -761,13 +761,17 @@
*************************************************************************/
void handleAlarmClear( MESSAGE_T *message )
{
+ BOOL result = FALSE;
+
if ( message->hdr.payloadLen == sizeof( U32 ) )
{
U32 alarmId;
+ result = TRUE;
memcpy(&alarmId, message->payload, sizeof( U32 ) );
clearAlarm( (ALARM_ID_T)alarmId );
}
+ sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_HD, result );
}
/*********************************************************************//**
@@ -3233,6 +3237,40 @@
/*********************************************************************//**
* @brief
+* The handleDGPOSTResultRequest function handles a request to report DG
+* POST results.
+* @details Inputs: none
+* @details Outputs: message handled
+* @param message a pointer to the message to handle
+* @return none
+*************************************************************************/
+void handleDGPOSTResultRequest( MESSAGE_T *message )
+{
+ BOOL status = FALSE;
+ BOOL result = FALSE;
+ U08* payloadPtr = message->payload;
+
+ if ( 0 == message->hdr.payloadLen )
+ {
+ if ( TRUE == isPOSTCompleted() )
+ {
+ status = TRUE;
+ if ( TRUE == isPOSTPassed() )
+ {
+ result = TRUE;
+ }
+ sendPOSTFinalResult( result );
+ }
+ }
+ // If can't respond to request, NAK the message
+ if ( status != TRUE )
+ {
+ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, status );
+ }
+}
+
+/*********************************************************************//**
+* @brief
* The handleSetDGCalibrationRecord function handles a request to set the DG
* calibration data record.
* @details Inputs: none
@@ -3503,6 +3541,38 @@
}
/*********************************************************************//**
+ * @brief
+ * The handleFilterFlushTimePeriodOverride function handles a request
+ * to override the filter flush time period value.
+ * @details Inputs: none
+ * @details Outputs: message handled
+ * @param message a pointer to the message to handle
+ * @return none
+ *************************************************************************/
+void handleFilterFlushTimePeriodOverride( MESSAGE_T *message )
+{
+ TEST_OVERRIDE_PAYLOAD_T payload;
+ BOOL result = FALSE;
+
+ // verify payload length
+ if ( sizeof( TEST_OVERRIDE_PAYLOAD_T ) == message->hdr.payloadLen )
+ {
+ memcpy( &payload, message->payload, sizeof( TEST_OVERRIDE_PAYLOAD_T ) );
+ if ( FALSE == payload.reset )
+ {
+ result = testSetFilterFlushTimePeriodOverride( payload.state.u32 );
+ }
+ else
+ {
+ result = testResetFilterFlushTimePeriodOverride();
+ }
+ }
+
+ // respond to request
+ sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result );
+}
+
+/*********************************************************************//**
* @brief
* The handleStartStopDGChemicalDisinfect function handles a request to start
* or stop DG chemical disinfect mode.
Index: firmware/App/Services/SystemCommMessages.h
===================================================================
diff -u -rc55d371408bdf962de525a47bc8541d5b43414a3 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision c55d371408bdf962de525a47bc8541d5b43414a3)
+++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -109,6 +109,9 @@
// MSG_ID_DG_UV_REACTORS_DATA
BOOL broadcastUVReactorsData( UV_REACTORS_DATA_T *uvReactorsData );
+// MSG_ID_DG_HEAT_DISINFECT_DATA
+BOOL broadcastHeatDisinfectData( MODE_HEAT_DISINFECT_DATA_T *heatDisinfectData );
+
// MSG_ID_DG_FILTER_FLUSH_PROGRESS
BOOL broadcastFilterFlushData( U32 timeout, U32 countdown );
@@ -178,12 +181,6 @@
// MSG_ID_DG_START_STOP_TRIMMER_HEATER_CMD
void handleStartStopTrimmerHeaterCmd( MESSAGE_T *message );
-// MSG_ID_DG_UV_REACTORS_DATA
-BOOL broadcastUVReactorsData( UV_REACTORS_DATA_T *uvReactorsData );
-
-// MSG_ID_DG_HEAT_DISINFECT_DATA
-BOOL broadcastHeatDisinfectData( MODE_HEAT_DISINFECT_DATA_T *heatDisinfectData );
-
// MSG_ID_DG_SEND_CALIBRATION_DATA
BOOL sendDGCalibrationRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* calRcrdAddress );
@@ -357,6 +354,9 @@
// MSG_ID_UI_DG_SET_RTC_REQUEST
void handleUIClockSyncRequest( MESSAGE_T *message );
+// MSG_ID_HD_DG_POST_RESULT_REQUEST
+void handleDGPOSTResultRequest( MESSAGE_T *message );
+
// MSG_ID_DG_SET_CALIBRATION_DATA
void handleSetDGCalibrationRecord( MESSAGE_T *message );
@@ -384,6 +384,9 @@
// MSG_ID_DG_START_STOP_CHEM_DSINFECT
BOOL handleStartStopDGChemicalDisinfect( MESSAGE_T *message );
+// MSG_ID_FILTER_FLUSH_TIME_PERIOD_OVERRIDE
+void handleFilterFlushTimePeriodOverride( MESSAGE_T *message );
+
/**@}*/
#endif
Index: firmware/App/Services/WatchdogMgmt.c
===================================================================
diff -u -r97e0100921ccad633b39b509a93a7237e4d80446 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision 97e0100921ccad633b39b509a93a7237e4d80446)
+++ firmware/App/Services/WatchdogMgmt.c (.../WatchdogMgmt.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -15,7 +15,9 @@
*
***************************************************************************/
-#include "CPLD.h"
+#include "CPLD.h"
+#include "InternalADC.h"
+#include "OperationModes.h"
#include "SystemCommMessages.h"
#include "Timers.h"
#include "WatchdogMgmt.h"
@@ -28,9 +30,13 @@
// ********** private definitions **********
#define MIN_WATCHDOG_PET_INTERVAL_MS 45 ///< Minimum watchdog pet interval.
-#define WATCHDOG_POST_TIMEOUT_MS 100 ///< Watchdog POST timeout in ms.
-#define WATCHDOG_RECOVERY_TIME_MS 250 ///< Watchdog recovery time in ms.
+#define WATCHDOG_POST_TIMEOUT_MS 500 ///< Watchdog POST timeout in ms.
+#define WATCHDOG_RECOVERY_TIME_MS 500 ///< Watchdog recovery time in ms.
+
+#define MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED 5.0 ///< Maximum voltage on 24V line when watchdog is expired. // TODO - check w/ Systems. Takes time for V to bleed off. Had to raise to 5V.
+#define MIN_24V_LEVEL_ON_WATCHDOG_RECOVER 22.6 ///< Minimum voltage on 24V line when watchdog is recovered.
+
/// List of watchdog states.
typedef enum Button_Self_Test_States
{
@@ -111,7 +117,8 @@
if ( PIN_SIGNAL_LOW == getCPLDWatchdogExpired() )
{
// ignore expired watchdog until after watchdog POST
- if ( WATCHDOG_SELF_TEST_STATE_COMPLETE == watchdogSelfTestState )
+ if ( ( WATCHDOG_SELF_TEST_STATE_COMPLETE == watchdogSelfTestState ) ||
+ ( getCurrentOperationMode() != DG_MODE_INIT ) )
{
#ifndef DEBUG_ENABLED
activateAlarmNoData( ALARM_ID_WATCHDOG_EXPIRED );
@@ -163,20 +170,42 @@
}
if ( PIN_SIGNAL_LOW == getCPLDWatchdogExpired() )
{
- watchdogSelfTestStatus = SELF_TEST_STATUS_PASSED;
+ F32 v24 = getIntADCVoltageConverted( INT_ADC_MAIN_24_VOLTS );
+
+ // Verify 24V is down when w.d. expired
+ if ( v24 > MAX_24V_LEVEL_ON_WATCHDOG_EXPIRED )
+ {
+ SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 2.0, v24 );
+ watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED;
+ }
}
else
{
- activateAlarmNoData( ALARM_ID_WATCHDOG_POST_TEST_FAILED );
+ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 1 );
watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED;
}
- watchdogSelfTestTimerCount = getMSTimerCount();
- watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_RECOVER;
+ watchdogSelfTestTimerCount = getMSTimerCount();
+ watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_RECOVER;
break;
case WATCHDOG_SELF_TEST_STATE_RECOVER:
if ( TRUE == didTimeout( watchdogSelfTestTimerCount, WATCHDOG_RECOVERY_TIME_MS ) )
{
+ if ( getCPLDWatchdogExpired() == PIN_SIGNAL_HIGH )
+ {
+ F32 v24 = getIntADCVoltageConverted( INT_ADC_MAIN_24_VOLTS );
+
+ // Verify 24V is down when w.d. recovered
+ if ( v24 < MIN_24V_LEVEL_ON_WATCHDOG_RECOVER )
+ {
+ SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_WATCHDOG_POST_TEST_FAILED, 3.0, v24 );
+ watchdogSelfTestStatus = SELF_TEST_STATUS_FAILED;
+ }
+ else
+ {
+ watchdogSelfTestStatus = SELF_TEST_STATUS_PASSED;
+ }
+ }
result = watchdogSelfTestStatus;
watchdogSelfTestState = WATCHDOG_SELF_TEST_STATE_COMPLETE;
}
@@ -266,7 +295,7 @@
}
else
{
- activateAlarmNoData( ALARM_ID_DG_SOFTWARE_FAULT );
+ SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_INVALID_TASK, task );
}
return result;
Index: firmware/source/sys_main.c
===================================================================
diff -u -r2fff37fa585181917705645494549b5fd4a4d522 -ra79db345deaaeef0f1b619dc49d031fdae22d7e6
--- firmware/source/sys_main.c (.../sys_main.c) (revision 2fff37fa585181917705645494549b5fd4a4d522)
+++ firmware/source/sys_main.c (.../sys_main.c) (revision a79db345deaaeef0f1b619dc49d031fdae22d7e6)
@@ -85,6 +85,7 @@
#include "ROPump.h"
#include "RTC.h"
#include "SafetyShutdown.h"
+#include "Switches.h"
#include "SystemComm.h"
#include "TaskBG.h"
#include "TemperatureSensors.h"
@@ -192,6 +193,7 @@
initUVReactors();
initAccel();
initRTC();
+ initSwitches();
initCommBuffers();
initMsgQueues();
initSystemComm();