Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r8a916f65cd66ab85f6f220c4e9e9c8a1bc6b0616 -rdcd360fb4dc37db2dcbeb7fb14fb327fe68235f4 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 8a916f65cd66ab85f6f220c4e9e9c8a1bc6b0616) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision dcd360fb4dc37db2dcbeb7fb14fb327fe68235f4) @@ -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,7 @@ #include "DrainPump.h" #include "FPGA.h" +#include "MessageSupport.h" #include "NVDataMgmt.h" #include "OperationModes.h" #include "PersistentAlarm.h" @@ -111,7 +112,8 @@ 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. 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). @@ -134,19 +136,20 @@ * @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; + 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 @@ -160,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 *************************************************************************/ @@ -177,6 +179,7 @@ targetDrainPumpRPM = rpm; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; + signalNewRPMRequest = TRUE; result = TRUE; } else @@ -286,10 +289,9 @@ /*********************************************************************//** * @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 ) @@ -313,8 +315,8 @@ * 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 ) @@ -323,12 +325,12 @@ if ( DRAIN_PUMP_OFF_RPM_ADC_COUNT == fpgaADCSpeedCount ) { - currentDrainPumpRPM = 0; + drainPumpMeasuredRPM.data = 0; } else { // Convert speed ADC to RPM - currentDrainPumpRPM = CONVERSION_COEFF / getFPGADrainPumpSpeed(); + drainPumpMeasuredRPM.data = CONVERSION_COEFF / getFPGADrainPumpSpeed(); } #ifndef IGNORE_DRAIN_PUMP_MONITOR @@ -338,20 +340,20 @@ if ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) { // Using abs since the read RPM can be above or below the target - U32 rpmDiff = abs( getTargetDrainPumpRPM() - currentDrainPumpRPM ); + U32 rpmDiff = abs( getDrainPumpTargetRPM() - getDrainPumpMeasuredRPM() ); // 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, MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); + 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 ( 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 ) ) @@ -390,7 +392,7 @@ } else if ( DRAIN_PUMP_OPEN_LOOP_STATE == pendingDrainPumpCmd ) { - drainPumpDAC = (U32)( pendingDrainPumpCmdTarget * RPM_2_DAC_SLOPE - RPM_2_DAC_INTERCEPT + FLOAT_TO_INT_ROUNDUP_OFFSET ); + 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; @@ -450,26 +452,46 @@ /*********************************************************************//** * @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; } @@ -502,9 +524,8 @@ * @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 ) @@ -513,11 +534,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 ) && ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) ) + 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 ); @@ -553,13 +576,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 ); @@ -568,25 +591,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; @@ -624,12 +649,13 @@ 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; } @@ -735,10 +761,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; @@ -760,7 +791,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 ); } @@ -769,4 +800,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; +} + /**@}*/