Index: firmware/App/Controllers/DrainPump.c =================================================================== diff -u -r1aeab08c1baf6445514b81fe51fc60a3e536e782 -ra3ee6d44d7eb0a1f96772c634ac243d4899419d3 --- firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision 1aeab08c1baf6445514b81fe51fc60a3e536e782) +++ firmware/App/Controllers/DrainPump.c (.../DrainPump.c) (revision a3ee6d44d7eb0a1f96772c634ac243d4899419d3) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2019-2021 Diality Inc. - All Rights Reserved. +* Copyright (c) 2019-2022 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) Sean Nash -* @date (last) 12-Nov-2021 +* @author (last) Dara Navaei +* @date (last) 22-Nov-2021 * * @author (original) Sean * @date (original) 08-Apr-2020 @@ -67,7 +67,7 @@ #define MAX_ALLOWED_TARGET_OUTLET_PRESSURE 15.0 ///< Maximum allowed outlet pressure for closed loop 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 ( 5 * MS_PER_SECOND ) ///< Open loop RPM out of range time out in ms. +#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. @@ -76,6 +76,7 @@ #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. +#define DATA_PUBLISH_COUNTER_START_COUNT 60 ///< Data publish counter start count. /// Enumeration of drain pump states. typedef enum DrainPump_States @@ -98,7 +99,7 @@ // ********** private data ********** static DRAIN_PUMP_STATE_T drainPumpState = DRAIN_PUMP_OFF_STATE; ///< Current state of drain pump controller state machine. -static U32 drainPumpDataPublicationTimerCounter = 0; ///< Used to schedule drain pump data publication to CAN bus. +static U32 drainPumpDataPublicationTimerCounter; ///< Used to schedule drain pump data publication to CAN bus. static U32 drainPumpDAC = 0; ///< Initial drain pump DAC value. static U32 drainPumpDACSet = 0; ///< Currently set drain pump DAC value. static PUMP_CONTROL_MODE_T drainPumpControlMode = NUM_OF_PUMP_CONTROL_MODES; ///< Requested drain pump control mode. @@ -118,7 +119,8 @@ 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. +static DG_DRAIN_LINE_VOLUME_T drainLineVolumeRecord; ///< Drain line volume record. +static DG_DRAIN_PUMP_CAL_RECORD_T drainPumpCalRecord; ///< Drain pump calibration record. /// 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 ); @@ -130,23 +132,21 @@ static DRAIN_PUMP_STATE_T handleDrainPumpOpenLoopState( void ); static void stopDrainPump( void ); static void publishDrainPumpData( void ); -static BOOL processCalibrationData( void ); /*********************************************************************//** * @brief * The initDrainPump function initializes the DrainPump module. * @details Inputs: none - * @details Outputs: hasClosedLoopBeenRequested, targetFlushLineVolume_L, - * signalNewRPMRequest + * @details Outputs: hasClosedLoopBeenRequested, signalNewRPMRequest * @return none *************************************************************************/ void initDrainPump( void ) { stopDrainPump(); - hasClosedLoopBeenRequested = FALSE; - targetFlushLineVolume_L = 0.0; - signalNewRPMRequest = FALSE; + hasClosedLoopBeenRequested = FALSE; + signalNewRPMRequest = FALSE; + drainPumpDataPublicationTimerCounter = DATA_PUBLISH_COUNTER_START_COUNT; // Initialize the drain pump PI controller initializePIController( PI_CONTROLLER_ID_DRAIN_PUMP, DRAIN_PUMP_MIN_DAC, DRAIN_PUMP_P_COEFFICIENT, DRAIN_PUMP_I_COEFFICIENT, @@ -175,11 +175,14 @@ 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; + 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 @@ -207,8 +210,8 @@ if ( ( 0 == rpm ) || ( ( rpm >= MIN_DRAIN_PUMP_RPM ) && ( rpm <= MAX_DRAIN_PUMP_RPM ) ) ) { - pendingDrainPumpCmd = DRAIN_PUMP_OPEN_LOOP_STATE; - pendingDrainPumpCmdTarget = (F32)rpm; + pendingDrainPumpCmd = DRAIN_PUMP_OPEN_LOOP_STATE; + pendingDrainPumpCmdTarget = (F32)rpm; pendingDrainPumpCmdCountDown = delayMs / TASK_GENERAL_INTERVAL; result = TRUE; } @@ -299,14 +302,14 @@ 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; - drainControlTimerCounter = 0; - pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; - pendingDrainPumpCmdTarget = 0.0; + targetDrainPumpRPM = 0; + drainPumpState = DRAIN_PUMP_OFF_STATE; + hasClosedLoopBeenRequested = FALSE; + drainPumpControlMode = PUMP_CONTROL_MODE_CLOSED_LOOP; + drainPumpControlModeSet = drainPumpControlMode; + drainControlTimerCounter = 0; + pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; + pendingDrainPumpCmdTarget = 0.0; pendingDrainPumpCmdCountDown = 0; } @@ -334,20 +337,7 @@ } #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 ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) - { - // 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 - BOOL isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); - - 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 ) { @@ -356,11 +346,24 @@ 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 ) ) + if ( TRUE == isAlarmActive( ALARM_ID_DRAIN_PUMP_OFF_FAULT ) ) { activateSafetyShutdown(); } } + // 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. + else if ( PUMP_CONTROL_MODE_OPEN_LOOP == drainPumpControlModeSet ) + { + // 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 + BOOL isRPMOutOfRange = ( rpmDiff > MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ? TRUE : FALSE ); + + checkPersistentAlarm( ALARM_ID_DRAIN_PUMP_RPM_OUT_OF_RANGE, isRPMOutOfRange, getDrainPumpMeasuredRPM(), MAX_ALLOWED_OPEN_LOOP_RPM_OUT_OF_RANGE ); + } #endif // Publish drain pump data on interval @@ -376,6 +379,14 @@ *************************************************************************/ 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 ) { @@ -396,9 +407,10 @@ targetDrainPumpRPM = (U32)pendingDrainPumpCmdTarget; drainPumpControlMode = PUMP_CONTROL_MODE_OPEN_LOOP; drainPumpControlModeSet = drainPumpControlMode; + signalNewRPMRequest = TRUE; } pendingDrainPumpCmdTarget = 0.0; - pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; + pendingDrainPumpCmd = DRAIN_PUMP_OFF_STATE; } } @@ -435,9 +447,15 @@ SELF_TEST_STATUS_T execDrainPumpSelfTest( void ) { SELF_TEST_STATUS_T result = SELF_TEST_STATUS_IN_PROGRESS; + BOOL calStatus = FALSE; - BOOL calStatus = processCalibrationData(); + // 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; @@ -510,14 +528,15 @@ /*********************************************************************//** * @brief - * The getFlushLineVolume function returns the target flush line volume. - * @details Inputs: targetFlushLineVolume_L + * 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 getFlushLineVolume( void ) +F32 getFlushLineVolumeL( void ) { - return targetFlushLineVolume_L; + return drainLineVolumeRecord.volume; } /*********************************************************************//** @@ -539,8 +558,6 @@ // 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 ); @@ -609,9 +626,9 @@ if ( TRUE == signalNewRPMRequest ) { // Set drain pump DAC - drainPumpDACSet = drainPumpDAC; - setFPGADrainPumpSpeed( drainPumpDACSet ); + drainPumpDACSet = drainPumpDAC; signalNewRPMRequest = FALSE; + setFPGADrainPumpSpeed( drainPumpDACSet ); } return state; @@ -661,39 +678,7 @@ } } -/*********************************************************************//** - * @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 *************************************************************************/