/************************************************************************** * * Copyright (c) 2019-2020 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 ModeRecirculate.c * * @author (last) Quang Nguyen * @date (last) 24-Aug-2020 * * @author (original) Sean * @date (original) 04-Apr-2020 * ***************************************************************************/ #include "ConcentratePumps.h" #include "ConductivitySensors.h" #include "DrainPump.h" #include "FPGA.h" #include "Heaters.h" #include "ModeGenIdle.h" #include "NVDataMgmt.h" #include "OperationModes.h" #include "Pressures.h" #include "ROPump.h" #include "SystemComm.h" #include "TaskGeneral.h" #include "TemperatureSensors.h" #include "Timers.h" #include "UVReactors.h" #include "Valves.h" /** * @addtogroup DGRecirculateMode * @{ */ // ********** private definitions ********** #define TARGET_RO_PRESSURE_PSI 130 ///< Target pressure for RO pump. #define TARGET_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. #define TARGET_FLUSH_LINES_RO_FLOW_RATE_L 0.3 ///< Target flow rate for RO pump. /// The time of HD lost comm before DG transition back to standby. #define HD_LOST_COMM_TIMEOUT_MS (5 * SEC_PER_MIN * MS_PER_SECOND ) // ********** private data ********** static DG_GEN_IDLE_MODE_STATE_T genIdleState; ///< Currently active generation idle state. static F32 flushLinesVolumeL = 0.0; ///< Volume of water pumped by RO pump during flush lines state. static U32 hdLostCommStartTime_ms = 0; ///< Lost communication with HD start time in ms. // ********** private function prototypes ********** static DG_GEN_IDLE_MODE_STATE_T handleFlushLinesState( void ); static DG_GEN_IDLE_MODE_STATE_T handleFlushWaterState( void ); /*********************************************************************//** * @brief * The initGenIdleMode function initializes the generation idle mode module. * @details Inputs: none * @details Outputs: Generation idle mode module initialized * @return none *************************************************************************/ void initGenIdleMode( void ) { genIdleState = DG_GEN_IDLE_MODE_STATE_START; flushLinesVolumeL = 0.0; hdLostCommStartTime_ms = 0; } /*********************************************************************//** * @brief * The transitionToGenIdleMode function prepares for transition to generation idle mode. * @details Inputs: none * @details Outputs: Re-initialized generation idle mode * @return initial state *************************************************************************/ U32 transitionToGenIdleMode( void ) { // Re-initialize each time we transition to generation idle mode initGenIdleMode(); // Set initial actuator states setValveState( VSP, VALVE_STATE_CLOSED ); setValveState( VPI, VALVE_STATE_OPEN ); setValveState( VPD, VALVE_STATE_OPEN_C_TO_NC ); setValveState( VRD1, VALVE_STATE_CLOSED ); setValveState( VRD2, VALVE_STATE_CLOSED ); setValveState( VRC, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VDR, VALVE_STATE_DRAIN_C_TO_NO ); setValveState( VPO, VALVE_STATE_NOFILL_C_TO_NO ); signalDrainPumpHardStop(); requestConcentratePumpOff( CONCENTRATEPUMPS_CP1_ACID ); requestConcentratePumpOff( CONCENTRATEPUMPS_CP2_BICARB ); // UV reactors on turnOnUVReactor( INLET_UV_REACTOR ); turnOnUVReactor( OUTLET_UV_REACTOR ); // NOTE: The target flow rate should be set prior to setting the start primary heater // because the initial guess in the heaters driver needs the target flow to calculate // the new PWMs for the main and small primary heaters #ifndef DISABLE_FLOW_CONTROL_TREATMENT setROPumpTargetFlowRate( TARGET_FLUSH_LINES_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); setHeaterTargetTemperature( DG_PRIMARY_HEATER, 39.0 ); // TODO remove this line. It comes form HD this for testing only startHeater( DG_PRIMARY_HEATER ); #endif return genIdleState; } /*********************************************************************//** * @brief * The execGenIdleMode function executes the generation idle mode state machine. * @details Inputs: genIdleState * @details Outputs: Check water quality, generation idle mode state machine executed * @return current state *************************************************************************/ U32 execGenIdleMode( void ) { // Check inlet water conductivity, temperature, pressure, and RO rejection ratio checkInletWaterConductivity(); checkInletWaterTemperature(); checkInletPressure(); checkRORejectionRatio(); // Transition to standby mode when HD is not communicating if ( TRUE == isHDCommunicating() ) { hdLostCommStartTime_ms = getMSTimerCount(); } else { if ( TRUE == didTimeout( hdLostCommStartTime_ms, HD_LOST_COMM_TIMEOUT_MS ) ) { requestNewOperationMode( DG_MODE_STAN ); } } // Execute current generation idle state switch ( genIdleState ) { case DG_GEN_IDLE_MODE_STATE_START: genIdleState = DG_GEN_IDLE_MODE_STATE_FLUSH_LINES; break; case DG_GEN_IDLE_MODE_STATE_FLUSH_LINES: genIdleState = handleFlushLinesState(); break; case DG_GEN_IDLE_MODE_STATE_FLUSH_WATER: genIdleState = handleFlushWaterState(); break; default: SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_GEN_IDLE_MODE_INVALID_EXEC_STATE, genIdleState ) genIdleState = DG_GEN_IDLE_MODE_STATE_START; break; } return (U32)genIdleState; } /*********************************************************************//** * @brief * The getCurrentGenIdleState function returns the current state of the * generation idle mode. * @details Inputs: genIdleState * @details Outputs: none * @return the current state of generation idle mode *************************************************************************/ DG_GEN_IDLE_MODE_STATE_T getCurrentGenIdleState( void ) { return genIdleState; } /*********************************************************************//** * @brief * The requestDGStop function handles an HD request to stop (return to standby mode). * @details Inputs: none * @details Outputs: DG standby mode requested * @return TRUE if request accepted, FALSE if not. *************************************************************************/ BOOL requestDGStop( void ) { BOOL result = TRUE; requestNewOperationMode( DG_MODE_STAN ); return result; } /*********************************************************************//** * @brief * The handleFlushLinesState function executes the flush lines state of the * generation idle mode state machine. * @details Inputs: flushLinesVolumeL * @details Outputs: Integrate volume of water moved through line * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleFlushLinesState( void ) { DG_GEN_IDLE_MODE_STATE_T result = DG_GEN_IDLE_MODE_STATE_FLUSH_LINES; F32 waterFlowRate = getMeasuredROFlowRate(); F32 waterVolume = ( ( waterFlowRate / SEC_PER_MIN ) / ( MS_PER_SECOND / TASK_GENERAL_INTERVAL ) ); // Integrate volume of water moved through line flushLinesVolumeL += waterVolume; // When enough water volume has flowed to flush the lines, transition to flush water state if ( flushLinesVolumeL >= getFlushLineVolume() ) { #ifndef DISABLE_FLOW_CONTROL_TREATMENT setROPumpTargetFlowRate( TARGET_RO_FLOW_RATE_L, TARGET_RO_PRESSURE_PSI ); #endif result = DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; } return result; } /*********************************************************************//** * @brief * The handleFlushWaterState function executes the flush water state * of the generation idle mode state machine. * @details Inputs: none * @details Outputs: none * @return the next state *************************************************************************/ static DG_GEN_IDLE_MODE_STATE_T handleFlushWaterState( void ) { return DG_GEN_IDLE_MODE_STATE_FLUSH_WATER; } /**@}*/