Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -rfba89d67dd2bef913e85a13563e2aa49f0e2e2f5 -r94a190522ce398399c7b93c59f788d7666ec0060 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision fba89d67dd2bef913e85a13563e2aa49f0e2e2f5) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 94a190522ce398399c7b93c59f788d7666ec0060) @@ -1,17 +1,17 @@ /************************************************************************** * -* Copyright (c) 2019-2020 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2021 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 +* @file DrainPump.c * -* @author (last) Quang Nguyen -* @date (last) 14-Sep-2020 +* @author (last) Dara Navaei +* @date (last) 10-Nov-2021 * -* @author (original) Sean -* @date (original) 08-Apr-2020 +* @author (original) Sean +* @date (original) 08-Apr-2020 * ***************************************************************************/ @@ -22,6 +22,8 @@ #include "DrainPump.h" #include "FPGA.h" +#include "MessageSupport.h" +#include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" #include "PIControllers.h" @@ -43,27 +45,28 @@ // ********** private definitions ********** -#define DRAIN_PUMP_MIN_DAC ( ( (F32)MIN_DRAIN_PUMP_RPM * \ - 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 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 ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Drain pump is controlled. +#define DRP_CONTROL_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the Drain pump is controlled. TODO original one is 1 second -#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. #define DRAIN_PUMP_P_COEFFICIENT 0.5 ///< P term for drain pump delta pressure control. #define DRAIN_PUMP_I_COEFFICIENT 1.0 ///< I term for drain pump delta pressure control. -#define MIN_ALLOWED_TARGET_OUTLET_PRESSURE -10.0 ///< Minimum allowed outlet pressure for closed loop control. -#define MAX_ALLOWED_TARGET_OUTLET_PRESSURE 10.0 ///< Maximum allowed outlet pressure for closed loop control. +#define MIN_ALLOWED_TARGET_OUTLET_PRESSURE -15.0 ///< Minimum allowed outlet pressure for closed loop control. +#define MAX_ALLOWED_TARGET_OUTLET_PRESSURE 15.0 ///< Maximum allowed outlet pressure for closed loop control. -#define OPEN_LOOP_RPM_OUT_OF_RANGE 0.1 ///< Maximum allowed RPM out of range from target RPM in open loop percent. +#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 ( 5 * 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. @@ -72,6 +75,8 @@ #define SAFETY_SHUTDOWN_TIMEOUT MS_PER_SECOND ///< Drain pump safety shutdown activation timeout. +#define DRAIN_PUMP_OFF_RPM_ADC_COUNT 0xFFFF ///< ADC count value when pump is off. + /// Enumeration of drain pump states. typedef enum DrainPump_States { @@ -101,18 +106,19 @@ static OVERRIDE_U32_T drainPumpDataPublishInterval = { DRAIN_PUMP_DATA_PUB_INTERVAL, DRAIN_PUMP_DATA_PUB_INTERVAL, - 0, 0 }; ///< Interval (in ms) at which to publish RO flow data to CAN bus. + 0, 0 }; ///< Interval (in ms) at which to publish drain pump data to CAN bus. static U32 targetDrainPumpRPM = 0; ///< Target drain pump RPM. static F32 targetDrainPumpOutletPressure = 0.0; ///< Target outlet pressure for the drain pump. static U32 drainControlTimerCounter = 0; ///< Determines when to perform control on drain pump. static BOOL hasClosedLoopBeenRequested = FALSE; ///< Closed loop pump control flag. -static U32 currentDrainPumpRPM = 0; ///< Current drain pump RPM from feedback. +static OVERRIDE_U32_T drainPumpMeasuredRPM = { 0, 0, 0, 0 }; ///< Measured drain pump RPM from feedback. +static BOOL signalNewRPMRequest = FALSE; ///< Signal flag the indicates there is a new RPM request. -/* TODO These variables are used for POST. POST will be implemented later -static DRAIN_PUMP_SELF_TEST_STATE_T drainPumpSelfTestState = DRAIN_PUMP_SELF_TEST_STATE_START; ///< Current drain pump self test state. -static U32 drainPumpSelfTestTimerCount = 0; ///< Timer counter for drain pump self test. -*/ +static DRAIN_PUMP_STATE_T pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; ///< Delayed (pending) drain pump command. +static F32 pendingDrainPumpCmdTarget = 0.0; ///< Delayed (pending) drain pump command target (rpm or PSI depending on command). +static U32 pendingDrainPumpCmdCountDown = 0; ///< Delayed (pending) drain pump command count down timer (in task intervals). +static F32 targetFlushLineVolume_L = 0.0; ///< Target flush volume in liters. /// ADC to RPM conversion coefficient or RPM to ADC conversion. static const F32 CONVERSION_COEFF = SEC_PER_MIN / ( 2 * TOGGLE_PERIOD_RESOLUTION_SECONDS * ROTATIONAL_TO_TOGGLE_PERIOD_CONVERSION ); @@ -124,24 +130,26 @@ static DRAIN_PUMP_STATE_T handleDrainPumpOpenLoopState( void ); static void stopDrainPump( void ); static void publishDrainPumpData( void ); -static U32 getPublishDrainPumpDataInterval( void ); +static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief * The initDrainPump function initializes the DrainPump module. * @details Inputs: none - * @details Outputs: hasClosedLoopBeenRequested + * @details Outputs: hasClosedLoopBeenRequested, targetFlushLineVolume_L, + * signalNewRPMRequest * @return none *************************************************************************/ void initDrainPump( void ) { stopDrainPump(); hasClosedLoopBeenRequested = FALSE; + targetFlushLineVolume_L = 0.0; + signalNewRPMRequest = FALSE; // Initialize the drain pump PI controller - initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, - DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, + 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 alarm for open loop RPM out of range @@ -155,10 +163,9 @@ * @brief * The setDrainPumpTargetSpeed function sets a new target RPM for the * drain pump. - * @details Inputs: drainPumpDAC, targetDrainPumpSpeed, drainPumpControlMode, - * drainPumpControlModeSet - * @details Outputs: drainPumpDAC, targetDrainPumpSpeed, drainPumpControlMode, - * drainPumpControlModeSet + * @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 *************************************************************************/ @@ -168,11 +175,11 @@ 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)GET_RPM_2_DAC_CONVERSION(rpm); targetDrainPumpRPM = rpm; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; + signalNewRPMRequest = TRUE; result = TRUE; } else @@ -185,8 +192,38 @@ /*********************************************************************//** * @brief - * The setDrainPumpTargetOutletPressure function sets the target drain pump - * outlet pressure. + * 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 setDrainPumpTargetOutletPressure function sets the drain pump to start + * with given target PDr pressure. * @details Inputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet * @details Outputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, @@ -219,11 +256,42 @@ /*********************************************************************//** * @brief + * The setDrainPumpTargetOutletPressureDelayed function sets the drain pump + * to start with given target PDr pressure after given delay. + * @details Inputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, + * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet + * @details Outputs: targetDrainPumpDeltaPressure, hasClosedLoopBeenRequested, + * drainPumpDAC, drainPumpControlMode, drainPumpControlModeSet + * @param pressure new target drain pump outlet pressure + * @param delayMS delay duration (in ms) before drain pump started + * @return TRUE if new target speed is set, FALSE if not + *************************************************************************/ +BOOL setDrainPumpTargetOutletPressureDelayed( F32 pressure, U32 delayMs ) +{ + BOOL result = FALSE; + + // Check the delta pressure is in range + if ( ( pressure >= MIN_ALLOWED_TARGET_OUTLET_PRESSURE ) && ( pressure <= MAX_ALLOWED_TARGET_OUTLET_PRESSURE ) ) + { + pendingDrainPumpCmd = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; + pendingDrainPumpCmdTarget = pressure; + pendingDrainPumpCmdCountDown = delayMs / TASK_GENERAL_INTERVAL; + result = TRUE; + } + else + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_DRAIN_PUMP_INVALID_DELTA_PRESSURE_SELECTED, pressure ) + } + + return result; +} + +/*********************************************************************//** + * @brief * The signalDrainPumpHardStop function stops the Drain pump immediately. - * @details Inputs: targetDrainPumpSpeed, drainPumpState, drainPumpControlMode, - * hasClosedLoopBeenRequested, drainControlTimerCounter - * @details Outputs: targetDrainPumpSpeed, drainPumpState, drainPumpControlMode, - * hasClosedLoopBeenRequested, drainControlTimerCounter + * @details Inputs: none + * @details Outputs: targetDrainPumpRPM, drainPumpState, drainPumpControlMode, + * hasClosedLoopBeenRequested, drainControlTimerCounter, drainPumpControlModeSet * @return none *************************************************************************/ void signalDrainPumpHardStop( void ) @@ -234,7 +302,8 @@ targetDrainPumpRPM = 0; drainPumpState = DRAIN_PUMP_OFF_STATE; hasClosedLoopBeenRequested = FALSE; - drainPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; // Set the control mode to none + drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + drainPumpControlModeSet = drainPumpControlMode; drainControlTimerCounter = 0; } @@ -243,46 +312,50 @@ * The execDrainPumpMonitor function executes the drain pump monitor. * RPM = ( 1 / ADC ) * conversion coefficient. * ADC = ( 1 / RPM ) * conversion coefficient. - * @details Inputs: currentDrainPumpRPM - * @details Outputs: currentDrainPumpRPM + * @details Inputs: drainPumpControlModeSet, drainPumpState + * @details Outputs: drainPumpMeasuredRPM * @return none *************************************************************************/ void execDrainPumpMonitor( void ) { - // Convert speed ADC to RPM - currentDrainPumpRPM = CONVERSION_COEFF / getFPGADrainPumpSpeed(); + U16 const fpgaADCSpeedCount = getFPGADrainPumpSpeed(); - /* TODO: The RPM is not converted properly. There will be a story to work on this issue. - * This part of code is commented out until the RPM is calculated from ADC correctly. - * There will be a story to address the RPM conversion. - */ + if ( DRAIN_PUMP_OFF_RPM_ADC_COUNT == fpgaADCSpeedCount ) + { + drainPumpMeasuredRPM.data = 0; + } + else + { + // Convert speed ADC to RPM + drainPumpMeasuredRPM.data = CONVERSION_COEFF / getFPGADrainPumpSpeed(); + } + #ifndef IGNORE_DRAIN_PUMP_MONITOR // The RPM is only checked in open loop state that the pump is run at a fixed RPM. // The persistent alarm waits for a couple of seconds before raising an alarm, this is supposed to cover // when the pump is turned on and it takes a while to ramp up to target RPM. - if( drainPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) + if ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) { - U32 targetRPM = getTargetDrainPumpRPM(); - F32 threshold = OPEN_LOOP_RPM_OUT_OF_RANGE * targetRPM; + // Using abs since the read RPM can be above or below the target + U32 rpmDiff = abs( getDrainPumpTargetRPM() - getDrainPumpMeasuredRPM() ); - // Check if RPM is out of range. Using fabs since the read RPM can be above or below the target. - BOOL isRPMOutOfRange = fabs( targetRPM - currentDrainPumpRPM ) > threshold; + // Check if RPM is out of range + BOOL isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, currentDrainPumpRPM, threshold ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); } // Check if the pump is in off state and the RPM is greater than the minimum RPM - if ( drainPumpState == DRAIN_PUMP_OFF_STATE ) + if ( DRAIN_PUMP_OFF_STATE == drainPumpState ) { - BOOL isRPMTooHigh = currentDrainPumpRPM > MIN_DRAIN_PUMP_RPM; + BOOL isRPMTooHigh = ( getDrainPumpMeasuredRPM() > MIN_DRAIN_PUMP_RPM ? TRUE : FALSE ); - checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, currentDrainPumpRPM, MIN_DRAIN_PUMP_RPM ); + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_OFF_FAULT, isRPMTooHigh, getDrainPumpMeasuredRPM(), MIN_DRAIN_PUMP_RPM ); // If the off fault alarm has become active, trigger the safety shutdown if ( isAlarmActive( ALARM_ID_DRAIN_PUMP_OFF_FAULT ) ) { activateSafetyShutdown(); - BOOL test = FALSE; } } #endif @@ -300,6 +373,33 @@ *************************************************************************/ void execDrainPumpController( void ) { + // Handle pending drain pump command + if ( pendingDrainPumpCmdCountDown > 0 ) + { + pendingDrainPumpCmdCountDown--; + if ( 0 == pendingDrainPumpCmdCountDown ) + { + if ( DRAIN_PUMP_CONTROL_TO_TARGET_STATE == pendingDrainPumpCmd ) + { + targetDrainPumpOutletPressure = 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; + } + pendingDrainPumpCmdTarget = 0.0; + pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; + } + } + + // Execute drain pump state machine switch ( drainPumpState ) { case DRAIN_PUMP_OFF_STATE: @@ -324,54 +424,105 @@ /*********************************************************************//** * @brief - * The execDrainPumpSelfTest function executes the state machine for the drain - * pump self-test. - * @details Inputs: TODO FILL UP - * @details Outputs: TODO FILL UP - * @return the current state of the Drain Pump self test. + * 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_FAILED; + SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; - // TODO - implement self-test(s) + BOOL calStatus = processCalibrationData(); + if ( TRUE == calStatus ) + { + result = SELF_TEST_STATUS_PASSED; + } + else + { + result = SELF_TEST_STATUS_FAILED; + } + return result; } /*********************************************************************//** * @brief - * The getTargetDrainPumpRPM function gets the current target drain pump + * The getDrainPumpTargetRPM function gets the current target drain pump * RPM. * @details Inputs: targetDrainPumpRPM * @details Outputs: none * @return the current target drain pump RPM. *************************************************************************/ -U32 getTargetDrainPumpRPM( void ) +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 + * @return drain pump RPM + *************************************************************************/ +U32 getDrainPumpMeasuredRPM( void ) +{ + U32 rpm = drainPumpMeasuredRPM.data; + + if ( OVERRIDE_KEY == drainPumpMeasuredRPM.override ) + { + rpm = drainPumpMeasuredRPM.ovData; + } + + return rpm; +} + +/*********************************************************************//** + * @brief * The getTargetDrainPumpOutletPressure function gets the current target * drain pump delta pressure. * @details Inputs: targetDrainPumpOutletPressure * @details Outputs: none * @return the current target drain pump outlet pressure. *************************************************************************/ -F32 getTargetDrainPumpOutletPressure( void ) +F32 getDrainPumpTargetOutletPressure( void ) { return targetDrainPumpOutletPressure; } /*********************************************************************//** * @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 getFlushLineVolume function returns the target flush line volume. + * @details Inputs: targetFlushLineVolume_L + * @details Outputs: none + * @return the target flush line volume in Liter + *************************************************************************/ +F32 getFlushLineVolume( void ) +{ + return targetFlushLineVolume_L; +} + +/*********************************************************************//** + * @brief * The handleDrainPumpOffState function handles the drain pump off state of * the drain pump controller state machine. - * @details Inputs: drainPumpControlModeSet, drainPumpDACSet, drainPumpDAC - * hasClosedLoopBeenRequested - * @details Outputs: drainPumpDACSet + * @details Inputs: drainPumpControlModeSet, hasClosedLoopBeenRequested * + * @details Outputs: drainPumpDACSet, signalNewRPMRequest * @return next state for the controller state machine *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpOffState( void ) @@ -380,11 +531,13 @@ // If the target drain pump speed was not 0 and the control mode // is open loop, set the drain pump to open loop - if ( getTargetDrainPumpRPM() > 0 && drainPumpControlModeSet == PUMP_CONTROL_MODE_OPEN_LOOP ) + if ( ( getDrainPumpTargetRPM() > 0 ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) ) { // Set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); + // Turn off the new RPM signal + signalNewRPMRequest = FALSE; // Set drain pump DAC drainPumpDACSet = drainPumpDAC; setFPGADrainPumpSpeed( drainPumpDACSet ); @@ -393,7 +546,7 @@ } // 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 ( drainPumpControlModeSet == PUMP_CONTROL_MODE_CLOSED_LOOP && hasClosedLoopBeenRequested ) + else if ( ( PUMP_CONTROL_MODE_CLOSED_LOOP == drainPumpControlModeSet ) && ( TRUE == hasClosedLoopBeenRequested ) ) { // set drain pump enable pin SET_DRAIN_PUMP_ENABLE(); @@ -420,13 +573,13 @@ *************************************************************************/ static DRAIN_PUMP_STATE_T handleDrainPumpControlToTargetState( void ) { - DRAIN_PUMP_STATE_T result = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; + DRAIN_PUMP_STATE_T state = DRAIN_PUMP_CONTROL_TO_TARGET_STATE; // control at set interval if ( ++drainControlTimerCounter >= DRP_CONTROL_INTERVAL ) { F32 outletDrainPressure = getMeasuredDGPressure( PRESSURE_SENSOR_DRAIN_PUMP_OUTLET ); - F32 dac = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP, getTargetDrainPumpOutletPressure(), outletDrainPressure ); + F32 dac = runPIController( PI_CONTROLLER_ID_DRAIN_PUMP, getDrainPumpTargetOutletPressure(), outletDrainPressure ); // The PI controller sends the DAC out and it is rounded to the nearest offset and is fed to the FPGA drainPumpDACSet = (U32)( dac + FLOAT_TO_INT_ROUNDUP_OFFSET ); @@ -435,25 +588,27 @@ drainControlTimerCounter = 0; } - return result; + return state; } /*********************************************************************//** * @brief * The handleDrainPumpOpenLoopState function handles the open loop state. - * @details Inputs: none - * @details Outputs: none + * @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; - // Check if the RPM is 0, and if it is turn off the pump - if ( 0 == getTargetDrainPumpRPM() ) + // If there is a signal for a new RPM, change to the new RPM + if ( TRUE == signalNewRPMRequest ) { - state = DRAIN_PUMP_OFF_STATE; - signalDrainPumpHardStop(); + // Set drain pump DAC + drainPumpDACSet = drainPumpDAC; + setFPGADrainPumpSpeed( drainPumpDACSet ); + signalNewRPMRequest = FALSE; } return state; @@ -477,26 +632,6 @@ /*********************************************************************//** * @brief - * The getPublishDrainPumpDataInterval function gets the drain pump data - * publication interval. - * @details Inputs: drainPumpDataPublishInterval - * @details Outputs: drainPumpDataPublishInterval - * @return the current Drain pump data publication interval (in ms). - *************************************************************************/ -static U32 getPublishDrainPumpDataInterval( void ) -{ - U32 result = drainPumpDataPublishInterval.data; - - if ( OVERRIDE_KEY == drainPumpDataPublishInterval.override ) - { - result = drainPumpDataPublishInterval.ovData; - } - - return result; -} - -/*********************************************************************//** - * @brief * The publishDrainPumpData function publishes drain pump data at the set * interval. * @details Inputs: drainPumpDataPublicationTimerCounter @@ -506,22 +641,56 @@ static void publishDrainPumpData( void ) { // publish Drain pump data on interval - if ( ++drainPumpDataPublicationTimerCounter >= getPublishDrainPumpDataInterval() ) + if ( ++drainPumpDataPublicationTimerCounter >= getU32OverrideValue( &drainPumpDataPublishInterval ) ) { DRAIN_PUMP_DATA_T drainPumpData; // Populate the data structure for publication - drainPumpData.rpmSetPoint = getTargetDrainPumpRPM(); + drainPumpData.rpmSetPoint = getDrainPumpTargetRPM(); drainPumpData.pumpDACSet = drainPumpDACSet; drainPumpData.drainPumpState = (U32)drainPumpState; - drainPumpData.drainPumpRPM = currentDrainPumpRPM; + drainPumpData.drainPumpRPM = getDrainPumpMeasuredRPM(); + drainPumpData.trgtOutletPrsr = targetDrainPumpOutletPressure; - broadcastDrainPumpData( &drainPumpData ); + broadcastData( MSG_ID_DRAIN_PUMP_DATA, COMM_BUFFER_OUT_CAN_DG_BROADCAST, (U08*)&drainPumpData, sizeof( DRAIN_PUMP_DATA_T ) ); drainPumpDataPublicationTimerCounter = 0; } } +/*********************************************************************//** + * @brief + * The processCalibrationData function gets the calibration data and makes + * sure it is valid by checking the calibration date. The calibration date + * should not be 0. + * @details Inputs: none + * @details Outputs: modeRecircTargetFlushVolL + * @return TRUE if the calibration record is valid, otherwise FALSE + *************************************************************************/ +static BOOL processCalibrationData( void ) +{ + BOOL status = TRUE; + + // Get the calibration record from NVDataMgmt + DG_DRAIN_LINE_VOLUME_T calData = getDGDrainLineVolumeRecord(); + + // Check if the calibration data that was received from NVDataMgmt is legitimate + // The calibration date item should not be zero. If the calibration date is 0, + // then the data is not stored in the NV memory or it was corrupted. + if ( 0 == calData.calibrationTime ) + { +#ifndef SKIP_CAL_CHECK + activateAlarmNoData( ALARM_ID_DG_DRAIN_LINE_VOLUME_INVALID_CAL_RECORD ); + status = FALSE; +#endif + } + + // The calibration data was valid, update the local copy + targetFlushLineVolume_L = calData.volume; + + return status; +} + /************************************************************************* * TEST SUPPORT FUNCTIONS *************************************************************************/ @@ -589,10 +758,15 @@ if ( TRUE == isTestingActivated() ) { - if ( ( 0 == value ) || ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) + if ( ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) { result = setDrainPumpTargetRPM( value ); } + + if ( 0 == value ) + { + signalDrainPumpHardStop(); + } } return result; @@ -614,7 +788,7 @@ if ( TRUE == isTestingActivated() ) { // Check if delta pressure is in range - if ( value >= MIN_ALLOWED_TARGET_OUTLET_PRESSURE && value <= MAX_ALLOWED_TARGET_OUTLET_PRESSURE ) + if ( ( value >= MIN_ALLOWED_TARGET_OUTLET_PRESSURE ) && ( value <= MAX_ALLOWED_TARGET_OUTLET_PRESSURE ) ) { result = setDrainPumpTargetOutletPressure( value ); } @@ -623,4 +797,56 @@ return result; } +/*********************************************************************//** + * @brief + * The testSetDrainPumpMeasuredRPMOverride function overrides the drain pump + * measured RPM data. + * @details Inputs: none + * @details Outputs: drainPumpMeasuredRPM + * @param value override drain pump measured data + * @return TRUE if override successful, FALSE if not + *************************************************************************/ +BOOL testSetDrainPumpMeasuredRPMOverride( U32 value ) +{ + BOOL status = FALSE; + + // Check if the requested drain pump RPM is within range + if ( ( value >= MIN_DRAIN_PUMP_RPM ) && ( value <= MAX_DRAIN_PUMP_RPM ) ) + { + // Check if the user is logged in + if ( TRUE == isTestingActivated() ) + { + drainPumpMeasuredRPM.ovData = value; + drainPumpMeasuredRPM.override = OVERRIDE_KEY; + drainPumpMeasuredRPM.ovInitData = drainPumpMeasuredRPM.data; + status = TRUE; + } + } + + return status; +} + +/*********************************************************************//** + * @brief + * The testResetDrainPumpMeasuredRPMOverride function resets the drain pump + * measured RPM data. + * @details Inputs: none + * @details Outputs: drainPumpMeasuredRPM + * @return TRUE if override reset successful, FALSE if not + *************************************************************************/ +BOOL testResetDrainPumpMeasuredRPMOverride( void ) +{ + BOOL status = FALSE; + + // Check if the user is logged in + if ( TRUE == isTestingActivated() ) + { + drainPumpMeasuredRPM.ovData = drainPumpMeasuredRPM.ovInitData; + drainPumpMeasuredRPM.override = OVERRIDE_RESET; + status = TRUE; + } + + return status; +} + /**@}*/