/************************************************************************** * * Copyright (c) 2020-2024 Diality Inc. - All Rights Reserved. * * THIS CODE MAY NOT BE COPIED OR REPRODUCED IN ANY FORM, IN PART OR IN * WHOLE, WITHOUT THE EXPLICIT PERMISSION OF THE COPYRIGHT OWNER. * * @file DrainPump.c * * @author (last) Dara Navaei * @date (last) 07-Mar-2024 * * @author (original) Sean * @date (original) 08-Apr-2020 * ***************************************************************************/ #include #include "etpwm.h" #include "mibspi.h" #include "DrainPump.h" #include "FlowSensors.h" #include "FPGA.h" #include "MessageSupport.h" #include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "PIControllers.h" #include "Pressures.h" #include "ROPump.h" #include "SafetyShutdown.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "TaskPriority.h" #include "Timers.h" #include "Utilities.h" #include "Valves.h" /** * @addtogroup DrainPump * @{ */ // ********** private definitions ********** #define DRAIN_PUMP_MIN_DAC GET_RPM_2_DAC_CONVERSION( MIN_DRAIN_PUMP_RPM ) ///< Drain pump minimum RPM to DAC conversion. #define DRAIN_PUMP_MAX_DAC GET_RPM_2_DAC_CONVERSION( MAX_DRAIN_PUMP_RPM ) ///< Drain pump maximum RPM to DAC conversion. #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 ( 1000 / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Drain pump is controlled. #define DRP_CONTROL_MAX_ALLOWED_PPO_PSI CLEANING_MODE_HIGH_TEMP_MAX_RO_PRESSURE_PSI ///< Drain pump maximum allowed PPo pressure in psi. #define DRP_CONTROL_MAX_ALLOWED_PDR_PSI 40.0F ///< Drain pump maximum allowed PDr pressure in psi. #define DRP_CONTROL_PSI_TO_DAC_P_ONLY_TERM 0.2F ///< Drain pump psi to DAC conversion. #define DRP_CONTROL_FLOW_TO_DAC_P_ONLY_TERM 100.0F ///< Drain pump flow (L/min) to DAC conversion. #define DRP_CONTROL_PRES_TO_MAX_THRESHOLD_PSI 1.0F ///< Drain pump pressure to maximum pressure threshold in psi. #define DRP_CONTROL_MIN_DAC_CHANGE 1 ///< Drain pump minimum DAC change #define RPM_2_DAC_SLOPE 0.0547F ///< RPM to DAC conversion slope. #define RPM_2_DAC_INTERCEPT 2.9968F ///< 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.000005F ///< Toggle period to resolution in seconds. #define ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION 4.0F ///< Rotational to toggle period conversion coefficient. #define DRAIN_PUMP_P_COEFFICIENT 20.0F ///< P term for drain pump delta pressure control. #define DRAIN_PUMP_I_COEFFICIENT 80.0F ///< I term for drain pump delta pressure control. #define MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE 100 ///< Maximum allowed RPM out of range from target RPM in open loop. #define OPEN_LOOP_RPM_OUT_OF_RANGE_TIME_OUT ( 10 * MS_PER_SECOND ) ///< Open loop RPM out of range time out in ms. #define DRAIN_PUMP_ENABLE_SPI3_PORT_MASK 0x00000020 ///< CS5 - Out put GPIO for pump enable. #define SET_DRAIN_PUMP_ENABLE() {mibspiREG3->PC3 |= DRAIN_PUMP_ENABLE_SPI3_PORT_MASK;} ///< Drain pump enable set macro. #define CLR_DRAIN_PUMP_ENABLE() {mibspiREG3->PC3 &= ~DRAIN_PUMP_ENABLE_SPI3_PORT_MASK;} ///< Drain pump enable clear macro. #define SAFETY_SHUTDOWN_TIMEOUT ( 1 * MS_PER_SECOND ) ///< Drain pump safety shutdown activation timeout. #define DRAIN_PUMP_OFF_RPM_ADC_COUNT 0xFFFF ///< ADC count value when pump is off. #define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. #define DRAIN_PUMP_MAX_CURRENT_WHEN_OFF_A 0.1F ///< Drain pump maximum current when the pump is off in amps. #define DRAIN_PUMP_MAX_CURRENT_A 2.2F ///< Drain pump maximum current in amps. #define DRAIN_PUMP_CURRENT_OUT_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Drain pump current out of range timeout in milliseconds. #define DRAIN_PUMP_DIR_OF_RANGE_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< Drain pump direction out of range timeout in milliseconds. #define DRAIN_PUMP_FORWARD_DIR 1 ///< Drain pump forward direction. #define DRAIN_PUMP_DIR_BIT_MASK 0x80 ///< Drain pump direction bit clear mask. #define DRAIN_PUMP_DIR_ERROR_CNT_BIT_MASK 0x3F ///< Drain pump direction error count bit mask. #define MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_WINDOW_MS ( 1 * SEC_PER_MIN * MS_PER_SECOND ) ///< FPGA drain pump direction fault window #define MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_FAILURES 10 ///< FPGA drain pump direction fault failures per MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_WINDOW_MS /// Enumeration of drain pump states. typedef enum DrainPump_States { DRAIN_PUMP_OFF_STATE = 0, ///< Drain pump off state DRAIN_PUMP_CONTROL_TO_TARGET_STATE, ///< Drain pump control to target state DRAIN_PUMP_OPEN_LOOP_STATE, ///< Drain pump open loop state NUM_OF_DRAIN_PUMP_STATES ///< Number of drain pump states } DRAIN_PUMP_STATE_T; /// Enumeration of drain pump self-test states. typedef enum DrainPump_Self_Test_States { DRAIN_PUMP_SELF_TEST_STATE_START = 0, ///< Drain pump self-test start state DRAIN_PUMP_TEST_STATE_IN_PROGRESS, ///< Drain pump self-test in progress state DRAIN_PUMP_TEST_STATE_COMPLETE, ///< Drain pump self-test completed state NUM_OF_DRAIN_PUMP_SELF_TEST_STATES ///< Number of drain pump self-test states } DRAIN_PUMP_SELF_TEST_STATE_T; // ********** private data ********** static DRAIN_PUMP_STATE_T drainPumpState; ///< Current state of drain pump controller state machine. static U32 drainPumpDataPublicationTimerCounter; ///< Used to schedule drain pump data publication to CAN bus. static U32 drainPumpDAC; ///< Initial drain pump DAC value. static U32 drainPumpDACSet; ///< Currently set drain pump DAC value. static PUMP_CONTROL_MODE_T drainPumpControlMode; ///< Requested drain pump control mode. static PUMP_CONTROL_MODE_T drainPumpControlModeSet; ///< Currently set drain pump control mode. static OVERRIDE_U32_T drainPumpDataPublishInterval = { DRAIN_PUMP_DATA_PUB_INTERVAL, DRAIN_PUMP_DATA_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish drain pump data to CAN bus. static U32 targetDrainPumpRPM; ///< Target drain pump RPM. static F32 targetDrainPumpOutletFlowLPM; ///< Target outlet pressure for the drain pump. static U32 drainControlTimerCtr; ///< Determines when to perform control on drain pump. static BOOL hasClosedLoopBeenRequested; ///< Closed loop pump control flag. static OVERRIDE_U32_T drainPumpHallMeasuredRPM = { 0, 0, 0, 0 }; ///< Measured drain pump RPM from feedback. static OVERRIDE_U32_T drainPumpMaxonMeasuredRPM = { 0, 0, 0, 0 }; ///< Measured Maxon drain pump RPM. static OVERRIDE_F32_T drainPumpMeasuredCurrentA = { 0.0F, 0.0F, 0.0F, 0 }; ///< Measured drain pump current feedback. static OVERRIDE_U32_T drainPumpMeasuredDir = { 0, 0, 0, 0 }; ///< Measured drain pump direction. static BOOL signalNewRPMRequest; ///< Signal flag the indicates there is a new RPM request. static DRAIN_PUMP_STATE_T pendingDrainPumpCmd; ///< Delayed (pending) drain pump command. static F32 pendingDrainPumpCmdTarget; ///< Delayed (pending) drain pump command target (rpm or PSI depending on command). static U32 pendingDrainPumpCmdCountDown; ///< Delayed (pending) drain pump command count down timer (in task intervals). static DG_DRAIN_LINE_VOLUME_T drainLineVolumeRecord; ///< Drain line volume record. static DG_DRAIN_PUMP_CAL_RECORD_T drainPumpCalRecord; ///< Drain pump calibration record. static BOOL isDrainPumpControlInFlowMode; ///< Drain pump flag to indicate whether the drain pump in flow control or not. /// ADC to RPM conversion coefficient or RPM to ADC conversion. static const F32 RPM_CONVERSION_COEFF = (F32) SEC_PER_MIN / ( 2.0F * TOGGLE_PERIOD_RESOLUTION_SECONDS * ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION ); static const F32 CURRENT_CONVERSION_COEFF = (F32)( 2.5F / ( BITS_12_FULL_SCALE - 1.0F ) ); /// Drain pump hall sensor failure count static U32 lastDirHallSensorErrorCount = 0; ///< Last drain pump encoder errors for hal sensor // ********** private function prototypes ********** static DRAIN_PUMP_STATE_T handleDrainPumpOffState( void ); static DRAIN_PUMP_STATE_T handleDrainPumpControlToTargetState( void ); static DRAIN_PUMP_STATE_T handleDrainPumpOpenLoopState( void ); static void stopDrainPump( void ); static void publishDrainPumpData( void ); static F32 getDrainPumpMeasuredCurrentA( void ); static U32 getDrainPumpMeasuredDirection( void ); /*********************************************************************//** * @brief * The initDrainPump function initializes the DrainPump module. * @details Inputs: none * @details Outputs: drainPumpState, drainPumpDAC, drainPumpDACSet, * drainPumpControlMode, drainPumpControlModeSet, targetDrainPumpRPM, * targetDrainPumpOutletFlowLPM, drainControlTimerCtr, * pendingDrainPumpCmd, pendingDrainPumpCmdTarget, pendingDrainPumpCmdCountDown, * hasClosedLoopBeenRequested, signalNewRPMRequest, lastDrainPumpEncoderErrors, * drainPumpDataPublicationTimerCounter, isDrainPumpControlInFlowMode * @return none *************************************************************************/ void initDrainPump( void ) { stopDrainPump(); drainPumpState = DRAIN_PUMP_OFF_STATE; drainPumpDAC = 0; drainPumpDACSet = 0; drainPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; drainPumpControlModeSet = PUMP_CONTROL_MODE_CLOSED_LOOP; targetDrainPumpRPM = 0; targetDrainPumpOutletFlowLPM = 0.0F; drainControlTimerCtr = 0; pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; pendingDrainPumpCmdTarget = 0.0F; pendingDrainPumpCmdCountDown = 0; hasClosedLoopBeenRequested = FALSE; signalNewRPMRequest = FALSE; drainPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; isDrainPumpControlInFlowMode = TRUE; lastDirHallSensorErrorCount = 0; // Initialize the drain pump PI controller initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_MAX_DAC ); // Initialize the persistent alarms initPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_RPM_OUT_OF_RANGE, OPEN_LOOP_RPM_OUT_OF_RANGE_TIME_OUT, OPEN_LOOP_RPM_OUT_OF_RANGE_TIME_OUT ); initPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT, SAFETY_SHUTDOWN_TIMEOUT, SAFETY_SHUTDOWN_TIMEOUT ); initPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, DRAIN_PUMP_CURRENT_OUT_OF_RANGE_TIMEOUT_MS, DRAIN_PUMP_CURRENT_OUT_OF_RANGE_TIMEOUT_MS ); initPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, DRAIN_PUMP_DIR_OF_RANGE_TIMEOUT_MS, DRAIN_PUMP_DIR_OF_RANGE_TIMEOUT_MS ); // initialize FPGA drain pump hall sensor error initTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_DRAIN_PUMP_HALL_SENSOR_ERROR, MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_FAILURES, MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_WINDOW_MS); } /*********************************************************************//** * @brief * The setDrainPumpTargetSpeed function sets a new target RPM for the * drain pump. * @details Inputs: none * @details Outputs: drainPumpDAC, targetDrainPumpRPM, drainPumpControlMode, * drainPumpControlModeSet, signalNewRPMRequest * @param rpm new drain pump target RPM * @return TRUE if new target RPM is set, FALSE if not *************************************************************************/ BOOL setDrainPumpTargetRPM( U32 rpm ) { BOOL result = FALSE; if ( ( 0 == rpm ) || ( ( rpm >= MIN_DRAIN_PUMP_RPM ) && ( rpm <= MAX_DRAIN_PUMP_RPM ) ) ) { drainPumpDAC = (U32)GET_RPM_2_DAC_CONVERSION(rpm); targetDrainPumpRPM = rpm; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; signalNewRPMRequest = TRUE; // If this function was called, delayed command does not need to be executed // so the pending count down is zeroed. pendingDrainPumpCmdCountDown = 0; result = TRUE; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_INVALID_RPM_SELECTED, rpm ) } return result; } /*********************************************************************//** * @brief * The setDrainPumpTargetRPMDelayed function sets a new target RPM for the * drain pump with delayed start. * @details Inputs: drainPumpDAC, targetDrainPumpSpeed, drainPumpControlMode, * drainPumpControlModeSet * @details Outputs: pendingDrainPumpCmd, pendingDrainPumpCmdTarget, pendingDrainPumpCmdCountDown * @param rpm new drain pump target RPM * @param delayMs delay duration (in ms) before drain pump started * @return TRUE if new target RPM is set, FALSE if not *************************************************************************/ BOOL setDrainPumpTargetRPMDelayed( U32 rpm, U32 delayMs ) { BOOL result = FALSE; if ( ( 0 == rpm ) || ( ( rpm >= MIN_DRAIN_PUMP_RPM ) && ( rpm <= MAX_DRAIN_PUMP_RPM ) ) ) { pendingDrainPumpCmd = DRAIN_PUMP_OPEN_LOOP_STATE; pendingDrainPumpCmdTarget = (F32)rpm; pendingDrainPumpCmdCountDown = delayMs / TASK_GENERAL_INTERVAL; result = TRUE; } else { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_INVALID_RPM_SELECTED, rpm ) } return result; } /*********************************************************************//** * @brief * The setDrainPumpTargetOutletFlowLPM function sets the drain pump target flow * rate in L/min. * @details Inputs: none * @details Outputs: targetDrainPumpOutletFlowFMP, hasClosedLoopBeenRequested, * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet, * isDrainPumpControlInFlowMode * @param flow new target flow in L/min * @return TRUE if new target speed is set, FALSE if not *************************************************************************/ BOOL setDrainPumpTargetOutletFlowLPM( F32 flow ) { BOOL result = FALSE; // Check the delta pressure is in range if ( ( flow >= MIN_RO_FLOWRATE_LPM ) && ( flow <= MAX_RO_FLOWRATE_LPM ) ) { // Set all the variables for closed loop mode targetDrainPumpOutletFlowLPM = flow; hasClosedLoopBeenRequested = TRUE; drainPumpDAC = DRAIN_PUMP_MIN_DAC; drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; drainPumpControlModeSet = drainPumpControlMode; result = TRUE; isDrainPumpControlInFlowMode = TRUE; resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC ); } else { SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_TARGET_FLOW_LPM_SELECTED, flow ) } return result; } /*********************************************************************//** * @brief * The signalDrainPumpHardStop function stops the Drain pump immediately. * @details Inputs: none * @details Outputs: targetDrainPumpRPM, drainPumpState, drainPumpControlMode, * hasClosedLoopBeenRequested, drainControlTimerCounter, drainPumpControlModeSet, * drainControlTimerCtr, pendingDrainPumpCmd, pendingDrainPumpCmdTarget, * pendingDrainPumpCmdCountDown * @return none *************************************************************************/ void signalDrainPumpHardStop( void ) { stopDrainPump(); // Reset all the variables to stop mode targetDrainPumpRPM = 0; drainPumpState = DRAIN_PUMP_OFF_STATE; hasClosedLoopBeenRequested = FALSE; drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; drainPumpControlModeSet = drainPumpControlMode; drainControlTimerCtr = 0; pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; pendingDrainPumpCmdTarget = 0.0F; pendingDrainPumpCmdCountDown = 0; } /*********************************************************************//** * @brief * The execDrainPumpMonitor function executes the drain pump monitor. * RPM = ( 1 / ADC ) * conversion coefficient. * ADC = ( 1 / RPM ) * conversion coefficient. * @details Inputs: drainPumpMeasuredRPM, drainPumpMeasuredCurrentA, * drainPumpMeasuredDir * @details Outputs: drainPumpMeasuredRPM, drainPumpMeasuredCurrentA, * drainPumpMeasuredDir * @return none *************************************************************************/ void execDrainPumpMonitor( void ) { U16 fpgaADCSpeedCount = getFPGADrainPumpSpeed(); U16 fpgaMaxonADCSpeedCount = getFPGADrainPumpSpeedFeedback(); U16 fpgaADCCurrentCount = getFPGADrainPumpCurrentFeedback(); F32 currentA = getDrainPumpMeasuredCurrentA(); U32 dirHallSensorErrorCount = (U32)( getFPGADrainPumpDirection() & DRAIN_PUMP_DIR_ERROR_CNT_BIT_MASK ); BOOL isOffCurrentOut = FALSE; BOOL isCurrentOutOfRange = FALSE; // Update the override variables drainPumpMaxonMeasuredRPM.data = MAX_DRAIN_PUMP_RPM * ( (F32)fpgaMaxonADCSpeedCount / (F32)BITS_12_FULL_SCALE ); drainPumpHallMeasuredRPM.data = ( DRAIN_PUMP_OFF_RPM_ADC_COUNT == fpgaADCSpeedCount ? 0 : (U32)( RPM_CONVERSION_COEFF / (F32)fpgaADCSpeedCount ) ); drainPumpMeasuredCurrentA.data = (F32)fpgaADCCurrentCount * CURRENT_CONVERSION_COEFF; drainPumpMeasuredDir.data = (U32)( ( getFPGADrainPumpDirection() & DRAIN_PUMP_DIR_BIT_MASK ) >> SHIFT_BITS_BY_7 ); #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_DRAIN_PUMP_MONITOR ) != SW_CONFIG_ENABLE_VALUE ) #endif { if ( dirHallSensorErrorCount != lastDirHallSensorErrorCount ) { if ( TRUE == incTimeWindowedCount( TIME_WINDOWED_COUNT_FPGA_DRAIN_PUMP_HALL_SENSOR_ERROR ) ) { SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_FPGA_FAULT, MAX_FPGA_DRAIN_PUMP_DIRECTION_FAULT_FAILURES, dirHallSensorErrorCount ) } lastDirHallSensorErrorCount = dirHallSensorErrorCount; } switch( drainPumpState ) { case DRAIN_PUMP_OFF_STATE: { BOOL isRPMTooHigh = FALSE; isOffCurrentOut = ( currentA > DRAIN_PUMP_MAX_CURRENT_WHEN_OFF_A ? TRUE : FALSE ); isRPMTooHigh |= ( getDrainPumpMeasuredRPM( DRAIN_PUMP_HALL_SNSR_FB ) > MIN_DRAIN_PUMP_RPM ? TRUE : FALSE ); isRPMTooHigh |= ( getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ) > MIN_DRAIN_PUMP_RPM ? TRUE : FALSE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ), MIN_DRAIN_PUMP_RPM ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, FALSE, getFPGADrainPumpDirection(), DRAIN_PUMP_FORWARD_DIR ); // If the off fault alarm has become active, trigger the safety shutdown if ( TRUE == isAlarmActive( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT ) ) { activateSafetyShutdown(); } } break; // The RPM is only checked in open loop state that the pump is run at a fixed RPM. case DRAIN_PUMP_OPEN_LOOP_STATE: { U32 rpmHall = getDrainPumpMeasuredRPM( DRAIN_PUMP_HALL_SNSR_FB ); U32 rpmMaxon = getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ); BOOL isRPMOutOfRange = FALSE; U32 direction = getDrainPumpMeasuredDirection(); BOOL isDirInvalid = ( ( direction != DRAIN_PUMP_FORWARD_DIR ) && ( rpmMaxon > 0 ) ? TRUE : FALSE ); // Make sure the pump is running prior to checking the direction error U32 rpmHallDiff = abs( getDrainPumpTargetRPM() - rpmHall ); U32 rpmMaxonDiff = abs( getDrainPumpTargetRPM() - rpmMaxon ); isRPMOutOfRange |= ( rpmHallDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); isRPMOutOfRange |= ( rpmMaxonDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, rpmHall, MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT, FALSE, rpmHall, MIN_DRAIN_PUMP_RPM ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); } break; case DRAIN_PUMP_CONTROL_TO_TARGET_STATE: { U32 direction = getDrainPumpMeasuredDirection(); U32 rpmMaxon = getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ); BOOL isDirInvalid = ( ( direction != DRAIN_PUMP_FORWARD_DIR ) && ( rpmMaxon > 0 ) ? TRUE : FALSE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, isDirInvalid, (F32)direction, DRAIN_PUMP_FORWARD_DIR ); } break; default: // There are not out of range conditions, clear the alarms checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_RPM_OUT_OF_RANGE, FALSE, getDrainPumpMeasuredRPM( DRAIN_PUMP_HALL_SNSR_FB ), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_OFF_FAULT, FALSE, getDrainPumpMeasuredRPM( DRAIN_PUMP_HALL_SNSR_FB ), MIN_DRAIN_PUMP_RPM ); checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_DIRECTION_INVALID, FALSE, getFPGADrainPumpDirection(), DRAIN_PUMP_FORWARD_DIR ); break; } // Check the persistent alarm for the maximum drain pump current isCurrentOutOfRange = ( currentA > DRAIN_PUMP_MAX_CURRENT_A ? TRUE : FALSE ) | isOffCurrentOut; checkPersistentAlarm( ALARM_ID_DG_DRAIN_PUMP_CURRENT_OUT_OF_RANGE, isCurrentOutOfRange, currentA, DRAIN_PUMP_MAX_CURRENT_A ); } // Publish drain pump data on interval publishDrainPumpData(); } /*********************************************************************//** * @brief * The execDrainPumpController function executes the drain pump controller. * @details Inputs: drainPumpState, pendingDrainPumpCmdCountDown, * pendingDrainPumpCmd * @details Outputs: drainPumpState, pendingDrainPumpCmdCountDown, * pendingDrainPumpCmd, targetDrainPumpOutletFlowLPM, drainPumpDAC, * hasClosedLoopBeenRequested, drainPumpControlMode, drainPumpControlModeSet * @return none *************************************************************************/ void execDrainPumpController( void ) { // Check if a new calibration is available if ( TRUE == isNewCalibrationRecordAvailable() ) { // This is only one record the number of items to check is 0 since the get NV data function does not do a for loop to check the calibration time getNVRecord2Driver( GET_CAL_DRAIN_LINE_VOLUME_RECORD, (U08*)&drainLineVolumeRecord, sizeof( DG_DRAIN_LINE_VOLUME_T ), 0, ALARM_ID_DG_DRAIN_LINE_VOLUME_INVALID_CAL_RECORD ); } // Handle pending drain pump command if ( pendingDrainPumpCmdCountDown > 0 ) { pendingDrainPumpCmdCountDown--; if ( 0 == pendingDrainPumpCmdCountDown ) { if ( DRAIN_PUMP_CONTROL_TO_TARGET_STATE == pendingDrainPumpCmd ) { targetDrainPumpOutletFlowLPM = pendingDrainPumpCmdTarget; hasClosedLoopBeenRequested = TRUE; drainPumpDAC = DRAIN_PUMP_MIN_DAC; drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; drainPumpControlModeSet = drainPumpControlMode; } else if ( DRAIN_PUMP_OPEN_LOOP_STATE == pendingDrainPumpCmd ) { drainPumpDAC = (U32)( pendingDrainPumpCmdTarget * RPM_2_DAC_SLOPE - RPM_2_DAC_INTERCEPT + FLOAT_TO_INT_ROUNDUP_OFFSET ); targetDrainPumpRPM = (U32)pendingDrainPumpCmdTarget; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; signalNewRPMRequest = TRUE; } pendingDrainPumpCmdTarget = 0.0F; pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; } } // Execute drain pump state machine switch ( drainPumpState ) { case DRAIN_PUMP_OFF_STATE: drainPumpState = handleDrainPumpOffState(); break; case DRAIN_PUMP_CONTROL_TO_TARGET_STATE: drainPumpState = handleDrainPumpControlToTargetState(); break; case DRAIN_PUMP_OPEN_LOOP_STATE: drainPumpState = handleDrainPumpOpenLoopState(); break; default: // Wrong state was selected SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_INVALID_EXEC_STATE, drainPumpState ) drainPumpState = DRAIN_PUMP_OFF_STATE; break; } } /*********************************************************************//** * @brief * The execDrainPumpSelfTest function executes the drain pump's self-test. * @details Inputs: none * @details Outputs: none * @return PressuresSelfTestResult (SELF_TEST_STATUS_T) *************************************************************************/ SELF_TEST_STATUS_T execDrainPumpSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; BOOL calStatus = FALSE; // This is only one record the number of items to check is 0 since the get NV data function does not do a for loop to check the calibration time calStatus |= getNVRecord2Driver( GET_CAL_DRAIN_LINE_VOLUME_RECORD, (U08*)&drainLineVolumeRecord, sizeof( DG_DRAIN_LINE_VOLUME_T ), 0, ALARM_ID_DG_DRAIN_LINE_VOLUME_INVALID_CAL_RECORD ); calStatus |= getNVRecord2Driver( GET_CAL_DRAIN_PUMP_RECORD, (U08*)&drainPumpCalRecord, sizeof( DG_DRAIN_PUMP_CAL_RECORD_T ), 0, ALARM_ID_NO_ALARM ); if ( TRUE == calStatus ) { result = SELF_TEST_STATUS_PASSED; } else { result = SELF_TEST_STATUS_FAILED; } return result; } /*********************************************************************//** * @brief * The getDrainPumpTargetRPM function gets the current target drain pump * RPM. * @details Inputs: targetDrainPumpRPM * @details Outputs: none * @return the current target drain pump RPM. *************************************************************************/ U32 getDrainPumpTargetRPM( void ) { return targetDrainPumpRPM; } /*********************************************************************//** * @brief * The getDrainPumpMeasuredRPM function returns the RPM read from the drain * pump RPM sensor. * @details Inputs: drainPumpMeasuredRPM * @details Outputs: none * @param sensor to get its RPM from (Hall sensor or Maxon board in DVT) * @return drain pump RPM *************************************************************************/ U32 getDrainPumpMeasuredRPM( DRAIN_PUMP_SPEED_FB_SNSR_T sensor ) { U32 rpm = 0; if ( DRAIN_PUMP_HALL_SNSR_FB == sensor ) { rpm = getU32OverrideValue( &drainPumpHallMeasuredRPM ); } else if ( DRAIN_PUMP_MAXON_SNSR_FB == sensor ) { rpm = getU32OverrideValue( &drainPumpMaxonMeasuredRPM ); } return rpm; } /*********************************************************************//** * @brief * The targetDrainPumpOutletFlowLPM function gets the current target * drain pump flow in L/min. * @details Inputs: targetDrainPumpOutletPressure * @details Outputs: none * @return the current target drain pump flow in L/min *************************************************************************/ F32 getDrainPumpTargetOutletFlowLPM( void ) { return targetDrainPumpOutletFlowLPM; } /*********************************************************************//** * @brief * The isDrainPumpOn function determines whether the drain pump is on. * @details Inputs: drainPumpDACSet * @details Outputs: none * @return TRUE if drain pump is on, FALSE if not. *************************************************************************/ BOOL isDrainPumpOn( void ) { return ( drainPumpDACSet > 0 ? TRUE : FALSE ); } /*********************************************************************//** * @brief * The getFlushLineVolumeL function returns the target flush line volume in * liters. * @details Inputs: drainLineVolumeRecord * @details Outputs: none * @return the target flush line volume in Liter *************************************************************************/ F32 getFlushLineVolumeL( void ) { return drainLineVolumeRecord.volume; } /*********************************************************************//** * @brief * The handleDrainPumpOffState function handles the drain pump off state of * the drain pump controller state machine. * @details Inputs: drainPumpControlModeSet, hasClosedLoopBeenRequested * * @details Outputs: drainPumpDACSet, signalNewRPMRequest * @return next state for the controller state machine *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpOffState( void ) { DRAIN_PUMP_STATE_T result = DRAIN_PUMP_OFF_STATE; // If the target drain pump speed was not 0 and the control mode // is open loop, set the drain pump to open loop if ( ( getDrainPumpTargetRPM() > 0 ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) ) { // Set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); // Set drain pump DAC drainPumpDACSet = drainPumpDAC; setFPGADrainPumpSpeed( drainPumpDACSet ); result = DRAIN_PUMP_OPEN_LOOP_STATE; } // If the drain pump is set to closed loop, call the proper state // It is checked for the value of delta pressure because it can be anything including 0 else if ( ( PUMP_CONTROL_MODE_CLOSED_LOOP == drainPumpControlModeSet ) && ( TRUE == hasClosedLoopBeenRequested ) ) { // set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); resetPIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC ); // set drain pump DAC drainPumpDACSet = drainPumpDAC; setFPGADrainPumpSpeed( drainPumpDACSet ); result = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; } return result; } /*********************************************************************//** * @brief * The handleDrainPumpControlToTargetState function handles the control to * target state of the drain pump controller state machine. * @details Inputs: drainControlTimerCtr * @details Outputs: drainControlTimerCtr, drainPumpDACSet * @return next state of the controller state machine *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpControlToTargetState( void ) { DRAIN_PUMP_STATE_T state = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; // control at set interval if ( ++drainControlTimerCtr >= DRP_CONTROL_INTERVAL ) { U32 tempDACSet; F32 drainPumpOutletPressurePSI = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); F32 roPumpOutletPressurePSI = getMeasuredDGPressure( PRESSURE_SENSOR_RO_PUMP_OUTLET ); F32 targetROFlowLPM = getDrainPumpTargetOutletFlowLPM(); F32 msrdROFlowLPM = getMeasuredROFlowRateWithConcPumpsLPM(); F32 flowSubLPM = msrdROFlowLPM - targetROFlowLPM; if ( TRUE == isDrainPumpControlInFlowMode ) { F32 dac = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP, targetROFlowLPM, msrdROFlowLPM ); drainPumpDACSet = (U32)( dac + FLOAT_TO_INT_ROUNDUP_OFFSET ); if ( ( drainPumpOutletPressurePSI > DRP_CONTROL_MAX_ALLOWED_PDR_PSI ) || ( roPumpOutletPressurePSI > (F32)DRP_CONTROL_MAX_ALLOWED_PPO_PSI ) ) { // If either of the pressure sensors are above range, transition to control to pressure isDrainPumpControlInFlowMode = FALSE; } } else if ( flowSubLPM > 0.0F ) { // If measured flow if greater than the target flow, adjust the DAC to lower the flow rate tempDACSet = (U32)( ( flowSubLPM * DRP_CONTROL_FLOW_TO_DAC_P_ONLY_TERM ) + FLOAT_TO_INT_ROUNDUP_OFFSET ); tempDACSet = ( tempDACSet > drainPumpDACSet ? DRAIN_PUMP_MIN_DAC : tempDACSet ); drainPumpDACSet -= tempDACSet; } else { // Get the status of the current pressure readings with respect to their maximum pressures // Get the maximum of the pressure difference of PPo and PDr F32 pdrSubPSI = drainPumpOutletPressurePSI - DRP_CONTROL_MAX_ALLOWED_PDR_PSI; F32 ppoSubPSI = roPumpOutletPressurePSI - (F32)DRP_CONTROL_MAX_ALLOWED_PPO_PSI; F32 maxPresPSI = MAX( pdrSubPSI, ppoSubPSI ); if ( ( pdrSubPSI > 0.0F ) || ( ppoSubPSI > 0.0F ) ) { // If either of the pressure values are greater than the maximum pressure, recalculate the DAC by the maximum pressure difference // If the calculated DAC value turned out to be 0, set it to 1 so it changes at least by 1 DAC tempDACSet = (U32)( ( maxPresPSI * DRP_CONTROL_PSI_TO_DAC_P_ONLY_TERM ) + FLOAT_TO_INT_ROUNDUP_OFFSET ); tempDACSet = ( tempDACSet > drainPumpDACSet ? DRAIN_PUMP_MIN_DAC : tempDACSet ); drainPumpDACSet -= tempDACSet; } else if ( ( fabs(pdrSubPSI) > DRP_CONTROL_PRES_TO_MAX_THRESHOLD_PSI ) && ( fabs(ppoSubPSI) > DRP_CONTROL_PRES_TO_MAX_THRESHOLD_PSI ) ) { // If both of the DACs turned out to be less than their maximum pressure limits by more than the specified value, recalculate the // DAC. Using fabs for the subtraction means both pressure subtractions are negative so they are below their limits. // In the calculations use fabs for max pressure because it is negative so it will end of subtracting DAC but it should be adding tempDACSet = (U32)( ( fabs(maxPresPSI) * DRP_CONTROL_PSI_TO_DAC_P_ONLY_TERM ) + FLOAT_TO_INT_ROUNDUP_OFFSET ); drainPumpDACSet += tempDACSet; } } // Check the DAC to make sure it is not out the min and max ranges of the drain pump tempDACSet = drainPumpDACSet; tempDACSet = MIN( tempDACSet, DRAIN_PUMP_MAX_DAC ); tempDACSet = MAX( tempDACSet, DRAIN_PUMP_MIN_DAC ); drainPumpDACSet = tempDACSet; drainControlTimerCtr = 0; setFPGADrainPumpSpeed( drainPumpDACSet ); } return state; } /*********************************************************************//** * @brief * The handleDrainPumpOpenLoopState function handles the open loop state. * @details Inputs: signalNewRPMRequest * @details Outputs: signalNewRPMRequest, drainPumpDACSet * @return next state of the controller state machine *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpOpenLoopState( void ) { DRAIN_PUMP_STATE_T state = DRAIN_PUMP_OPEN_LOOP_STATE; // If there is a signal for a new RPM, change to the new RPM if ( TRUE == signalNewRPMRequest ) { // Set drain pump DAC drainPumpDACSet = drainPumpDAC; signalNewRPMRequest = FALSE; setFPGADrainPumpSpeed( drainPumpDACSet ); } return state; } /*********************************************************************//** * @brief * The stopDrainPump function sets the drain pump DAC to zero and stops * the pump. * @details Inputs: drainPumpDAC, drainPumpDACSet * @details Outputs: drainPumpDAC, drainPumpDACSet * @return none *************************************************************************/ static void stopDrainPump( void ) { drainPumpDAC = 0; drainPumpDACSet = 0; setFPGADrainPumpSpeed( drainPumpDACSet ); CLR_DRAIN_PUMP_ENABLE(); } /*********************************************************************//** * @brief * The publishDrainPumpData function publishes drain pump data at the set * interval. * @details Inputs: drainPumpDataPublicationTimerCounter * @details Outputs: none * @return none *************************************************************************/ static void publishDrainPumpData( void ) { // publish Drain pump data on interval if ( ++drainPumpDataPublicationTimerCounter >= getU32OverrideValue( &drainPumpDataPublishInterval ) ) { DRAIN_PUMP_DATA_T drainPumpData; // Populate the data structure for publication drainPumpData.rpmSetPoint = getDrainPumpTargetRPM(); drainPumpData.pumpDACSet = drainPumpDACSet; drainPumpData.drainPumpState = (U32)drainPumpState; drainPumpData.drainPumpHallRPM = getDrainPumpMeasuredRPM( DRAIN_PUMP_HALL_SNSR_FB ); drainPumpData.trgtOutletFlowLPM = targetDrainPumpOutletFlowLPM; drainPumpData.drainPumpCurrentA = getDrainPumpMeasuredCurrentA(); drainPumpData.drainPumpDirection = getDrainPumpMeasuredDirection(); drainPumpData.drainPumpMaxonRPM = getDrainPumpMeasuredRPM( DRAIN_PUMP_MAXON_SNSR_FB ); broadcastData( MSG_ID_DRAIN_PUMP_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&drainPumpData, sizeof( DRAIN_PUMP_DATA_T ) ); drainPumpDataPublicationTimerCounter = 0; } } /*********************************************************************//** * @brief * The getDrainPumpMeasuredCurrentA function returns the drain pump current * feedback. * @details Inputs: drainPumpMeasuredCurrent * @details Outputs: none * @return drain pump current feedback *************************************************************************/ static F32 getDrainPumpMeasuredCurrentA( void ) { F32 current = getF32OverrideValue( &drainPumpMeasuredCurrentA ); return current; } /*********************************************************************//** * @brief * The getDrainPumpMeasuredDirection function returns the drain pump current * direction. * @details Inputs: drainPumpMeasuredDir * @details Outputs: none * @return drain pump current direction *************************************************************************/ static U32 getDrainPumpMeasuredDirection( void ) { U32 direction = getU32OverrideValue( &drainPumpMeasuredDir ); return direction; } /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ /*********************************************************************//** * @brief * The testSetDrainPumpDataPublishIntervalOverride function overrides the * drain pump data publish interval. * @details Inputs: drainPumpDataPublishInterval * @details Outputs: drainPumpDataPublishInterval * @param value override drain pump data publish interval with (in ms) * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDrainPumpDataPublishIntervalOverride( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { U32 intvl = value / TASK_PRIORITY_INTERVAL; drainPumpDataPublishInterval.ovData = intvl; drainPumpDataPublishInterval.override = OVERRIDE_KEY; result = TRUE; } return result; } /*********************************************************************//** * @brief * The testResetDrainPumpDataPublishIntervalOverride function resets the * override of the drain pump data publish interval. * @details Inputs: drainPumpDataPublishInterval * @details Outputs: drainPumpDataPublishInterval * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetDrainPumpDataPublishIntervalOverride( void ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { drainPumpDataPublishInterval.override = OVERRIDE_RESET; drainPumpDataPublishInterval.ovData = drainPumpDataPublishInterval.ovInitData; result = TRUE; } return result; } /*********************************************************************//** * @brief * The testSetTargetDrainPumpRPMOverride function overrides the target * drain pump RPM. * @details Inputs: none * @details Outputs: none * @param value override target drain pump RPM * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetTargetDrainPumpRPM( U32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { if ( ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) { result = setDrainPumpTargetRPM( value ); } if ( 0 == value ) { result = TRUE; signalDrainPumpHardStop(); } } return result; } /*********************************************************************//** * @brief * The testSetTargetDrainPumpOutletFlowLPM function overrides * the target drain pump outlet flow in L/min/ * @details Inputs: none * @details Outputs: none * @param value of flow in L/min * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetTargetDrainPumpOutletFlowLPM( F32 value ) { BOOL result = FALSE; if ( TRUE == isTestingActivated() ) { // Check if delta pressure is in range if ( ( value >= MIN_RO_FLOWRATE_LPM ) && ( value <= MAX_RO_FLOWRATE_LPM ) ) { result = setDrainPumpTargetOutletFlowLPM( value ); } } return result; } /*********************************************************************//** * @brief * The testSetDrainPumpMeasuredRPMOverride function overrides the drain pump * measured RPM data. * @details Inputs: none * @details Outputs: drainPumpHallMeasuredRPM, drainPumpMaxonMeasuredRPM * @param sensor the type of sensor to pick (hall sensor or Maxon board) * @param value override drain pump measured data * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDrainPumpMeasuredRPMOverride( U32 sensor, U32 value ) { BOOL status = FALSE; // Check if the user is logged in if ( ( TRUE == isTestingActivated() ) && ( (DRAIN_PUMP_SPEED_FB_SNSR_T)sensor < NUM_OF_DRAIN_PUMP_SNSR_FB ) ) { if ( DRAIN_PUMP_HALL_SNSR_FB == (DRAIN_PUMP_SPEED_FB_SNSR_T)sensor ) { drainPumpHallMeasuredRPM.ovData = value; drainPumpHallMeasuredRPM.override = OVERRIDE_KEY; drainPumpHallMeasuredRPM.ovInitData = drainPumpHallMeasuredRPM.data; } else { drainPumpMaxonMeasuredRPM.ovData = value; drainPumpMaxonMeasuredRPM.override = OVERRIDE_KEY; drainPumpMaxonMeasuredRPM.ovInitData = drainPumpMaxonMeasuredRPM.data; } status = TRUE; } return status; } /*********************************************************************//** * @brief * The testResetDrainPumpMeasuredRPMOverride function resets the drain pump * measured RPM data. * @details Inputs: none * @details Outputs: drainPumpMeasuredRPM * @param sensor the type of sensor to pick (hall sensor or Maxon board) * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetDrainPumpMeasuredRPMOverride( U32 sensor ) { BOOL status = FALSE; // Check if the user is logged in if ( ( TRUE == isTestingActivated() ) && ( (DRAIN_PUMP_SPEED_FB_SNSR_T)sensor < NUM_OF_DRAIN_PUMP_SNSR_FB ) ) { if ( DRAIN_PUMP_HALL_SNSR_FB == (DRAIN_PUMP_SPEED_FB_SNSR_T)sensor ) { drainPumpHallMeasuredRPM.ovData = drainPumpHallMeasuredRPM.ovInitData; drainPumpHallMeasuredRPM.override = OVERRIDE_RESET; } else { drainPumpMaxonMeasuredRPM.ovData = drainPumpMaxonMeasuredRPM.ovInitData; drainPumpMaxonMeasuredRPM.override = OVERRIDE_RESET; } status = TRUE; } return status; } /*********************************************************************//** * @brief * The testSetDrainPumpMeasuredCurrentOverride function overrides the drain pump * measured current data. * @details Inputs: none * @details Outputs: drainPumpMeasuredCurrentA * @param value override drain pump measured current data * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDrainPumpMeasuredCurrentOverride( F32 value ) { BOOL status = FALSE; // Check if the user is logged in if ( TRUE == isTestingActivated() ) { drainPumpMeasuredCurrentA.ovData = value; drainPumpMeasuredCurrentA.override = OVERRIDE_KEY; drainPumpMeasuredCurrentA.ovInitData = drainPumpMeasuredCurrentA.data; status = TRUE; } return status; } /*********************************************************************//** * @brief * The testResetDrainPumpMeasuredCurrentOverride function resets the drain pump * measured current data. * @details Inputs: none * @details Outputs: drainPumpMeasuredCurrentA * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetDrainPumpMeasuredCurrentOverride( void ) { BOOL status = FALSE; // Check if the user is logged in if ( TRUE == isTestingActivated() ) { drainPumpMeasuredCurrentA.ovData = drainPumpMeasuredCurrentA.ovInitData; drainPumpMeasuredCurrentA.override = OVERRIDE_RESET; status = TRUE; } return status; } /*********************************************************************//** * @brief * The testSetDrainPumpMeasuredDirectionOverride function overrides the drain pump * measured direction data. * @details Inputs: none * @details Outputs: drainPumpMeasuredDir * @param value override drain pump measured direction data * @return TRUE if override successful, FALSE if not *************************************************************************/ BOOL testSetDrainPumpMeasuredDirectionOverride( U32 value ) { BOOL status = FALSE; // Check if the user is logged in if ( TRUE == isTestingActivated() ) { drainPumpMeasuredDir.ovData = value; drainPumpMeasuredDir.override = OVERRIDE_KEY; drainPumpMeasuredDir.ovInitData = drainPumpMeasuredDir.data; status = TRUE; } return status; } /*********************************************************************//** * @brief * The testResetDrainPumpMeasuredDirectionOverride function resets the drain pump * measured direction data. * @details Inputs: none * @details Outputs: drainPumpMeasuredDir * @return TRUE if override reset successful, FALSE if not *************************************************************************/ BOOL testResetDrainPumpMeasuredDirectionOverride( void ) { BOOL status = FALSE; // Check if the user is logged in if ( TRUE == isTestingActivated() ) { drainPumpMeasuredDir.ovData = drainPumpMeasuredDir.ovInitData; drainPumpMeasuredDir.override = OVERRIDE_RESET; status = TRUE; } return status; } /**@}*/