Index: firmware/.launches/DG.launch =================================================================== diff -u -r3f7d30b23906496854054949d4491f3bae6ef3c4 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/.launches/DG.launch (.../DG.launch) (revision 3f7d30b23906496854054949d4491f3bae6ef3c4) +++ firmware/.launches/DG.launch (.../DG.launch) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -1,12 +1,38 @@ +<<<<<<< HEAD +======= +<<<<<<< HEAD + + + + + + + + + + + + + + + + + + + + + +======= +>>>>>>> staging @@ -15,6 +41,7 @@ +>>>>>>> staging Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r2e3b3b2034ee5afb52a8630568145c9705afff9f -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 2e3b3b2034ee5afb52a8630568145c9705afff9f) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -47,12 +47,17 @@ DRP_SPEED_RPM_TO_ADC_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ///< Drain pump minimum RPM to DAC conversion. #define DRAIN_PUMP_MAX_DAC ( ( (F32)MAX_DRAIN_PUMP_RPM * \ DRP_SPEED_RPM_TO_ADC_FACTOR ) + FLOAT_TO_INT_ROUNDUP_OFFSET ) ///< Drain pump maximum RPM to DAC conversion. +#define DRP_SPEED_ADC_TO_RPM_CONVERSION 12.94 // TODO remove ///< Conversion factor from ADC counts to RPM for Drain pump. +#define DRP_SPEED_RPM_TO_ADC_FACTOR ( 1.0 / DRP_SPEED_ADC_TO_RPM_CONVERSION ) // TODO remove ///< Conversion factor from RPM to ADC counts for Drain pump. + #define DRAIN_PUMP_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_PRIORITY_INTERVAL ) ///< Interval (ms/task time) at which the Drain Pump data is published on the CAN bus. #define DRP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Drain pump is controlled. -#define DRP_SPEED_ADC_TO_RPM_CONVERSION 12.94 ///< Conversion factor from ADC counts to RPM for Drain pump. -#define DRP_SPEED_RPM_TO_ADC_FACTOR ( 1.0 / DRP_SPEED_ADC_TO_RPM_CONVERSION ) ///< Conversion factor from RPM to ADC counts for Drain pump. +#define RPM_2_DAC_SLOPE 0.0547 ///< RPM to DAC conversion slope. +#define RPM_2_DAC_INTERCEPT 2.9968 ///< RPM to DAC conversion intercept. +#define GET_RPM_2_DAC_CONVERSION(rpm) ( ( RPM_2_DAC_SLOPE * rpm ) - RPM_2_DAC_INTERCEPT + \ + FLOAT_TO_INT_ROUNDUP_OFFSET ) ///< RPM to DAC conversion equation. #define TOGGLE_PERIOD_RESOLUTION_SECONDS 0.000005 ///< Toggle period to resolution in seconds. #define ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION 4 ///< Rotational to toggle period conversion coefficient. @@ -174,8 +179,10 @@ if ( ( 0 == rpm ) || ( ( rpm >= MIN_DRAIN_PUMP_RPM ) && ( rpm <= MAX_DRAIN_PUMP_RPM ) ) ) { - drainPumpDAC = (U32)((F32)rpm * DRP_SPEED_RPM_TO_ADC_FACTOR + FLOAT_TO_INT_ROUNDUP_OFFSET); + //drainPumpDAC = (U32)((F32)rpm * DRP_SPEED_RPM_TO_ADC_FACTOR + FLOAT_TO_INT_ROUNDUP_OFFSET); //TODO remove. Yes, it is temporary don't laugh + drainPumpDAC = (U32)GET_RPM_2_DAC_CONVERSION(rpm); + targetDrainPumpRPM = rpm; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; Index: firmware/App/Controllers/LoadCell.c =================================================================== diff -u -r7b6b599a6f98241bc51bbee65b736b92cb881f01 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 7b6b599a6f98241bc51bbee65b736b92cb881f01) +++ firmware/App/Controllers/LoadCell.c (.../LoadCell.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -34,16 +34,17 @@ // TODO check the maximum weight on the load cells in tare. There was 1500 grams limit // but it has been removed. Check the load cells data sheet. -#define LOAD_CELL_REPORT_PERIOD (100 / TASK_PRIORITY_INTERVAL) ///< Broadcast load cell values message every 100 ms. +#define LOAD_CELL_REPORT_PERIOD (100 / TASK_PRIORITY_INTERVAL) ///< Broadcast load cell values message every 100 ms. /// Conversion factor from ADC counts to grams. -static const F32 ADC2GRAM = (0.0894 * 1.1338); -#define LOAD_CELL_ZERO_OFFSET -1500.0 ///< Zero offset (in grams). TODO - right now, this is empty reservoir weight. -#define LOAD_CELL_FILTER_ALPHA 0.05 ///< Alpha factor for the alpha filter used on load cell readings. +static const F32 ADC2GRAM = (0.0894 * 1.1338); +#define LOAD_CELL_FILTER_ALPHA 0.05 ///< Alpha factor for the alpha filter used on load cell readings. -#define SIZE_OF_SMALL_LOAD_CELL_AVG 100 ///< Small load cell moving average has 100 raw samples @ 10ms intervals (1-second). -#define SIZE_OF_LARGE_LOAD_CELL_AVG 40 ///< Large load cell moving average has 40 samples from small filter @ 100ms intervals (4-second). +#define SIZE_OF_SMALL_LOAD_CELL_AVG 100 ///< Small load cell moving average has 100 raw samples @ 10ms intervals (1-second). +#define SIZE_OF_LARGE_LOAD_CELL_AVG 40 ///< Large load cell moving average has 40 samples from small filter @ 100ms intervals (4-second). -#define LOAD_CELL_ADC_ERROR_PERSISTENCE 500 ///< Alarm persistence period (in ms) for load cell ADC errors. +#define LOAD_CELL_ADC_ERROR_PERSISTENCE 500 ///< Alarm persistence period (in ms) for load cell ADC errors. +#define EMPTY_RESERVOIR_WEIGHT_GRAMS 1600 ///< Reservoirs empty weight in grams. +#define MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_TARE_GRAMS 300 ///< Max allowed extra weight before tare in grams. /// Load cell data structure. typedef struct @@ -53,13 +54,13 @@ F32 autoCalOffset; ///< Load cell auto-calibration offset F32 loadCellVelocity_g_min; ///< Velocity (in g/min) of load cell. - F32 smallFilterReadings[ SIZE_OF_SMALL_LOAD_CELL_AVG ]; ///< Load cell samples for small load cell moving average - F32 smallFilterTotal; ///< Small filter rolling total - used to calc small load cell moving average - F32 smallFilteredWeight; ///< Load cell small filtered (100 100Hz raw sample) weight + F32 smallFilterReadings[ SIZE_OF_SMALL_LOAD_CELL_AVG ]; ///< Load cell samples for small load cell moving average. + F64 smallFilterTotal; ///< Small filter rolling total - used to calc small load cell moving average. + F32 smallFilteredWeight; ///< Load cell small filtered (100 100Hz raw sample) weight. - F32 largeFilterReadings[ SIZE_OF_LARGE_LOAD_CELL_AVG ]; ///< Load cell samples for large load cell moving average - F32 largeFilterTotal; ///< Large filter rolling total - used to calc small load cell moving average - F32 largeFilteredWeight; ///< Load cell large filtered (40 10Hz filtered sample) weight + F32 largeFilterReadings[ SIZE_OF_LARGE_LOAD_CELL_AVG ]; ///< Load cell samples for large load cell moving average. + F32 largeFilterTotal; ///< Large filter rolling total - used to calc small load cell moving average. + F32 largeFilteredWeight; ///< Load cell large filtered (40 10Hz filtered sample) weight. } LOADCELL_T; // ********** private data ********** @@ -74,8 +75,6 @@ static U32 largeReadingsIdx; ///< Index for next sample in load cell large rolling average sample array. static DG_LOAD_CELLS_CAL_RECORD_T loadCellsCalRecord; ///< Load cells calibration record. -// TODO - gain and offset for load cells should be read from NV Data calibration record. - // ********** private function prototypes ********** static U32 getLoadCellDataPublishInterval( void ); @@ -174,17 +173,39 @@ SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_LOAD_CELL_ADC_ERROR, ( a1 | a2 | b1 | b2 ) ) } + // Check if a new calibration is available + if ( isNewCalibrationRecordAvailable() == TRUE ) + { + // Get the new calibration data and check its validity + processCalibrationData(); + + // Zero the current tare values when new calibration data is available + loadcells[ LOAD_CELL_RESERVOIR_1_PRIMARY ].autoCalOffset = 0.0; + loadcells[ LOAD_CELL_RESERVOIR_1_BACKUP ].autoCalOffset = 0.0; + loadcells[ LOAD_CELL_RESERVOIR_2_PRIMARY ].autoCalOffset = 0.0; + loadcells[ LOAD_CELL_RESERVOIR_2_BACKUP ].autoCalOffset = 0.0; + } + // Rolling average of last 100 raw samples in small filter for ( ii = 0; ii < NUM_OF_LOAD_CELLS; ++ii ) { - loadcells[ ii ].weight.data = (F32)loadcells[ ii ].rawReading * ADC2GRAM + LOAD_CELL_ZERO_OFFSET - loadcells[ ii ].autoCalOffset; + loadcells[ ii ].weight.data = (F32)loadcells[ ii ].rawReading * ADC2GRAM; + // Apply the calibration factors to the data. + // load_cell_weight = fourth_order_coeff * (load_cell^4) + third_order_coeff * (load_cell^3) + second_order_coeff * (load_cell^2) + gain * load_cell + offset + loadcells[ ii ].weight.data = pow(loadcells[ ii ].weight.data, 4) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].fourthOrderCoeff + + pow(loadcells[ ii ].weight.data, 3) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].thirdOrderCoeff + + pow(loadcells[ ii ].weight.data, 2) * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].secondOrderCoeff + + loadcells[ ii ].weight.data * loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].gain + + loadCellsCalRecord.loadCells[ (CAL_DATA_DG_LOAD_CELLS_T)ii ].offset; + loadcells[ ii ].weight.data = loadcells[ ii ].weight.data - loadcells[ ii ].autoCalOffset; + loadcells[ ii ].loadCellVelocity_g_min = ( getLoadCellWeight( (LOAD_CELL_ID_T)ii ) - loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ] ) * (F32)SEC_PER_MIN; // Update small filter with new weight sample loadcells[ ii ].smallFilterTotal -= loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ]; loadcells[ ii ].smallFilterReadings[ smallReadingsIdx ] = getLoadCellWeight( (LOAD_CELL_ID_T)ii ); loadcells[ ii ].smallFilterTotal += getLoadCellWeight( (LOAD_CELL_ID_T)ii ); - loadcells[ ii ].smallFilteredWeight = loadcells[ ii ].smallFilterTotal / (F32)SIZE_OF_SMALL_LOAD_CELL_AVG; + loadcells[ ii ].smallFilteredWeight = (F32)( loadcells[ ii ].smallFilterTotal / (F64)SIZE_OF_SMALL_LOAD_CELL_AVG ); } smallReadingsIdx = INC_WRAP( smallReadingsIdx, 0, SIZE_OF_SMALL_LOAD_CELL_AVG - 1 ); @@ -255,8 +276,32 @@ *************************************************************************/ void tareLoadCell( LOAD_CELL_ID_T loadCellID ) { - // Add old auto calibration offset to get back to actual weight value - loadcells[ loadCellID ].autoCalOffset = ( loadcells[ loadCellID ].smallFilteredWeight + loadcells[ loadCellID ].autoCalOffset ); + BOOL isWeightOutOfRange = FALSE; + + F32 weight = getLoadCellSmallFilteredWeight( loadCellID ); + + // Check if the load cell is being tared for the first time + if ( fabs(loadcells[ loadCellID ].autoCalOffset) < NEARLY_ZERO ) + { + // For the first tare, the weight of the reservoir should be considered + // The current weight of the load cell should not be greater than the weight of the reservoir + the extra weight + F32 deltaWeight = fabs( weight - EMPTY_RESERVOIR_WEIGHT_GRAMS ); + isWeightOutOfRange = ( deltaWeight > MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_TARE_GRAMS ? TRUE : FALSE ); + } + else + { + isWeightOutOfRange = ( fabs(weight) > MAX_ALLOWED_EXTRA_WEIGHT_BEFORE_TARE_GRAMS ? TRUE : FALSE ); + } + + if ( FALSE == isWeightOutOfRange ) + { + // Add old auto calibration offset to get back to actual weight value + loadcells[ loadCellID ].autoCalOffset = ( loadcells[ loadCellID ].smallFilteredWeight + loadcells[ loadCellID ].autoCalOffset ); + } + else + { + SET_ALARM_WITH_1_F32_DATA( ALARM_ID_DG_LOAD_CELLS_TARE_WEIGHT_OUT_OF_RANGE, weight ) + } } /*********************************************************************//** Index: firmware/App/Controllers/TemperatureSensors.c =================================================================== diff -u -r8a4182663ef6b12e3fd6414c0c14158943cd4ce1 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 8a4182663ef6b12e3fd6414c0c14158943cd4ce1) +++ firmware/App/Controllers/TemperatureSensors.c (.../TemperatureSensors.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -256,12 +256,7 @@ // Persistent alarm for temperature sensors ADC error // When the FPGA read count does not increment for a period of time, it is considered as an internal error of the temperature sensors // driver. This is internal because FPGA does not error out if the FPGA read count does not increment. - initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD, - TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); - - // Persistent alarm for temperature sensors internal error flag - initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSOR_FAULT, TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD, - TEMPERATURE_SENSORS_ERROR_FLAG_PERSISTENT_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_TEMPERATURE_SENSORS_ADC_FAULT, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD, TEMPERATURE_SENSORS_FPGA_ERROR_PERSISTENT_PERIOD ); } /*********************************************************************//** @@ -782,9 +777,9 @@ rawADC = getFPGACD2Temp(); processTempSnsrsADCRead( TEMPSENSORS_CONDUCTIVITY_SENSOR_2, rawADC, errorCount, readCount ); - rawADC = getFPGATHDoTemp(); - errorCount = (U32)getFPGATHDoErrorCount(); - readCount = (U32)getFPGATHDoReadCount(); + rawADC = getFPGATRoTemp(); + errorCount = (U32)getFPGATRoErrorCount(); + readCount = (U32)getFPGATRoReadCount(); processTempSnsrsADCRead( TEMPSENSORS_OUTLET_REDUNDANT, rawADC, errorCount, readCount ); rawADC = getFPGATDiTemp(); @@ -815,7 +810,7 @@ processTempSnsrsADCRead( TEMPSENSORS_FPGA_BOARD_SENSOR, getFPGABoardTemp(), 0, ++simulatedCounter ); processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A1_B1, getFPGALoadCellsA1B1Temp(), getFPGAADC1ErrorCount(), getFPGAADC1ReadCount() ); processTempSnsrsADCRead( TEMPSENSORS_LOAD_CELL_A2_B2, getFPGALoadCellsA2B2Temp(), getFPGAADC2ErrorCount(), getFPGAADC2ReadCount() ); - processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THDO_RTD, getFPGATHDoInternalTemp(), getFPGATHDoErrorCount(), getFPGATHDoReadCount() ); + processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_THDO_RTD, getFPGATRoInternalTemp(), getFPGATRoErrorCount(), getFPGATRoReadCount() ); processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_TDI_RTD, getFPGATDiInternalTemp(), getFPGATDiErrorCount(), getFPGATDiReadCount() ); processTempSnsrsADCRead( TEMPSENSORS_INTERNAL_COND_TEMP_SENSOR, getFPGACondSnsrInternalTemp(), getFPGARTDErrorCount(), getFPGARTDReadCount() ); Index: firmware/App/Controllers/Valves.c =================================================================== diff -u -r379f78f1fad668d741b3ccf1e78c69f3fccc45b5 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Controllers/Valves.c (.../Valves.c) (revision 379f78f1fad668d741b3ccf1e78c69f3fccc45b5) +++ firmware/App/Controllers/Valves.c (.../Valves.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -39,7 +39,9 @@ static U32 valvesStatesPublicationTimerCounter = 0; ///< Timer counter used to schedule valve state publication to CAN bus. static U16 commandedValvesStates = ALL_VALVES_DEENERGIZED; ///< Initialize commanded valves states bit field. -static U32 valveStateMismatchCounter = 0; ///< Initialize valve state mismatch counter. +static U32 valveStateMismatchCounter = 0; ///< Initialize valve state mismatch counter. +static U32 pendingValveStateChanges[ NUM_OF_VALVES ]; ///< Delayed (pending) valve state changes. +static U32 pendingValveStateChangeCountDowns[ NUM_OF_VALVES ]; ///< Delayed (pending) valve state change count down timers (in task intervals). static OVERRIDE_U32_T valveStates[ NUM_OF_VALVES ]; ///< Currently commanded valves states. static OVERRIDE_U32_T valvesStatesPublishInterval = { VALVES_STATE_PUB_INTERVAL, VALVES_STATE_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms/task interval) at which to publish valves state to CAN bus. @@ -69,7 +71,10 @@ valveStates[ i ].data = DEENERGIZED; valveStates[ i ].ovInitData = DEENERGIZED; valveStates[ i ].ovData = DEENERGIZED; - valveStates[ i ].override = OVERRIDE_RESET; + valveStates[ i ].override = OVERRIDE_RESET; + + pendingValveStateChanges[ i ] = DEENERGIZED; + pendingValveStateChangeCountDowns[ i ] = 0; } commandedValvesStates = fromU32ArrayToU16(); setFPGAValveStates( commandedValvesStates ); // initially set all valves to de-energized state via FPGA @@ -85,10 +90,11 @@ * @return none *************************************************************************/ void execValves( void ) -{ +{ + U32 i; U16 readValvesStates = getFPGAValveStates(); // get valves states from FPGA - // verify read back FPGA valve states match last commanded valve states + // Verify read back FPGA valve states match last commanded valve states if ( readValvesStates != commandedValvesStates ) { valveStateMismatchCounter++; // increment valve state mismatch counter by 1 @@ -100,13 +106,27 @@ else { valveStateMismatchCounter = 0; + } + + // Handle pending delayed valve state changes + for ( i = 0; i < NUM_OF_VALVES; i++ ) + { + if ( pendingValveStateChangeCountDowns[ i ] > 0 ) + { + pendingValveStateChangeCountDowns[ i ]--; + if ( 0 == pendingValveStateChangeCountDowns[ i ] ) + { + valveStates[ i ].data = pendingValveStateChanges[ i ]; + pendingValveStateChanges[ i ] = DEENERGIZED; + } + } } - // set valves states (via FPGA) to currently commanded states + // Set valves states (via FPGA) to currently commanded states commandedValvesStates = fromU32ArrayToU16(); setFPGAValveStates( commandedValvesStates ); - // publish valve states on interval + // Publish valve states on interval publishValvesStates(); } @@ -143,7 +163,7 @@ if ( ( valveID == VPI ) || ( valveID == VBF ) || ( valveID == VSP ) ) { result = TRUE; - } + } #ifndef V_2_SYSTEM if ( ( VRD1 == valveID ) || ( VRD2 == valveID ) ) { @@ -152,7 +172,7 @@ #endif break; -#ifndef V_2_SYSTEM +#ifndef V_2_SYSTEM case VALVE_STATE_OPEN_C_TO_NC: if ( VPD == valveID ) { @@ -174,7 +194,7 @@ } break; #endif - + case VALVE_STATE_NOFILL_C_TO_NO: if ( valveID == VPO ) { @@ -193,13 +213,13 @@ if ( ( valveID == VDR ) || ( valveID == VRC ) ) { result = TRUE; - } + } #ifndef V_2_SYSTEM if ( VPD == valveID ) { result = TRUE; } -#endif +#endif break; case VALVE_STATE_RECIRC_C_TO_NC: @@ -316,12 +336,12 @@ case VALVE_STATE_DRAIN_C_TO_NC: vState = ENERGIZED; - break; + break; #else case VALVE_STATE_OPEN_C_TO_NC: vState = ENERGIZED; break; -#endif +#endif case VALVE_STATE_NOFILL_C_TO_NO: vState = DEENERGIZED; @@ -367,7 +387,7 @@ * @brief * The setValveState function sets the valve state for given valve. * @details Inputs: none - * @details Outputs: none + * @details Outputs: valveStates[], pendingValveStateChanges[], pendingValveStateChangeCountDowns[] * @param valveID ID of valve to set state for * @param valveStateName name of valve state to set given valve to * @return TRUE if new valve state is set for given valve ID, FALSE if not. @@ -382,14 +402,55 @@ { valveStates[ valveID ].data = convertValveStateNameToValveState( valveStateName ); result = TRUE; + // If a delayed state change is pending for this valve, cancel it + pendingValveStateChanges[ valveID ] = DEENERGIZED; + pendingValveStateChangeCountDowns[ valveID ] = 0; } } else { - // TODO - s/w fault + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) } return result; +} + +/*********************************************************************//** + * @brief + * The setValveStateDelayed function sets the valve state for given valve + * after a given delay. + * @details Inputs: pendingValveStateChangeCountDowns[] + * @details Outputs: pendingValveStateChangeCountDowns[], pendingValveStateChangeCountDowns[] + * @param valveID ID of valve to set state for + * @param valveStateName name of valve state to set given valve to + * @param delayMs delay duration (in ms) before actuation + * @return TRUE if new valve state is set for given valve ID, FALSE if not. + *************************************************************************/ +BOOL setValveStateDelayed( VALVES_T valveID, VALVE_STATE_NAMES_T valveStateName, U32 delayMs ) +{ + BOOL result = FALSE; // initialize result flag to FALSE + + if ( valveID < NUM_OF_VALVES ) + { + if ( checkValveStateName( valveID, valveStateName ) ) + { + // If a delayed state change is already pending for this valve, execute it now before setting a new delayed state change + if ( pendingValveStateChangeCountDowns[ valveID ] > 0 ) + { + valveStates[ valveID ].data = pendingValveStateChanges[ valveID ]; + } + // Set delayed valve state change + pendingValveStateChanges[ valveID ] = convertValveStateNameToValveState( valveStateName ); + pendingValveStateChangeCountDowns[ valveID ] = delayMs / TASK_PRIORITY_INTERVAL; + result = TRUE; + } + } + else + { + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_VALVES_INVALID_VALVE_ID, valveID ) + } + + return result; } /*********************************************************************//** Index: firmware/App/Controllers/Valves.h =================================================================== diff -u -r379f78f1fad668d741b3ccf1e78c69f3fccc45b5 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Controllers/Valves.h (.../Valves.h) (revision 379f78f1fad668d741b3ccf1e78c69f3fccc45b5) +++ firmware/App/Controllers/Valves.h (.../Valves.h) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -79,6 +79,7 @@ void execValves( void ); BOOL setValveState( VALVES_T valve, VALVE_STATE_NAMES_T valveState ); +BOOL setValveStateDelayed( VALVES_T valve, VALVE_STATE_NAMES_T valveState, U32 delayMs ); U32 getValveState( U32 valveID ); BOOL testSetValvesStatesPublishIntervalOverride( U32 value ); Index: firmware/App/DGCommon.h =================================================================== diff -u -r8a4182663ef6b12e3fd6414c0c14158943cd4ce1 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/DGCommon.h (.../DGCommon.h) (revision 8a4182663ef6b12e3fd6414c0c14158943cd4ce1) +++ firmware/App/DGCommon.h (.../DGCommon.h) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -37,8 +37,8 @@ // #define SIMULATE_UI 1 // #define TASK_TIMING_OUTPUT_ENABLED 1 // re-purposes drain pump enable pin for task timing // #define DISABLE_HEATERS_AND_TEMPS 1 - #define DISABLE_ACCELS 1 - #define SKIP_POST 1 +// #define DISABLE_ACCELS 1 +// #define SKIP_POST 1 #define DISABLE_CAL_CHECK 1 // #define ENABLE_DIP_SWITCHES 1 // #define EMC_TEST_BUILD 1 @@ -49,7 +49,8 @@ #define IGNORE_DRAIN_PUMP_MONITOR 1 #define IGNORE_HEATERS_MONITOR 1 #define IGNORE_RO_PUMP_MONITOR 1 - #define DISABLE_RO_RATIO_CHECK 1 + #define IGNORE_HEAT_DISINFECT_RSRVR_TIMEOUT 1 +// #define DISABLE_RO_RATIO_CHECK 1 #define DISABLE_COND_SENSOR_CHECK 1 #define DISABLE_MIXING 1 #define DISABLE_WATER_QUALITY_CHECK 1 Index: firmware/App/Modes/ModeDrain.c =================================================================== diff -u -r092b20aaea3defad5e1dbacf5a3f87e67256bd45 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 092b20aaea3defad5e1dbacf5a3f87e67256bd45) +++ firmware/App/Modes/ModeDrain.c (.../ModeDrain.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -33,7 +33,7 @@ // ********** private definitions ********** -#define TARGET_DRAIN_PUMP_RPM 1800 ///< Target drain pump speed (in RPM). +#define TARGET_DRAIN_PUMP_RPM 2100 ///< Target drain pump speed (in RPM). #define DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 2 * MS_PER_SECOND ) ///< Time period of unchanged weight during draining before timeout. /// Time period to wait after drain complete and before taring load cells. #define DRAIN_EMPTY_TARE_WAIT ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) @@ -49,6 +49,8 @@ static DG_DRAIN_STATE_T drainState; ///< Currently active drain state. static U32 drainEmptyTareTimerCtr; ///< Timer counter for delay between drain complete and load cell tare. +static U32 tempTrans = 0; + // ********** private function prototypes ********** static DG_DRAIN_STATE_T handleDrainState( void ); @@ -94,7 +96,12 @@ // set initial actuator states setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setDrainPumpTargetRPMDelayed( TARGET_DRAIN_PUMP_RPM, DELAY_DRAIN_PUMP_MS ); + + // 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 ); + startPrimaryHeater(); } /*********************************************************************//** @@ -150,10 +157,29 @@ static DG_DRAIN_STATE_T handleDrainState( void ) { DG_DRAIN_STATE_T result = DG_DRAIN_STATE_DRAIN; + + // TODO test code remove DG_RESERVOIR_ID_T inactiveReservoir = getInactiveReservoir(); + if ( ++tempTrans == 20 ) + { + if ( DG_RESERVOIR_2 == inactiveReservoir ) + { + setValveState( VRD2, VALVE_STATE_OPEN ); + } + else if ( DG_RESERVOIR_1 == inactiveReservoir ) + { + setValveState( VRD1, VALVE_STATE_OPEN ); + } + } + else if ( tempTrans == 40 ) + { + setDrainPumpTargetRPM( TARGET_DRAIN_PUMP_RPM ); + } + // TODO test code remove + // if we have reached our target drain to volume (by weight) or cannot drain anymore, we are done draining - go back to re-circ mode - if ( hasTargetDrainVolumeBeenReached( inactiveReservoir, DRAIN_WEIGHT_UNCHANGE_TIMEOUT ) ) + if ( TRUE == hasTargetDrainVolumeBeenReached( inactiveReservoir, DRAIN_WEIGHT_UNCHANGE_TIMEOUT ) ) { setDrainPumpTargetRPM( 0 ); @@ -199,6 +225,11 @@ drainEmptyTareTimerCtr = 0; tareLoadCellsAtEmpty( inactiveReservoir ); requestNewOperationMode( DG_MODE_CIRC ); + +#ifndef V_2_SYSTEM + setValveState( VRD1, VALVE_STATE_CLOSED ); + setValveState( VRD2, VALVE_STATE_CLOSED ); +#endif } return result; Index: firmware/App/Modes/ModeFault.c =================================================================== diff -u -r8a4182663ef6b12e3fd6414c0c14158943cd4ce1 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision 8a4182663ef6b12e3fd6414c0c14158943cd4ce1) +++ firmware/App/Modes/ModeFault.c (.../ModeFault.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -21,6 +21,7 @@ #include "ModeFault.h" #include "OperationModes.h" #include "ROPump.h" +#include "SystemCommMessages.h" #include "UVReactors.h" #include "Valves.h" @@ -58,6 +59,12 @@ *************************************************************************/ void transitionToFaultMode( void ) { + // Publish POST failure status to UI if fault triggered in Init/POST mode + if ( DG_MODE_INIT == getPreviousOperationMode() ) + { + // Broadcast final POST failed + sendPOSTFinalResult( FALSE ); + } } /*********************************************************************//** Index: firmware/App/Modes/ModeHeatDisinfect.c =================================================================== diff -u -r99b0c8f1ff9f9319f68e5043cd8c007e317a05c0 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 99b0c8f1ff9f9319f68e5043cd8c007e317a05c0) +++ firmware/App/Modes/ModeHeatDisinfect.c (.../ModeHeatDisinfect.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -41,19 +41,19 @@ // General defines #define MAX_ALLOWED_STATE_TRIALS 1 ///< Max allowed trials on a state. This is general among all the states. -#define HEAT_DISINFECT_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Mode Heat Disinfect data publish interval in counts. +#define HEAT_DISINFECT_DATA_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Mode heat disinfect data publish interval in counts. // Start state defines #define MIN_INLET_PRESSURE_PSI 30.0 ///< Minimum water inlet pressure in psi. -#define MAX_START_STATE_TEMP_SENSORS_DIFF_C 1.0 ///< Max start state TDi and TRo difference tolerance in C. +#define MAX_START_STATE_TEMP_SENSORS_DIFF_C 3.0 ///< Max start state TDi and TRo difference tolerance in C. // Drain R1 & R2 states defines -#define DRAIN_PUMP_TARGET_RPM 1800 ///< Drain pump target RPM during drain. +#define DRAIN_PUMP_TARGET_RPM 2200 ///< Drain pump target RPM during drain. #define RSRVRS_INITIAL_DRAIN_TIME_OUT_MS ( 2* SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 initial drain time out in milliseconds. #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 ( SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. TODo original time was 60 seconds +#define FLUSH_DRAIN_WAIT_TIME_MS ( SEC_PER_MIN * MS_PER_SECOND ) ///< Flush Drain path wait time in milliseconds. #define MIN_INLET_TEMPERATURE_C 15.0 ///< Minimum water inlet temperature in C. TODO original temperature was 25 C #define MAX_INLET_CONDUCTIVITY_US_PER_CM 2000.0 ///< Maximum water inlet conductivity in us/cm @@ -73,29 +73,33 @@ #define RSRVRS_DRAIN_TIMEOUT_MS ( 2 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 drain timeout in ms. // Fill and heat water -#define HEAT_DISINFECT_TARGET_TEMPERATURE_C 85.0 ///< Heat disinfect target water temperature in C. TODO original temperature was 85.0 -#define HEAT_DISINFECT_START_TEMPERATURE_C 81.0 ///< Heat disinfect minimum acceptable temperature in C. TODO original temperature was 81.0 +#define HEAT_DISINFECT_TARGET_TEMPERATURE_C 83.0 ///< Heat disinfect target water temperature in C. +#define HEAT_DISINFECT_START_TEMPERATURE_C 81.0 ///< Heat disinfect minimum acceptable temperature in C. // R1 to R2 & R2 to R1 heat disinfect circulation -#define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 0.9 ///< Heat disinfect target RO flow rate in L/min. TODO original value was 0.8 +#define HEAT_DISINFECT_TARGET_RO_FLOW_LPM 1.2 ///< Heat disinfect target RO flow rate in L/min. #define HEAT_DISINFECT_MAX_RO_PRESSURE_PSI 30 ///< Heat disinfect maximum RO pressure in psi. #define HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI 10.0 ///< Heat disinfect target drain outlet pressure in psi. -#define HEAT_DISINFECT_TIME_MS ( 5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time for each section in milliseconds. TODO original time was 10 minutes +#define HEAT_DISINFECT_TIME_MS ( 10 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect time for each section in milliseconds. #define HEAT_DISINFECT_START_TEMP_TIMOUT_MS ( 4 * MIN_PER_HOUR * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect reaching to minimum temperature timeout in milliseconds. TODO figure out this timeout #define RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ( 0.5 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 maximum volume out of range timeout during heat disinfect. TODO change this to 5 seconds #define RSRVRS_MAX_TARGET_VOL_CHANGE_ML 600.0 ///< Reservoirs 1 & 2 maximum allowed volume change when full during heat disinfect. TODO original value is 100 mL #define POST_HEAT_DISINFECT_WAIT_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< Heat disinfect final wait time before flushing the system in milliseconds. +// Cool down RO filter +#define MIN_NUM_OF_ROF_CIRCULATIONS_FOR_COOLING 2 ///< Number of circulations that are needed to make the RO filter is below 45 C. +#define ROF_COOL_DOWN_TARGET_FLOW_LPM 0.3 ///< RO filter cool down target flow in L/min. +#define ROF_COOL_DOWN_CIRCULATION_TIME_MS ( 3 * SEC_PER_MIN * MS_PER_SECOND ) ///< RO filter cool down circulation timer in milliseconds. + // Mix drain R1 and R2 #define RSRVRS_MIX_DRAIN_TIMEOUT_MS ( 20 * SEC_PER_MIN * MS_PER_SECOND ) ///< Reservoirs 1 & 2 mix drain timeout in ms. #define DRAIN_PUMP_START_TIME_IN_MIX_DRAIN_MS ( 5 * MS_PER_SECOND ) ///< Time to start the drain pump at mix drain after directing the flow to drain in ms. #define DRAIN_PUMP_RPM_IN_MIX_DRAIN 600 ///< The RPM that the drain pump should be run during mix drain. #define MIX_DRAIN_WEIGHT_UNCHANGE_TIMEOUT ( 15 * MS_PER_SECOND ) ///< Time period of unchanged weight during mix draining before timeout. // Rinse R1 to R2 -#define ROF_MIN_LOW_PRESSURE_TEMPERATURE_C 45.0 ///< RO filter minimum temperature that the pressure must be no more than 30psi in C. TODO the actual value is 45.0 +#define ROF_MIN_LOW_PRESSURE_TEMPERATURE_C 45.0 ///< RO filter minimum temperature that the pressure must be no more than 30psi in C. -// Cancellation paths #define MIX_DRAIN_TEMPERATURE_THRESHOLD_C 60.0 ///< Temperature threshold for performing mix drain or normal drain. /// Cancellation paths @@ -106,7 +110,7 @@ CANCELLATION_MODE_HOT, ///< Cancellation mode hot. CANCELLATION_MODE_COLD, ///< Cancellation mode cold. NUM_OF_CANCELLATION_MODES ///< Number of cancellation modes. -} CANCELLATION_MODES_T; +} CANCELLATION_MODE_T; /// Heat disinfect status typedef enum Heat_disinfect_status @@ -120,27 +124,31 @@ // ********** private data ********** -static DG_HEAT_DISINFECT_STATE_T heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Current active heat disinfect state. -static DG_HEAT_DISINFECT_STATE_T prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Previous active heat disinfect state before alarm. -static U32 overallHeatDisinfectTimer = 0; ///< Heat disinfect cycle total timer. -static U32 stateTimer = 0; ///< Heat disinfect state timer to be used in different states. -static U32 stateTrialCounter = 0; ///< Heat disinfect state trial counter to be used for retries in different states. -static BOOL areTempSensorsInRange = FALSE; ///< Heat disinfect temperature sensors in/out range flag. +static DG_HEAT_DISINFECT_STATE_T heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Current active heat disinfect state. +static DG_HEAT_DISINFECT_STATE_T prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; ///< Previous active heat disinfect state before alarm. +static DG_HEAT_DISINFECT_UI_STATE_T heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_NOT_RUNNING; ///< Current active heat disinfect UI state. +static U32 overallHeatDisinfectTimer = 0; ///< Heat disinfect cycle total timer. +static U32 stateTimer = 0; ///< Heat disinfect state timer to be used in different states. +static U32 stateTrialCounter = 0; ///< Heat disinfect state trial counter to be used for retries in different states. +static BOOL areTempSensorsInRange = FALSE; ///< Heat disinfect temperature sensors in/out range flag. /// Boolean flag to check whether draining R1 and R2 is at the end of the heat disinfect cycle or in the beginning. So the drain states can be reused. static BOOL isThisLastDrain = FALSE; -static DG_RESERVOIR_STATUS_T rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 1 status. -static DG_RESERVOIR_STATUS_T rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 2 status. -static F32 R1HeatDisinfectVol = 0.0; ///< Reservoir 1 full volume during heat disinfect. -static F32 R2HeatDisinfectVol = 0.0; ///< Reservoir 2 full volume during heat disinfect. -static U32 heatDisinfectTimer = 0; ///< Heat disinfect timer. -static BOOL isPartialDisinfectInProgress = FALSE; ///< Heat disinfect partial complete/in progess flag. -static U32 rsrvrsVolMonitorTimer = 0; ///< Reservoir 1 & 2 volume monitor timers during heat disinfect. -static BOOL areRsrvrsLeaking = FALSE; ///< Reservoir 1 & 2 leak check flag during heat disinfect. -static U32 dataPublishCounter = 0; ///< Heat Disinfect data publish counter. -static CANCELLATION_MODES_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. -static U32 rsrvrFillStableTimeCounter = 0; ///< Reservoirs fill stable time counter. -static ALARM_ID_T alarmDetectedPendingTrigger; ///< Heat disinfect alarm to raise. -static BOOL isDrainPumpInMixDrainOn = FALSE; ///< Flag to show the drain pump is on during mix drain. +static DG_RESERVOIR_STATUS_T rsrvr1Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 1 status. +static DG_RESERVOIR_STATUS_T rsrvr2Status = NUM_OF_DG_RESERVOIR_STATUS; ///< Reservoir 2 status. +static F32 R1HeatDisinfectVol = 0.0; ///< Reservoir 1 full volume during heat disinfect. +static F32 R2HeatDisinfectVol = 0.0; ///< Reservoir 2 full volume during heat disinfect. +static U32 heatDisinfectTimer = 0; ///< Heat disinfect timer. +static BOOL isPartialDisinfectInProgress = FALSE; ///< Heat disinfect partial complete/in progess flag. +static U32 rsrvrsVolMonitorTimer = 0; ///< Reservoir 1 & 2 volume monitor timers during heat disinfect. +static BOOL areRsrvrsLeaking = FALSE; ///< Reservoir 1 & 2 leak check flag during heat disinfect. +static U32 dataPublishCounter = 0; ///< Heat Disinfect data publish counter. +static CANCELLATION_MODE_T cancellationMode = CANCELLATION_MODE_NONE; ///< Cancellation mode. +static U32 rsrvrFillStableTimeCounter = 0; ///< Reservoirs fill stable time counter. +static ALARM_ID_T alarmDetectedPendingTrigger; ///< Heat disinfect alarm to raise. +static BOOL isDrainPumpInMixDrainOn = FALSE; ///< Flag to indicate the drain pump is on during mix drain. +static BOOL hasROFCirculationBeenStarted = FALSE; ///< Flag to indicate the water in RO filter has been recirculated. +static U32 ROFCirculationTimer = 0; ///< RO filter circulation timer. +static U32 ROFCirculationCoolingCounter = 0; ///< RO filter circulation cooling counter. // ********** private function prototypes ********** @@ -182,14 +190,17 @@ * @details Outputs: heatDisinfectState, stateTimer, isThisLastDrain, * stateTrialCounter, areTempSensorsInRange, rsrvr1Status, rsrvr2Status, * R1HeatDisinfectVol, R2HeatDisinfectVol, overallHeatDisinfectTimer, - * cancellationMode, rsrvrFillStableTimeCounter, isPartialDisinfectInProgress, - * isDrainPumpOnInMixDrain + * cancellationMode, rsrvrFillStableTimeCounter, prevHeatDisinfectState + * isPartialDisinfectInProgress, isDrainPumpOnInMixDrain, + * hasROFCirculationBeenStarted, ROFCirculationTimer, + * ROFCirculationCoolingCounter * @return none *************************************************************************/ void initHeatDisinfectMode( void ) { heatDisinfectState = DG_HEAT_DISINFECT_STATE_START; prevHeatDisinfectState = DG_HEAT_DISINFECT_STATE_START; + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_NOT_RUNNING; stateTimer = 0; isThisLastDrain = FALSE; stateTrialCounter = 0; @@ -203,6 +214,9 @@ rsrvrFillStableTimeCounter = 0; isPartialDisinfectInProgress = FALSE; isDrainPumpInMixDrainOn = FALSE; + hasROFCirculationBeenStarted = FALSE; + ROFCirculationTimer = 0; + ROFCirculationCoolingCounter = 0; } /*********************************************************************//** @@ -406,7 +420,7 @@ F32 TDiTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODo change to TDi F32 TRoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); - // If the inlet pressure is less than the threshold and TDi and TRo difference is greater than 1 C, the cycle + // If the inlet pressure is less than the threshold and TDi and TRo difference is greater than 3 C, the cycle // should be canceled if ( ( ppiPressure < MIN_INLET_PRESSURE_PSI ) && ( fabs( TDiTemp - TRoTemp ) > MAX_START_STATE_TEMP_SENSORS_DIFF_C ) ) { @@ -416,6 +430,9 @@ } else { + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_FLUSH_BEFORE_DISINFECT; + // Close VPi to prevent wasting water setValveState( VPI, VALVE_STATE_CLOSED ); // Request a tare for reservoir 1 @@ -490,6 +507,7 @@ rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; // Request a tare for reservoir 2 tareReservoir(); + #ifndef V_2_SYSTEM // Done with draining R1, close it setValveState( VRD1, VALVE_STATE_CLOSED ); @@ -551,6 +569,7 @@ else { signalDrainPumpHardStop(); + #ifndef V_2_SYSTEM // Done with draining R2, close it setValveState( VRD2, VALVE_STATE_CLOSED ); @@ -574,7 +593,7 @@ * @brief * The handleHeatDisinfectFlushDrainState function handles the heat disinfect * flush drain state. The state flushes the drain line for a period of time - * and then measure the temperature and conductivity of water. If they are + * and then measures the temperature and conductivity of water. If they are * not within the range, it transitions to basic cancellation path, otherwise * it transitions to the next state. * @details Inputs: stateTimer, stateTrialCounter, alarm, @@ -640,7 +659,7 @@ DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FLUSH_CIRCULATION; // Check if the flush circulation time has elapsed and the temperature sensors are not in range yet - if ( TRUE == didTimeout( stateTimer, FLUSH_CICRCULATION_WAIT_TIME_MS ) && ( FALSE == areTempSensorsInRange ) ) + if ( ( TRUE == didTimeout( stateTimer, FLUSH_CICRCULATION_WAIT_TIME_MS ) ) && ( FALSE == areTempSensorsInRange ) ) { F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); // TODO add THd later. This is the new temp sensor of the coldest spot. F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); @@ -721,7 +740,7 @@ { rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); - // Keep monitoring the status of reservoir 2 as the same time + // Keep monitoring the status of reservoir 2 at the same time rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); // Reservoir 2 cannot be filled before reservoir 1 is filled and is overflowing to reservoir 2. If reservoir 2 has already // reached to target volume, it means reservoir 1's load cell might be reading incorrect values. This situation might continue @@ -964,7 +983,7 @@ // Turn on the RO pump setROPumpTargetFlowRate( RO_PUMP_TARGET_FLUSH_FILL_FLOW_RATE_LPM, MAX_RO_PUMP_FLUSH_FILL_PRESSURE_PSI ); - // Start heating the water while we are filling up the rsrvrs + // Start heating the water while we are filling up the reservoirs setPrimaryHeaterTargetTemperature( HEAT_DISINFECT_TARGET_TEMPERATURE_C ); startPrimaryHeater(); @@ -1002,6 +1021,9 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_WITH_WATER; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_HEAT_UP_WATER; + // First reservoir 1 must be full if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { @@ -1029,17 +1051,17 @@ // Set the drain pump to control mode setDrainPumpTargetOutletPressure( HEAT_DISINFECT_TARGET_DRAIN_PRES_PSI ); - // Set the RO flow to maximum pressure of 25psi since it is the maximum pressure on the RO filter + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter // at inlet temperature > 45 C setROPumpTargetFlowRate( HEAT_DISINFECT_TARGET_RO_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); - // Start the trimmer heater since we are recirculating water - //setTrimmerHeaterTargetTemperature( HEAT_DISINFECT_TARGET_TEMPERATURE_C ); - //startTrimmerHeater(); TODO turn the trimmer heater on when THD is implemented + // Start the trimmer heater since we are recirculating water and there is flow in the shunt line + setTrimmerHeaterTargetTemperature( HEAT_DISINFECT_TARGET_TEMPERATURE_C ); + startTrimmerHeater(); // Get the current volumes of R1 & R2. These values will be used to make sure the reservoirs' // volume does not change more than a certain amount during the actual heat disinfect cycle - R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ); //TODO change this back to primary + R1HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); R2HeatDisinfectVol = getLoadCellLargeFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ); stateTimer = getMSTimerCount(); @@ -1103,9 +1125,11 @@ rsrvr2Status = DG_RESERVOIR_BELOW_TARGET; rsrvr1Status = DG_RESERVOIR_BELOW_TARGET; stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; break; + case HEAT_DISINFECT_IN_PROGRESS: default: // Do nothing, heat disinfect is in progress break; @@ -1131,6 +1155,9 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_FILL_R2_WITH_HOT_WATER; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_TRANSITION_HOT_WATER; + // First reservoir 1 must be partially full if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { @@ -1150,21 +1177,17 @@ state = DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1; } -#ifdef IGNORE_HEAT_DISINFECT_RSRVR_TIMEOUT else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr2Status ) { prevHeatDisinfectState = state; state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } -#endif } -#ifdef IGNORE_HEAT_DISINFECT_RSRVR_TIMEOUT else if ( DG_RESERVOIR_NOT_REACHED_TARGET == rsrvr1Status ) { prevHeatDisinfectState = state; state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; } -#endif return state; } @@ -1176,8 +1199,8 @@ * temperature within a certain period of time, it transitions to water * cancellation state. If heat disinfect reservoir 1 to reservoir 2 is * completed, it transitions to the next state. - * @details Inputs: hasPostHeatDisinfectWaitStarted, stateTimer, rsrvr1Status - * @details Outputs: hasPostHeatDisinfectWaitStarted, stateTimer, rsrvr1Status + * @details Inputs: stateTimer, rsrvr1Status + * @details Outputs: stateTimer, rsrvr1Status * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectDisinfectR2ToR1State( void ) @@ -1193,13 +1216,18 @@ break; case HEAT_DISINFECT_COMPLETE: - // Turn off the pumps and heaters + // Turn off the heaters // TODO turn off CP1 and CP2 stopPrimaryHeater(); stopTrimmerHeater(); stateTimer = getMSTimerCount(); state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; break; + + case HEAT_DISINFECT_IN_PROGRESS: + default: + // Do nothing heat disinfect is in progress. + break; } return state; @@ -1218,6 +1246,9 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_HEATERS; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COOL_DOWN_DEVICE; + if ( TRUE == didTimeout( stateTimer, POST_HEAT_DISINFECT_WAIT_TIME_MS ) ) { // Stop the drain pump and the RO pump to exit the closed loop @@ -1226,8 +1257,8 @@ // De-energize all the valves that are not in the path anymore // and wait for the RO membrane to be cooled down. - // In this state, VPi and VPd must still be kept energized to make sure fresh - // water does not enter the circulation path the membrane is cooling down + setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPI, VALVE_STATE_CLOSED ); setValveState( VBF, VALVE_STATE_CLOSED ); #ifndef V_2_SYSTEM @@ -1250,32 +1281,68 @@ * The handleHeatDisinfectCoolDownROFilterState function handles the heat * disinfect cool down RO filter state. The state monitors the temperature * at THd and if it is less than 45 C, it transitions to the next state. - * @details Inputs: stateTimer, rsrvr1Status - * @details Outputs: stateTimer, rsrvr1Status + * @details Inputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, + * ROFCirculationCoolingCounter + * @details Outputs: stateTimer, rsrvr1Status, hasROFCirculationBeenStarted, + * ROFCirculationCoolingCounter * @return next state of the heat disinfect state machine *************************************************************************/ static DG_HEAT_DISINFECT_STATE_T handleHeatDisinfectCoolDownROFilterState( void ) { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COOL_DOWN_RO_FILTER; - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODO change this to actual THd sensor later + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COOL_DOWN_DEVICE; - // Check if the coldest spot temperature is less than 45 C so the RO filter - // can safely run fluid through - if ( ThdTemp < ROF_MIN_LOW_PRESSURE_TEMPERATURE_C ) + // TPo which is the temperature sensor after the heater is hottest spot + // and this temperature is monitored until it is dropped below 45 C to be able + // to run fluid through the RO filter + F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); + + // Check if the coldest spot temperature is less than 45 C so the RO filter can safely run fluid through + if ( ( FALSE == isROPumpRunning() ) && ( TPoTemp < ROF_MIN_LOW_PRESSURE_TEMPERATURE_C ) ) { - setValveState( VPI, VALVE_STATE_OPEN ); - setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); - setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); - setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); + // If the minimum number of circulations are done, transition to the next state + if ( ROFCirculationCoolingCounter > MIN_NUM_OF_ROF_CIRCULATIONS_FOR_COOLING ) + { + setValveState( VPI, VALVE_STATE_OPEN ); + // To make sure there is no leak from the reservoirs or drain to RO path during mix draining + setValveState( VBF, VALVE_STATE_CLOSED ); + setValveState( VPO, VALVE_STATE_FILL_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VRO, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRI, VALVE_STATE_R1_C_TO_NO ); + setValveState( VRF, VALVE_STATE_R2_C_TO_NO ); - rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; - stateTimer = getMSTimerCount(); - state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; + rsrvr1Status = DG_RESERVOIR_ABOVE_TARGET; + stateTimer = getMSTimerCount(); + state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; + } + else + { + // Set the valves to circulation. VBf is opened because the fluid in the RO filter might still be hot + setValveState( VBF, VALVE_STATE_OPEN ); + setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VRC, VALVE_STATE_RECIRC_C_TO_NC ); + setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); + + // Set the RO flow to maximum pressure of 30psi since it is the maximum pressure on the RO filter + // at inlet temperature > 45 C + setROPumpTargetFlowRate( ROF_COOL_DOWN_TARGET_FLOW_LPM, HEAT_DISINFECT_MAX_RO_PRESSURE_PSI ); + + // Increment the RO filter cooling counter + ROFCirculationCoolingCounter++; + hasROFCirculationBeenStarted = TRUE; + ROFCirculationTimer = getMSTimerCount(); + } } + // If the RO filter water circulation is in progress and the time for it has elapsed, stop the pump + else if ( ( TRUE == hasROFCirculationBeenStarted ) && ( TRUE == didTimeout( ROFCirculationTimer, ROF_COOL_DOWN_CIRCULATION_TIME_MS ) ) ) + { + signalROPumpHardStop(); + // Done with running the RO pump + hasROFCirculationBeenStarted = FALSE; + } return state; } @@ -1296,13 +1363,18 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_MIX_DRAIN_R1; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_FLUSH_AFTER_DISINFECT; + if ( ( TRUE == didTimeout( stateTimer, DRAIN_PUMP_START_TIME_IN_MIX_DRAIN_MS ) ) && ( isDrainPumpInMixDrainOn == FALSE ) ) { isDrainPumpInMixDrainOn = TRUE; #ifndef V_2_SYSTEM setValveState( VRD1, VALVE_STATE_OPEN ); #endif + setValveState( VRD1, VALVE_STATE_OPEN ); + // Turn on the drain pump to drain the reservoirs in open loop mode setDrainPumpTargetRPM( DRAIN_PUMP_RPM_IN_MIX_DRAIN ); } @@ -1410,6 +1482,18 @@ if ( DG_RESERVOIR_BELOW_TARGET == rsrvr1Status ) { rsrvr1Status = getRsrvrFillStatus( DG_RESERVOIR_1, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); + + // Keep monitoring the status of reservoir 2 at the same time + rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_PARTIAL_FILL_VOL_ML, RSRVRS_500ML_FILL_UP_TIMEOUT_MS ); + // Reservoir 2 cannot be filled before reservoir 1 is filled and is overflowing to reservoir 2. If reservoir 2 has already + // reached to target volume, it means reservoir 1's load cell might be reading incorrect values. This situation might continue + // until reservoir 2 is filled up and the tubing might expand or leak. + if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) + { + prevHeatDisinfectState = state; + alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + } } else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr1Status ) { @@ -1487,6 +1571,21 @@ if ( DG_RESERVOIR_BELOW_TARGET == rsrvr2Status ) { rsrvr2Status = getRsrvrFillStatus( DG_RESERVOIR_2, RSRVRS_FULL_VOL_ML, RSRVRS_FILL_UP_TIMEOUT_MS ); + + U32 drainPumpRPM = getTargetDrainPumpRPM(); + // Keep monitoring the status of reservoir 1 as the same time + F32 volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); + // Reservoir 1 cannot be filled before reservoir 2 is filled and is overflowing to reservoir 1. If reservoir 1 has already + // reached to target volume, it means reservoir 2's load cell might be reading incorrect values. This situation might continue + // until reservoir 1 is filled up and the tubing might expand or leak. + // Before checking whether reservoir 1 is filled pre-maturely, we have to make sure reservoir 1 is drained completely to make + // sure the extra volume that is read is not because of previous water that is being drained currently and it is above 500 mL + if ( ( volume > RSRVRS_PARTIAL_FILL_VOL_ML ) && ( 0 == drainPumpRPM ) ) + { + prevHeatDisinfectState = state; + alarmDetectedPendingTrigger = ALARM_ID_DG_INVALID_LOAD_CELL_VALUE; + state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + } } // Once reservoir 2 is completely full, monitor reservoir 1 else if ( DG_RESERVOIR_REACHED_TARGET == rsrvr2Status ) @@ -1576,6 +1675,9 @@ // Go to state complete, we are done DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_CANCEL_BASIC_PATH; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_CANCEL_DISINFECT; + // Set the cancellation mode cancellationMode = CANCELLATION_MODE_BASIC; @@ -1601,6 +1703,9 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_CANCEL_WATER_PATH; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_CANCEL_DISINFECT; + if ( CANCELLATION_MODE_NONE == cancellationMode ) { U32 targetRPM = 0; @@ -1636,6 +1741,8 @@ rsrvr2Status = DG_RESERVOIR_ABOVE_TARGET; // The drain is set to start from reservoir 2 since all the actuators have been de-energized + // Set the drain valve to reservoir 2 + setValveState( VRD2, VALVE_STATE_OPEN ); // Start the drain pump setDrainPumpTargetRPM( targetRPM ); @@ -1699,6 +1806,9 @@ { DG_HEAT_DISINFECT_STATE_T state = DG_HEAT_DISINFECT_STATE_COMPLETE; + // Set the heat disinfect UI state + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_COMPLETE; + stopDGHeatDisinfect(); return state; @@ -1747,7 +1857,7 @@ * @brief * The failHeatDisinfect function sets the alarm that failed the heat * disinfect mode. - * @details Inputs: alarm, prevHeatDisinfectState + * @details Inputs: alarmDetectedPendingTrigger, prevHeatDisinfectState * @details Outputs: none * @return none *************************************************************************/ @@ -1775,7 +1885,7 @@ if ( r == DG_RESERVOIR_1 ) { - volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ); //TODO change back to primary + volume = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ); } else if ( r == DG_RESERVOIR_2 ) { @@ -1814,8 +1924,7 @@ * reservoir. * @details Inputs: stateTimer, prevHeatDisinfectState, heatDisinfectState, * alarm - * @details Outputs: stateTimer, heatDisinfectState heatDisinfectState, - * alarm + * @details Outputs: stateTimer, heatDisinfectState, alarm * @param r is DG_RESERVOIR_1 or DG_RESERVOIR_2 * @param drainSteadyStateTimeout which is the time the reservoir's level * does not change and is steady state @@ -1856,21 +1965,21 @@ * If the heat disinfect has started or has elapsed, it set the status of * heat disinfect accordingly. * @details Inputs: areRsrvrsLeaking, areRsrvrsLeaking - * @details Outputs: areRsrvrsLeaking, areRsrvrsLeaking + * @details Outputs: areRsrvrsLeaking, areRsrvrsLeaking, heatDisinfectState * @return status of the heat disinfect (i.e in progress, complete) *************************************************************************/ static HEAT_DISINFECT_STATUS_T getHeatDisinfectStatus( void ) { HEAT_DISINFECT_STATUS_T status = HEAT_DISINFECT_IN_PROGRESS; F32 TPoTemp = getTemperatureValue( TEMPSENSORS_OUTLET_PRIMARY_HEATER ); - F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODO change this to actual TPm sensor later + F32 ThdTemp = getTemperatureValue( TEMPSENSORS_OUTLET_REDUNDANT ); //TODO change this to actual THd sensor later - BOOL isR1OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ) - R1HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; //TODo change this to primary when the stupid load cell was fixed + BOOL isR1OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_PRIMARY ) - R1HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; BOOL isR2OutOfRange = fabs( getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_2_PRIMARY ) - R2HeatDisinfectVol ) > RSRVRS_MAX_TARGET_VOL_CHANGE_ML; // Check if either reservoir 1 or reservoir 2 are losing volume more than allowed volume - if ( isR1OutOfRange || isR2OutOfRange ) + if ( ( TRUE == isR1OutOfRange ) || ( TRUE == isR2OutOfRange ) ) { // If the leak is the first time after a while, set the flag and start the timer if ( FALSE == areRsrvrsLeaking ) @@ -1882,7 +1991,7 @@ else if ( TRUE == didTimeout( rsrvrsVolMonitorTimer, RSRVRS_TARGET_VOL_OUT_TIMEOUT_MS ) ) { areRsrvrsLeaking = FALSE; - alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; + alarmDetectedPendingTrigger = ALARM_ID_DG_RESERVOIR_LEAK_TIMEOUT; status = HEAT_DISINFECT_RSRVRS_LEAK_TIMEOUT; } } @@ -1892,18 +2001,19 @@ areRsrvrsLeaking = FALSE; } - // If the coldest spot which is TPm is less than minimum heat disinfect temperature, + // If the coldest spot which is THd is less than minimum heat disinfect temperature, // reset the heat disinfect timers and check whether heating up has timed out if ( ThdTemp < HEAT_DISINFECT_START_TEMPERATURE_C ) { // 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; if ( TRUE == didTimeout( stateTimer, HEAT_DISINFECT_START_TEMP_TIMOUT_MS ) ) { // Heating up to minimum temperature for heat disinfect failed - alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; + alarmDetectedPendingTrigger = ALARM_ID_DG_HEAT_DISINFECT_TARGET_TEMP_TIMEOUT; status = HEAT_DISINFECT_HEAT_UP_TIMEOUT; } } @@ -1912,6 +2022,16 @@ // The temperature of the coldest spot is in range to start the disinfect timer heatDisinfectTimer = getMSTimerCount(); isPartialDisinfectInProgress = TRUE; + + // Set the heat disinfect UI state + if ( DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 == heatDisinfectState ) + { + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_1; + } + else + { + heatDisinfectUIState = HEAT_DISINFECT_UI_STATE_DISINFECT_RESERVOIR_2; + } } // If heat disinfect temperature has been reached, check if this stage of heat disinfect is done @@ -1938,26 +2058,36 @@ if ( ++dataPublishCounter > HEAT_DISINFECT_DATA_PUB_INTERVAL ) { MODE_HEAT_DISINFECT_DATA_T data; + MODE_HEAT_DISINFECT_UI_DATA_T uiData; - data.heatDisinfectState = (U32)heatDisinfectState; - data.overallElapsedTime = calcTimeSince( overallHeatDisinfectTimer ); - data.stateElapsedTime = calcTimeSince( stateTimer ); - data.cancellationMode = (U32)cancellationMode; - data.R1FillLevel = R1HeatDisinfectVol; - data.R2FillLevel = R2HeatDisinfectVol; + data.heatDisinfectState = (U32)heatDisinfectState; + data.overallElapsedTime = calcTimeSince( overallHeatDisinfectTimer ); + data.stateElapsedTime = calcTimeSince( stateTimer ); + data.cancellationMode = (U32)cancellationMode; + data.heatDisinfectUIState = (U32)heatDisinfectUIState; // If the mode is in the actual heat disinfect states, publish the elapsed time, otherwise publish 0 to avoid confusion - if ( DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 == heatDisinfectState || DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1 == heatDisinfectState ) + if ( ( DG_HEAT_DISINFECT_STATE_DISINFECT_R1_TO_R2 == heatDisinfectState ) || + ( DG_HEAT_DISINFECT_STATE_DISINFECT_R2_TO_R1 == heatDisinfectState ) ) { - data.heatDisinfectElapsedTime = calcTimeSince( heatDisinfectTimer ); + uiData.heatDisinfectTargetTime = HEAT_DISINFECT_TIME_MS; + uiData.heatDisinfectCountdownTime = HEAT_DISINFECT_TIME_MS - calcTimeSince( heatDisinfectTimer ); + data.R1FillLevel = R1HeatDisinfectVol; + data.R2FillLevel = R2HeatDisinfectVol; } else { - data.heatDisinfectElapsedTime = 0; + uiData.heatDisinfectTargetTime = 0; + uiData.heatDisinfectCountdownTime = 0; + data.R1FillLevel = 0.0; + data.R2FillLevel = 0.0; } broadcastHeatDisinfectData( &data ); + // Publish data to UI + broadcastHeatDisinfectData2UI( &uiData ); + dataPublishCounter = 0; } } Index: firmware/App/Modes/ModeHeatDisinfect.h =================================================================== diff -u -rfba89d67dd2bef913e85a13563e2aa49f0e2e2f5 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision fba89d67dd2bef913e85a13563e2aa49f0e2e2f5) +++ firmware/App/Modes/ModeHeatDisinfect.h (.../ModeHeatDisinfect.h) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -31,18 +31,25 @@ // ********** public definitions ********** -/// Heat Disinfect data publish struct +/// Heat disinfect data publish struct typedef struct { U32 heatDisinfectState; ///< Heat disinfect state. U32 overallElapsedTime; ///< Overall elapsed time in heat disinfect mode. U32 stateElapsedTime; ///< Current heat disinfect elapsed time. - U32 heatDisinfectElapsedTime; ///< Elapsed time in just heat disinfecting. U32 cancellationMode; ///< Heat disinfect cancellation mode. F32 R1FillLevel; ///< Reservoir 1 level upon starting the heat disinfect. F32 R2FillLevel; ///< Reservoir 2 level upon starting the heat disinfect. + U32 heatDisinfectUIState; ///< Heat disinfect UI state. } MODE_HEAT_DISINFECT_DATA_T; +/// Heat disinfect UI data publish struct +typedef struct +{ + U32 heatDisinfectTargetTime; ///< Target time to heat disinfect. + U32 heatDisinfectCountdownTime; ///< Heat disinfect count down time. +} MODE_HEAT_DISINFECT_UI_DATA_T; + // ********** public function prototypes ********** void initHeatDisinfectMode( void ); // Initialize this module Index: firmware/App/Modes/ModeInitPOST.c =================================================================== diff -u -r5156a859330f51537606ffdab32ea63d8fac9cac -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 5156a859330f51537606ffdab32ea63d8fac9cac) +++ firmware/App/Modes/ModeInitPOST.c (.../ModeInitPOST.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -20,7 +20,6 @@ #include "DrainPump.h" #include "Fans.h" #include "FPGA.h" -#include "Heaters.h" #include "LoadCell.h" #include "ModeInitPOST.h" #include "NVDataMgmt.h" @@ -134,11 +133,6 @@ #endif break; - case DG_POST_STATE_HEATERS: - testStatus = execHeatersSelfTest(); - postState = handlePOSTStatus( testStatus ); - break; - case DG_POST_STATE_ACCELEROMETER: #ifndef DISABLE_ACCELS testStatus = execAccelTest(); Index: firmware/App/Modes/ModeRecirculate.c =================================================================== diff -u -r847478dd75aac2edfe27df454ac5a644b6f30040 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeRecirculate.c (.../ModeRecirculate.c) (revision 847478dd75aac2edfe27df454ac5a644b6f30040) +++ firmware/App/Modes/ModeRecirculate.c (.../ModeRecirculate.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -44,7 +44,7 @@ #define TARGET_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. #define TARGET_FLUSH_LINES_RO_FLOW_RATE_L 0.6 ///< Target flow rate for RO pump. -#define FLUSH_LINES_VOLUME_L 0.1 ///< Water volume (in Liters) to flush when starting re-circulate mode. +#define FLUSH_LINES_VOLUME_L 0.01 ///< Water volume (in Liters) to flush when starting re-circulate mode. // ********** private data ********** @@ -82,6 +82,10 @@ // re-initialize each time we transition to re-circulate mode initRecirculateMode(); + // TODO uncomment + //stopPrimaryHeater(); + // TODO uncomment (SEAN) + // set initial actuator states setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); @@ -91,16 +95,25 @@ setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); - setROPumpTargetFlowRate( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); signalDrainPumpHardStop(); requestConcentratePumpsOff( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpsOff( CONCENTRATEPUMPS_CP2_BICARB ); - // UV on + // UV reactors on turnOnUVReactor( INLET_UV_REACTOR ); turnOnUVReactor( OUTLET_UV_REACTOR ); + // TODO remove + setPrimaryHeaterTargetTemperature( 39.0 ); + // TODO remove + + // 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 ); + startPrimaryHeater(); + #ifndef _VECTORCAST_ { // TODO - test code to start the fan since we're turning the heater on F32 fanPWM = 0.25; @@ -173,7 +186,9 @@ // when enough water volume has flowed to flush the lines, transition to re-circ state if ( flushLinesVolumeL >= FLUSH_LINES_VOLUME_L ) { +#ifndef SKIP_RECIRC setValveState( VDR, VALVE_STATE_RECIRC_C_TO_NC ); +#endif setROPumpTargetFlowRate( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); result = DG_RECIRCULATE_MODE_STATE_RECIRC_WATER; } Index: firmware/App/Modes/ModeStandby.c =================================================================== diff -u -rcec14e1b1b636760fcd44ab35f3f45a71a79b776 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision cec14e1b1b636760fcd44ab35f3f45a71a79b776) +++ firmware/App/Modes/ModeStandby.c (.../ModeStandby.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -190,7 +190,7 @@ filterFlushStartTime = getMSTimerCount(); setValveState( VPI, VALVE_STATE_OPEN ); #ifndef V_2_SYSTEM - setValveState( VPD, VALVE_STATE_DRAIN_C_TO_NO ); + setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); #else setValveState( VPD, VALVE_STATE_OPEN ); // TODO: VPD drain state is closed for V3 #endif Index: firmware/App/Modes/OperationModes.c =================================================================== diff -u -r0c3e4f0618d7e42f35386fe5acf450fbb61481b6 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 0c3e4f0618d7e42f35386fe5acf450fbb61481b6) +++ firmware/App/Modes/OperationModes.c (.../OperationModes.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -57,7 +57,7 @@ /* SERV */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* INIT */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_INIT, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* STAN */{ DG_MODE_FAUL, DG_MODE_SERV, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_CIRC, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_CHEM }, - /* SOLO */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_NLEG }, + /* SOLO */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_SOLO, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_FLUS, DG_MODE_HEAT, DG_MODE_CHEM /*DG_MODE_NLEG*/ }, // TODO for testing only /* CIRC */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_CIRC, DG_MODE_FILL, DG_MODE_DRAI, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* FILL */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_CIRC, DG_MODE_FILL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, /* DRAI */{ DG_MODE_FAUL, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_STAN, DG_MODE_NLEG, DG_MODE_CIRC, DG_MODE_NLEG, DG_MODE_DRAI, DG_MODE_NLEG, DG_MODE_NLEG, DG_MODE_NLEG }, Index: firmware/App/Services/AlarmMgmt.h =================================================================== diff -u -rc0700a4503f28288f16070634bb87f4eccb2568c -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision c0700a4503f28288f16070634bb87f4eccb2568c) +++ firmware/App/Services/AlarmMgmt.h (.../AlarmMgmt.h) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -158,8 +158,8 @@ SW_FAULT_ID_INVALID_DG_RESERVOIR_SELECTED, SW_FAULT_ID_STANDBY_MODE_INVALID_EXEC_STATE, SW_FAULT_ID_RECIRC_MODE_INVALID_EXEC_STATE, - SW_FAULT_ID_DRAIN_MODE_INVALID_EXEC_STATE, // 80 - SW_FAULT_ID_FILL_MODE_INVALID_EXEC_STATE, + SW_FAULT_ID_DRAIN_MODE_INVALID_EXEC_STATE, + SW_FAULT_ID_FILL_MODE_INVALID_EXEC_STATE, // 80 SW_FAULT_ID_PRESSURE_INVALID_EXEC_STATE, SW_FAULT_ID_INVALID_NVDATAMGMT_EXEC_CAL_STATE, SW_FAULT_ID_INVALID_VOLTAGE_MONITOR_STATE, Index: firmware/App/Services/Reservoirs.c =================================================================== diff -u -r99b0c8f1ff9f9319f68e5043cd8c007e317a05c0 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 99b0c8f1ff9f9319f68e5043cd8c007e317a05c0) +++ firmware/App/Services/Reservoirs.c (.../Reservoirs.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -446,20 +446,7 @@ { BOOL result = FALSE; - F32 loadcellWeight = 0.0; - - // TODO remove this code once the load cell is repaired - if ( DG_RESERVOIR_1 == reservoirId ) - { - loadcellWeight = getLoadCellSmallFilteredWeight( LOAD_CELL_RESERVOIR_1_BACKUP ); - } - else - { - loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); - } - // TODO remove the above code the load cell is repaired - - //F32 const loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); + F32 const loadcellWeight = getLoadCellSmallFilteredWeight( associatedLoadCell[ reservoirId ] ); U32 const targetDrainVolume = getReservoirDrainVolumeTargetMl(); if ( loadcellWeight < reservoirLowestWeight[ reservoirId ] ) @@ -471,11 +458,18 @@ BOOL const hasTimeOut = didTimeout( reservoirWeightUnchangeStartTime[ reservoirId ], timeout ); BOOL const hasTargetReached = ( targetDrainVolume >= loadcellWeight ); - if ( hasTimeOut || hasTargetReached ) + if ( ( TRUE == hasTimeOut ) || ( ( TRUE == hasTargetReached ) && ( FALSE == tareLoadCellRequest ) ) ) { result = TRUE; // Reset for next drain reservoirLowestWeight[ reservoirId ] = MAX_RESERVOIR_WEIGHT; + + if ( TRUE == tareLoadCellRequest ) + { + tareLoadCellRequest = FALSE; + tareLoadCell( associatedLoadCell[ reservoirId ] ); + tareLoadCell( redundantLoadCell[ reservoirId ] ); + } } return result; Index: firmware/App/Services/SystemComm.c =================================================================== diff -u -rcec14e1b1b636760fcd44ab35f3f45a71a79b776 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision cec14e1b1b636760fcd44ab35f3f45a71a79b776) +++ firmware/App/Services/SystemComm.c (.../SystemComm.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -1040,10 +1040,6 @@ handleStartStopTrimmerHeaterCmd( message ); break; - case MSG_ID_DG_TESTER_LOGIN_REQUEST: - handleTesterLogInRequest( message ); - break; - case MSG_ID_DG_START_STOP_FLUSH: handleStartStopDGFlush( message ); break; @@ -1056,6 +1052,14 @@ handleStartStopDGChemicalDisinfect( message ); break; + case MSG_ID_UI_DG_SET_RTC_REQUEST: + handleUIClockSyncRequest( message ); + break; + + case MSG_ID_DG_TESTER_LOGIN_REQUEST: + handleTesterLogInRequest( message ); + break; + default: // unrecognized message ID received - ok, ignore - may be a test message handled below break; @@ -1158,6 +1162,14 @@ handleTestDGAccelBroadcastIntervalOverrideRequest( message ); break; + case MSG_ID_DG_MONITORED_VOLTAGES_SEND_INTERVAL_OVERRIDE: + handleTestMonitoredVoltagesSendIntervalOverrideRequest( message ); + break; + + case MSG_ID_DG_MONITORED_VOLTAGES_OVERRIDE: + handleTestMonitoredVoltageOverrideRequest( message ); + break; + case MSG_ID_DRAIN_PUMP_SET_DELTA_PRESSURE_OVERRIDE: handleSetDrainPumpDeltaPressureOverrideRequest( message ); break; Index: firmware/App/Services/SystemCommMessages.c =================================================================== diff -u -r3f7d30b23906496854054949d4491f3bae6ef3c4 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 3f7d30b23906496854054949d4491f3bae6ef3c4) +++ firmware/App/Services/SystemCommMessages.c (.../SystemCommMessages.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -1022,6 +1022,34 @@ /*********************************************************************//** * @brief + * The broadcastVoltagesData function constructs a monitored voltages data msg to + * be broadcast and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: monitored voltages data msg constructed and queued. + * @param data Latest monitored voltage values. + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL broadcastVoltagesData( VOLTAGES_DATA_PAYLOAD_T data ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_VOLTAGES_DATA; + msg.hdr.payloadLen = sizeof( VOLTAGES_DATA_PAYLOAD_T ); + + memcpy( payloadPtr, &data, sizeof( VOLTAGES_DATA_PAYLOAD_T ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + + /*********************************************************************//** + * @brief * The broadcastFlushData function sends out the flush mode data. * @details Inputs: none * @details Outputs: flush data msg constructed and queued @@ -1250,6 +1278,67 @@ /*********************************************************************//** * @brief + * The sendPOSTTestResult function constructs an DG POST test result message + * and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG POST test result msg constructed and queued. + * @param test ID of DG POST test + * @param passed TRUE if POST test passed, FALSE if not + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPOSTTestResult( DG_POST_STATE_T test, BOOL passed ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + U32 testID = (U32)test; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_POST_SINGLE_TEST_RESULT; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + + memcpy( payloadPtr, &passed, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &testID, sizeof( U32) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; + +} + +/*********************************************************************//** + * @brief + * The sendPOSTFinalResult function constructs an DG POST final result message + * and queues the msg for transmit on the appropriate CAN channel. + * @details Inputs: none + * @details Outputs: DG POST final result msg constructed and queued. + * @param passed TRUE if DG POST passed, FALSE if not + * @return TRUE if msg successfully queued for transmit, FALSE if not + *************************************************************************/ +BOOL sendPOSTFinalResult( BOOL passed ) +{ + BOOL result; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + // Create a message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_POST_FINAL_TEST_RESULT; + msg.hdr.payloadLen = sizeof( BOOL ); + + memcpy( payloadPtr, &passed, sizeof( BOOL ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_BROADCAST, ACK_NOT_REQUIRED ); + + return result; +} + +/*********************************************************************//** + * @brief * The sendCommandResponseMsg function constructs a command response to HD * and queues the msg for transmit on the appropriate CAN channel. * @details Inputs: none @@ -2280,6 +2369,70 @@ /*********************************************************************//** * @brief + * The handleTestMonitoredVoltagesSendIntervalOverrideRequest function handles a + * request to override the monitored DG voltages data publication interval. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestMonitoredVoltagesSendIntervalOverrideRequest( 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 = testSetVoltagesDataPublishIntervalOverride( payload.state.u32 ); + } + else + { + result = testResetVoltagesDataPublishIntervalOverride(); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief + * The handleTestMonitoredVoltageOverrideRequest function handles a + * request to override the monitored DG voltage override. + * @details Inputs: none + * @details Outputs: message handled + * @param message : a pointer to the message to handle + * @return none + *************************************************************************/ +void handleTestMonitoredVoltageOverrideRequest( MESSAGE_T *message ) +{ + TEST_OVERRIDE_ARRAY_PAYLOAD_T payload; + BOOL result = FALSE; + + // Verify payload length + if ( sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) == message->hdr.payloadLen ) + { + memcpy( &payload, message->payload, sizeof(TEST_OVERRIDE_ARRAY_PAYLOAD_T) ); + if ( FALSE == payload.reset ) + { + result = testSetLineLevelOverride( payload.index, payload.state.f32 ); + } + else + { + result = testResetLineLevelOverride( payload.index ); + } + } + + // Respond to request + sendTestAckResponseMsg( (MSG_ID_T)message->hdr.msgID, result ); +} + +/*********************************************************************//** + * @brief * The handleTestSetConductivityOverrideRequest function handles a * request to override a conductivity sensor's value * @details Inputs: none @@ -2894,6 +3047,51 @@ } /*********************************************************************//** + * @brief + * The handleUIClockSyncRequest function handles a UI clock sync message. + * @details Inputs: none + * @details Outputs: message handled, response constructed and queued for transmit. + * @param messagePtr pointer to the message to handle. + * @return none + *************************************************************************/ +void handleUIClockSyncRequest( MESSAGE_T *message ) +{ + BOOL result = FALSE; + U32 rejReason = REQUEST_REJECT_REASON_NONE; + MESSAGE_T msg; + U08 *payloadPtr = msg.payload; + + if ( message->hdr.payloadLen == sizeof( U32 ) ) + { + U32 epoch; + + memcpy( &epoch, message->payload, sizeof( U32 ) ); + result = setRTCEpoch( epoch ); + if ( FALSE == result ) + { + rejReason = REQUEST_REJECT_REASON_INVALID_DATE_OR_TIME; + } + } + else + { + rejReason = REQUEST_REJECT_REASON_INVALID_REQUEST_FORMAT; + } + + // Create a response message record + blankMessage( &msg ); + msg.hdr.msgID = MSG_ID_DG_UI_SET_RTC_RESPONSE; + msg.hdr.payloadLen = sizeof( BOOL ) + sizeof( U32 ); + memcpy( payloadPtr, &result, sizeof( BOOL ) ); + payloadPtr += sizeof( BOOL ); + memcpy( payloadPtr, &rejReason, sizeof( U32 ) ); + + // Serialize the message (w/ sync, CRC, and appropriate CAN padding) and add serialized message data to appropriate comm buffer + result = serializeMessage( msg, COMM_BUFFER_OUT_CAN_DG_2_UI, ACK_REQUIRED ); + + sendAckResponseMsg( (MSG_ID_T)message->hdr.msgID, COMM_BUFFER_OUT_CAN_DG_2_UI, result ); +} + +/*********************************************************************//** * @brief * The handleSetDGCalibrationRecord function handles a request to set the DG * calibration data record. Index: firmware/App/Services/SystemCommMessages.h =================================================================== diff -u -r8a4182663ef6b12e3fd6414c0c14158943cd4ce1 -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 8a4182663ef6b12e3fd6414c0c14158943cd4ce1) +++ firmware/App/Services/SystemCommMessages.h (.../SystemCommMessages.h) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -33,6 +33,7 @@ #include "TemperatureSensors.h" #include "Thermistors.h" #include "UVReactors.h" +#include "Voltages.h" /** * @defgroup SystemCommMessages SystemCommMessages @@ -112,6 +113,9 @@ // MSG_ID_DG_FLUID_LEAK_STATE BOOL broadcastFluidLeakState( FLUID_LEAK_STATES_T state); +// MSG_ID_DG_VOLTAGES_DATA +BOOL broadcastVoltagesData( VOLTAGES_DATA_PAYLOAD_T data ); + // MSG_ID_DG_FLUSH_DATA BOOL broadcastFlushData( MODE_FLUSH_DATA_T *flushData ); @@ -181,6 +185,12 @@ // MSG_ID_DG_SEND_SCHEDULED_RUNS_RECORD BOOL sendDGScheduledRunsRecord( U32 payloadCurrNum, U32 payloadTotalNum, U32 length, U08* scheduledRcrdAddress ); +// MSG_ID_DG_POST_SINGLE_TEST_RESULT +BOOL sendPOSTTestResult( DG_POST_STATE_T test, BOOL passed ); + +// MSG_ID_DG_POST_FINAL_TEST_RESULT +BOOL sendPOSTFinalResult( BOOL passed ); + // *********** public test support message functions ********** #ifdef DEBUG_ENABLED @@ -264,6 +274,12 @@ // MSG_ID_DG_ACCEL_SEND_INTERVAL_OVERRIDE: void handleTestDGAccelBroadcastIntervalOverrideRequest( MESSAGE_T *message ); +// MSG_ID_DG_MONITORED_VOLTAGES_SEND_INTERVAL_OVERRIDE +void handleTestMonitoredVoltagesSendIntervalOverrideRequest( MESSAGE_T *message ); + +// MSG_ID_DG_MONITORED_VOLTAGES_OVERRIDE +void handleTestMonitoredVoltageOverrideRequest( MESSAGE_T *message ); + // MSG_ID_DG_START_STOP_INLET_UV_REACTOR void handleStartStopUVReactors( MESSAGE_T *message ); @@ -321,6 +337,9 @@ // MSG_ID_DG_START_STOP_HEAT_DISINFECT BOOL handleStartStopDGHeatDisinfect( MESSAGE_T *message ); +// MSG_ID_UI_DG_SET_RTC_REQUEST +void handleUIClockSyncRequest( MESSAGE_T *message ); + // MSG_ID_DG_SET_CALIBRATION_DATA void handleSetDGCalibrationRecord( MESSAGE_T *message ); Index: firmware/DG.dil =================================================================== diff -u -r35de566c96433689821b7a21f731df26b40d67ae -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/DG.dil (.../DG.dil) (revision 35de566c96433689821b7a21f731df26b40d67ae) +++ firmware/DG.dil (.../DG.dil) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -1,4 +1,4 @@ -# RM46L852PGE 04/21/21 17:25:51 +# RM46L852PGE 04/27/21 16:18:17 # ARCH=RM46L852PGE # @@ -311,7 +311,7 @@ DRIVER.SYSTEM.VAR.VIM_CHANNEL_8_INT_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.SAFETY_INIT_STC_CPUSELFTEST_ENA.VALUE=0 DRIVER.SYSTEM.VAR.ETPWM2_ENABLE.VALUE=1 -DRIVER.SYSTEM.VAR.HET1_ENABLE.VALUE=0 +DRIVER.SYSTEM.VAR.HET1_ENABLE.VALUE=1 DRIVER.SYSTEM.VAR.CLKT_RTI1_PRE_SOURCE.VALUE=PLL1 DRIVER.SYSTEM.VAR.FLASH_MODE_VALUE.VALUE=1 DRIVER.SYSTEM.VAR.CORE_MPU_REGION_5_SIZE_VALUE.VALUE=0x19 @@ -923,7 +923,7 @@ DRIVER.SYSTEM.VAR.VIM_CHANNEL_19_INT_PRAGMA_ENABLE.VALUE=0 DRIVER.SYSTEM.VAR.SAFETY_INIT_FRAY_RAMPARITYCHECK_ENA.VALUE=0 DRIVER.SYSTEM.VAR.SAFETY_INIT_DMA_DP_PBISTCHECK_ENA.VALUE=0x00000800 -DRIVER.SYSTEM.VAR.HET_ENABLE.VALUE=0 +DRIVER.SYSTEM.VAR.HET_ENABLE.VALUE=1 DRIVER.SYSTEM.VAR.PBIST_ALGO_13_14.VALUE=0 DRIVER.SYSTEM.VAR.RAM_STACK_UNDEF_BASE.VALUE=0x08004800 DRIVER.SYSTEM.VAR.RAM_STACK_SVC_BASE.VALUE=0x08001000 @@ -5957,7 +5957,7 @@ DRIVER.HET.VAR.HET1_BIT27_PSL.VALUE=0x00000000 DRIVER.HET.VAR.HET1_BIT19_PSL.VALUE=0x00080000 DRIVER.HET.VAR.HET2_EDGE6_LVL.VALUE=0x00000000 -DRIVER.HET.VAR.HET1_BIT24_PULL.VALUE=1 +DRIVER.HET.VAR.HET1_BIT24_PULL.VALUE=0 DRIVER.HET.VAR.HET1_BIT16_PULL.VALUE=1 DRIVER.HET.VAR.HET1_BIT2_DIR.VALUE=0x00000000 DRIVER.HET.VAR.HET2_PWM6_DUTY_INTENA.VALUE=0x00000000 @@ -6231,7 +6231,7 @@ DRIVER.HET.VAR.HET1_PWM3_PERIOD.VALUE=1000.000 DRIVER.HET.VAR.HET2_PWM5_DUTY_PRESCALER.VALUE=51968 DRIVER.HET.VAR.HET1_PWM1_PERIOD_PRESCALER.VALUE=103296 -DRIVER.HET.VAR.HET1_BIT10_DIR.VALUE=0x00000400 +DRIVER.HET.VAR.HET1_BIT10_DIR.VALUE=0x00000000 DRIVER.HET.VAR.HET2_CAP4_POLARITY.VALUE=0 DRIVER.HET.VAR.HET2_BIT8_XORSHARE.VALUE=0x00000000 DRIVER.HET.VAR.HET2_BIT4_PULDIS.VALUE=0x00000000 @@ -6261,7 +6261,7 @@ DRIVER.HET.VAR.HET2_EDGE3_PIN_SELECT.VALUE=6 DRIVER.HET.VAR.HET2_PWM2_ACTUALPERIOD.VALUE=1000.862 DRIVER.HET.VAR.HET2_BIT18_PSL.VALUE=0x00000000 -DRIVER.HET.VAR.HET1_BIT11_DIR.VALUE=0x00000800 +DRIVER.HET.VAR.HET1_BIT11_DIR.VALUE=0x00000000 DRIVER.HET.VAR.HET1_BIT10_PULL.VALUE=1 DRIVER.HET.VAR.HET2_EDGE1_INTENA.VALUE=0x00000000 DRIVER.HET.VAR.HET2_PWM7_PERIOD_INTENA.VALUE=0x00000000 @@ -6337,7 +6337,7 @@ DRIVER.HET.VAR.HET1_LR_ACTUALTIME.VALUE=1238.690 DRIVER.HET.VAR.HET1_BIT21_DIR.VALUE=0x00000000 DRIVER.HET.VAR.HET1_BIT13_DIR.VALUE=0x00000000 -DRIVER.HET.VAR.HET1_BIT11_PULL.VALUE=1 +DRIVER.HET.VAR.HET1_BIT11_PULL.VALUE=2 DRIVER.HET.VAR.HET2_PWM3_DUTY.VALUE=50 DRIVER.HET.VAR.HET1_PWM7_ENA.VALUE=0 DRIVER.HET.VAR.HET1_HR_PRESCALE.VALUE=0 @@ -6426,7 +6426,7 @@ DRIVER.HET.VAR.HET1_EDGE0_EVENT.VALUE=1 DRIVER.HET.VAR.HET2_BIT10_PULDIS.VALUE=0x00000000 DRIVER.HET.VAR.HET1_CAP2_PIN_SELECT.VALUE=4 -DRIVER.HET.VAR.HET1_BIT11_PSL.VALUE=0x00000000 +DRIVER.HET.VAR.HET1_BIT11_PSL.VALUE=0x00000800 DRIVER.HET.VAR.HET2_PWM2_DUTYTIME.VALUE=501.669 DRIVER.HET.VAR.HET2_PWM0_DUTY_LVL.VALUE=0x00000000 DRIVER.HET.VAR.HET1_BIT31_DIR.VALUE=0x80000000 @@ -6571,7 +6571,7 @@ DRIVER.HET.VAR.HET1_PWM7_DUTY_INTENA.VALUE=0x00000000 DRIVER.HET.VAR.HET1_BIT10_ANDSHARE.VALUE=0x00000000 DRIVER.HET.VAR.HET1_EDGE7_PIN_SELECT.VALUE=23 -DRIVER.HET.VAR.HET1_BIT24_PDR.VALUE=0x00000000 +DRIVER.HET.VAR.HET1_BIT24_PDR.VALUE=0x01000000 DRIVER.HET.VAR.HET1_BIT16_PDR.VALUE=0x00000000 DRIVER.HET.VAR.HET1_BIT5_DOUT.VALUE=0 DRIVER.HET.VAR.HET2_PWM7_PERIOD_PRESCALER.VALUE=103296 @@ -6622,7 +6622,7 @@ DRIVER.HET.VAR.HET2_EDGE1_POLARITY.VALUE=0 DRIVER.HET.VAR.HET1_CAP7_POLARITY.VALUE=0 DRIVER.HET.VAR.HET1_BIT28_ANDSHARE.VALUE=0x00000000 -DRIVER.HET.VAR.HET1_BIT24_PULDIS.VALUE=0x00000000 +DRIVER.HET.VAR.HET1_BIT24_PULDIS.VALUE=0x01000000 DRIVER.HET.VAR.HET1_BIT16_PULDIS.VALUE=0x00000000 DRIVER.HET.VAR.HET2_BIT16_PULL.VALUE=1 DRIVER.HET.VAR.HET2_BIT12_DIR.VALUE=0x00000000 @@ -6634,7 +6634,7 @@ DRIVER.HET.VAR.HET2_EDGE6_PIN_SELECT.VALUE=12 DRIVER.HET.VAR.HET2_BIT2_PDR.VALUE=0x00000000 DRIVER.HET.VAR.HET2_DIS_BLACKBOX.VALUE=0 -DRIVER.HET.VAR.HET1_BIT24_PSL.VALUE=0x00000000 +DRIVER.HET.VAR.HET1_BIT24_PSL.VALUE=0x01000000 DRIVER.HET.VAR.HET1_BIT16_PSL.VALUE=0x00000000 DRIVER.HET.VAR.HET2_EDGE3_LVL.VALUE=0x00000000 DRIVER.HET.VAR.HET1_EDGE6_EVENT.VALUE=1 @@ -7278,7 +7278,7 @@ DRIVER.PINMUX.VAR.DMA_PRITY_1_VALUE.VALUE=0x0001 DRIVER.PINMUX.VAR.PINMUX11.VALUE=PINMUX_PIN_91_HET1_24 DRIVER.PINMUX.VAR.DMA_PRITY_12.VALUE=FIXED -DRIVER.PINMUX.VAR.PINMUX20.VALUE=PINMUX_PIN_130_HET1_17 +DRIVER.PINMUX.VAR.PINMUX20.VALUE=PINMUX_PIN_130_MIBSPI1NCS_1 DRIVER.PINMUX.VAR.PINMUX12.VALUE="PINMUX_PIN_92_HET1_26 | PINMUX_PIN_96_MIBSPI1NENA | PINMUX_PIN_97_MIBSPI5NENA" DRIVER.PINMUX.VAR.DMA_PRITY_13.VALUE=FIXED DRIVER.PINMUX.VAR.PINMUX21.VALUE=PINMUX_PIN_133_GIOB_1 @@ -7402,7 +7402,7 @@ DRIVER.PINMUX.VAR.MUX75_OPTION4.VALUE=0 DRIVER.PINMUX.VAR.MUX67_OPTION4.VALUE=0 DRIVER.PINMUX.VAR.MUX59_OPTION4.VALUE=0 -DRIVER.PINMUX.VAR.MUX6_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX6_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.DMA_CHANNEL_29.VALUE=CHANNEL0 DRIVER.PINMUX.VAR.DMA_FIDXS_7.VALUE=0 DRIVER.PINMUX.VAR.DMA_AIM_7.VALUE=ENABLED @@ -7422,7 +7422,7 @@ DRIVER.PINMUX.VAR.MUX6_OPTION3.VALUE=0 DRIVER.PINMUX.VAR.MUX60_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX52_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX44_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX44_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX36_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX28_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX6_OPTION4.VALUE=0 @@ -7498,7 +7498,7 @@ DRIVER.PINMUX.VAR.DMA_CP0_IDADDR_16.VALUE=0 DRIVER.PINMUX.VAR.DMA_STADD_2.VALUE=0 DRIVER.PINMUX.VAR.MUX21_OPTION0.VALUE=1 -DRIVER.PINMUX.VAR.MUX13_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX13_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.DMA_TTYPE_25.VALUE=FRAME_TRANSFER DRIVER.PINMUX.VAR.DMA_CP0_IDADDR_25.VALUE=0 DRIVER.PINMUX.VAR.DMA_TTYPE_17.VALUE=FRAME_TRANSFER @@ -7519,7 +7519,7 @@ DRIVER.PINMUX.VAR.PIN_MUX_71_SELECT.VALUE=0 DRIVER.PINMUX.VAR.PIN_MUX_63_SELECT.VALUE=0 DRIVER.PINMUX.VAR.PIN_MUX_55_SELECT.VALUE=0 -DRIVER.PINMUX.VAR.PIN_MUX_47_SELECT.VALUE=1 +DRIVER.PINMUX.VAR.PIN_MUX_47_SELECT.VALUE=0 DRIVER.PINMUX.VAR.PIN_MUX_39_SELECT.VALUE=0 DRIVER.PINMUX.VAR.DMA_TTYPE_27.VALUE=FRAME_TRANSFER DRIVER.PINMUX.VAR.DMA_CP0_IDADDR_27.VALUE=0 @@ -7668,7 +7668,7 @@ DRIVER.PINMUX.VAR.DMA_ADDMW_6.VALUE=CONSTANT DRIVER.PINMUX.VAR.DMA_INTFTCEN_2.VALUE=1 DRIVER.PINMUX.VAR.MUX51_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX43_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX43_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX35_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX27_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX19_OPTION0.VALUE=0 @@ -7737,7 +7737,7 @@ DRIVER.PINMUX.VAR.DMA_INTMP_2_VALUE.VALUE=0x0001 DRIVER.PINMUX.VAR.DMA_INTEN_16.VALUE=1 DRIVER.PINMUX.VAR.MUX20_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX12_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX12_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX20_OPTION1.VALUE=1 DRIVER.PINMUX.VAR.MUX12_OPTION1.VALUE=0 DRIVER.PINMUX.VAR.MUX20_OPTION2.VALUE=0 @@ -7872,7 +7872,7 @@ DRIVER.PINMUX.VAR.MUX73_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX65_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX57_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX49_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX49_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.DMA_FIDXS_25.VALUE=0 DRIVER.PINMUX.VAR.DMA_AIM_25.VALUE=ENABLED DRIVER.PINMUX.VAR.DMA_FIDXS_17.VALUE=0 @@ -7943,7 +7943,7 @@ DRIVER.PINMUX.VAR.DMA_BYP_12.VALUE=1 DRIVER.PINMUX.VAR.DMA_INTBTCEN_2.VALUE=1 DRIVER.PINMUX.VAR.MUX50_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX42_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX42_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX34_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX26_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX18_OPTION0.VALUE=0 @@ -8183,8 +8183,8 @@ DRIVER.PINMUX.VAR.DMA_ADDMR_12.VALUE=CONSTANT DRIVER.PINMUX.VAR.DMA_INTEN_6.VALUE=1 DRIVER.PINMUX.VAR.EMIF.VALUE=0 -DRIVER.PINMUX.VAR.MUX41_OPTION0.VALUE=1 -DRIVER.PINMUX.VAR.MUX33_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX41_OPTION0.VALUE=0 +DRIVER.PINMUX.VAR.MUX33_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX25_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX17_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX3_OPTION4.VALUE=0 @@ -8380,7 +8380,7 @@ DRIVER.PINMUX.VAR.MUX94_OPTION4.VALUE=0 DRIVER.PINMUX.VAR.MUX86_OPTION4.VALUE=0 DRIVER.PINMUX.VAR.MUX78_OPTION4.VALUE=0 -DRIVER.PINMUX.VAR.MUX9_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX9_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX9_OPTION1.VALUE=0 DRIVER.PINMUX.VAR.DMA_EIDXD_0.VALUE=0 DRIVER.PINMUX.VAR.DMA_CHPR_10.VALUE=HIGH @@ -8407,7 +8407,7 @@ DRIVER.PINMUX.VAR.MUX71_OPTION1.VALUE=0 DRIVER.PINMUX.VAR.MUX63_OPTION1.VALUE=0 DRIVER.PINMUX.VAR.MUX55_OPTION1.VALUE=0 -DRIVER.PINMUX.VAR.MUX47_OPTION1.VALUE=1 +DRIVER.PINMUX.VAR.MUX47_OPTION1.VALUE=0 DRIVER.PINMUX.VAR.MUX39_OPTION1.VALUE=0 DRIVER.PINMUX.VAR.MUX9_OPTION5.VALUE=0 DRIVER.PINMUX.VAR.DMA_ADDMW_10.VALUE=CONSTANT @@ -8486,7 +8486,7 @@ DRIVER.PINMUX.VAR.DMA_IET_COUNT_6.VALUE=0 DRIVER.PINMUX.VAR.DMA_TRIG_12.VALUE=HARDWARE_TRIGGER DRIVER.PINMUX.VAR.MUX40_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX32_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX32_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX24_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX16_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX2_OPTION4.VALUE=0 @@ -8691,7 +8691,7 @@ DRIVER.PINMUX.VAR.MUX70_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX62_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX54_OPTION0.VALUE=0 -DRIVER.PINMUX.VAR.MUX46_OPTION0.VALUE=1 +DRIVER.PINMUX.VAR.MUX46_OPTION0.VALUE=0 DRIVER.PINMUX.VAR.MUX38_OPTION0.VALUE=1 DRIVER.PINMUX.VAR.MUX8_OPTION4.VALUE=0 DRIVER.PINMUX.VAR.MUX70_OPTION1.VALUE=0 Index: firmware/source/sys_main.c =================================================================== diff -u -re94cf93f66b011ca994fa768b523a80fd36e00ec -r1a5efe97f5f39594b45797fded52cafce92afe80 --- firmware/source/sys_main.c (.../sys_main.c) (revision e94cf93f66b011ca994fa768b523a80fd36e00ec) +++ firmware/source/sys_main.c (.../sys_main.c) (revision 1a5efe97f5f39594b45797fded52cafce92afe80) @@ -56,6 +56,7 @@ #include "can.h" #include "etpwm.h" #include "gio.h" +#include "het.h" #include "mibspi.h" #include "sci.h" #include "rti.h" @@ -141,6 +142,7 @@ static void initProcessor( void ) { gioInit(); // configure GPIO pins + hetInit(); // Configure HET1 adcInit(); // configure internal ADC channels mibspiInit(); // configure MIBSPI3 and re-purpose MIBSPI1 & 5 pins for GPIO etpwmInit(); // configure PWMs