Index: firmware/App/Modes/ModeGenIdle.c =================================================================== diff -u -re6e05130918b0aa7cd742d88e3b2cd850316cde7 -r7d0fd5ed6b9db0479af90477e5108f6d3fa8df17 --- firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision e6e05130918b0aa7cd742d88e3b2cd850316cde7) +++ firmware/App/Modes/ModeGenIdle.c (.../ModeGenIdle.c) (revision 7d0fd5ed6b9db0479af90477e5108f6d3fa8df17) @@ -1,15 +1,15 @@ /************************************************************************** * -* Copyright (c) 2021-2023 Diality Inc. - All Rights Reserved. +* Copyright (c) 2021-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 ModeGenIdle.c * -* @author (last) Sean Nash -* @date (last) 30-Sep-2023 +* @author (last) Dara Navaei +* @date (last) 09-Apr-2024 * * @author (original) Quang Nguyen * @date (original) 06-Aug-2021 @@ -47,6 +47,7 @@ #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define TARGET_RO_FLOW_RATE_L 0.8F ///< Target flow rate for RO pump. +#define MAX_IDLE_RSVR_WEIGHT_GAIN_ML 200.0F ///< Maximum fluid gain of inactive reservoir in Gen Idle mode (mL) #define HD_LOST_COMM_TIMEOUT_MS (5 * SEC_PER_MIN * MS_PER_SECOND ) ///< The time of HD lost comm before DG transition back to standby. #define BAD_FILL_SUBSTATES_PUB_INTERVAL ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ///< Interval (ms/task time) at which the bad fill sub-states is published on the CAN bus. #define DATA_PUBLISH_COUNTER_START_COUNT 61 ///< Data publish counter start count. @@ -66,6 +67,8 @@ static OVERRIDE_U32_T genIdleDataPublicationInterval = { BAD_FILL_SUBSTATES_PUB_INTERVAL, BAD_FILL_SUBSTATES_PUB_INTERVAL, 0, 0 }; ///< Interval (in ms) at which to publish bad fill sub-states to CAN bus. +static F32 initialReservoirWeight; ///< Initial weight of inactive reservoir in Gen Idle mode. +static DG_RESERVOIR_ID_T inactiveReservoir; ///< Inactive reservoir // ********** private function prototypes ********** @@ -79,7 +82,8 @@ static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleSecondDrainState( void ); static DG_GEN_IDLE_MODE_BAD_FILL_STATE_T handleRefillState( DG_GEN_IDLE_MODE_STATE_T* idleState ); -static void publishGenIdleSubstates(); +static void checkInvalidReservoirFill( void ); +static void publishGenIdleSubstates( void ); /*********************************************************************//** * @brief @@ -103,6 +107,9 @@ *************************************************************************/ U32 transitionToGenIdleMode( void ) { + BOOL cp1parkStatus = ( getConcPumpIsParked( CONCENTRATEPUMPS_CP1_ACID ) != TRUE ? PARK_CONC_PUMPS : NO_PARK_CONC_PUMPS ); + BOOL cp2parkStatus = ( getConcPumpIsParked( CONCENTRATEPUMPS_CP2_BICARB ) != TRUE ? PARK_CONC_PUMPS : NO_PARK_CONC_PUMPS ); + // Re-initialize each time we transition to generation idle mode initGenIdleMode(); setCurrentSubState( NO_SUB_STATE ); @@ -120,8 +127,8 @@ setCondcutivitySensorCalTable( CONDUCTIVITYSENSORS_CD2_SENSOR, CAL_DATA_CD2_COND_SENSOR ); signalDrainPumpHardStop(); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, NO_PARK_CONC_PUMPS ); - requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, NO_PARK_CONC_PUMPS ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID, cp1parkStatus ); + requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB, cp2parkStatus ); // UV reactors on turnOnUVReactor( INLET_UV_REACTOR ); @@ -140,6 +147,9 @@ setCPLDCleanLEDColor( CPLD_CLEAN_LED_OFF ); + inactiveReservoir = getInactiveReservoir(); + initialReservoirWeight = getReservoirWeight( inactiveReservoir ); + return genIdleState; } @@ -247,6 +257,7 @@ break; } + checkInvalidReservoirFill(); publishGenIdleSubstates(); return (U32)genIdleState; @@ -467,6 +478,33 @@ /*********************************************************************//** * @brief + * The checkInvalidReservoirFill function checks for reservoir filling in + * generation idle mode when it should be constant. + * @details Inputs: inactiveReservoir, initialReservoirWeight + * @details Outputs: inactiveReservoir, initialReservoirWeight + * @return the next state + *************************************************************************/ +static void checkInvalidReservoirFill( void ) +{ + DG_RESERVOIR_ID_T currentInactiveReservoir = getInactiveReservoir(); + F32 reservoirWeight = getReservoirWeight( currentInactiveReservoir ); + + if ( currentInactiveReservoir != inactiveReservoir ) + { + // Inactive Reservoir changed, update the start value + inactiveReservoir = currentInactiveReservoir; + initialReservoirWeight = getReservoirWeight( inactiveReservoir ); + } + + // Check for unwanted filling unless a transfer is in progress + if ( ( FALSE == isReservoirTransferInProgress() ) && ( reservoirWeight > ( initialReservoirWeight + MAX_IDLE_RSVR_WEIGHT_GAIN_ML ) ) ) + { + SET_ALARM_WITH_2_F32_DATA( ALARM_ID_DG_INACTIVE_RESERVOIR_WEIGHT_OUT_OF_RANGE, initialReservoirWeight, reservoirWeight ); + } +} + +/*********************************************************************//** + * @brief * The publishGenIdleSubstates function publishes gen idle * sub-states at the set interval. * @details Inputs: handleBadFillFlag, badFillState, targetFillVolumeML,