Index: firmware/App/Controllers/UVReactors.c =================================================================== diff -u -rd7be59e36db5e9899b02dd0bfadadc50fed934c0 -r6499ea25921fcf67826fa0c35bb03caf411ba542 --- firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision d7be59e36db5e9899b02dd0bfadadc50fed934c0) +++ firmware/App/Controllers/UVReactors.c (.../UVReactors.c) (revision 6499ea25921fcf67826fa0c35bb03caf411ba542) @@ -1,14 +1,14 @@ /************************************************************************** * -* Copyright (c) 2020-2022 Diality Inc. - All Rights Reserved. +* Copyright (c) 2020-2023 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 UVReactors.c * -* @author (last) Bill Bracken -* @date (last) 18-Aug-2022 +* @author (last) Dara Navaei +* @date (last) 12-Oct-2022 * * @author (original) Dara Navaei * @date (original) 24-Nov-2020 @@ -20,12 +20,14 @@ #include "AlarmMgmt.h" #include "Common.h" +#include "FlowSensors.h" #include "MessageSupport.h" #include "PersistentAlarm.h" #include "SystemCommMessages.h" #include "TaskGeneral.h" #include "Timers.h" #include "UVReactors.h" +#include "Valves.h" /** * @addtogroup UV Reactors @@ -43,7 +45,7 @@ #define SELF_TEST_DELAY_TIME 1000 ///< Self test wait time after enabling the reactors and before checking for their health in ms. #define MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD MS_PER_SECOND ///< UV reactors unhealthy state period. #define DATA_PUBLISH_COUNTER_START_COUNT 90 ///< Data publish counter start count. -#define UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ( 2 * MS_PER_SECOND ) ///< UV reactors on with no flow time out in milliseconds. +#define UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ( 10 * MS_PER_SECOND ) ///< UV reactors on with no flow time out in milliseconds. #define MIN_RO_UV_FLOWRATE_LPM 0.2F ///< Minimum target RO UV flow rate in L/min. /// UV reactors self test states @@ -72,8 +74,6 @@ U32 reactorEnablePin; ///< UV reactor enable pin of GIO port A. U32 reactorHealthStatusPin; ///< UV reactor status pin of N2HET1. OVERRIDE_U32_T healthStatus; ///< UV reactor current health status. - BOOL isFlowBelowMin; ///< UV reactor flag to indicate the flow is below minimum. - U32 reactorOnWithNoFlowTimer; ///< UV reactor on with no flow start time. } UV_REACTOR_STATUS_T; // ********** private data ********** @@ -138,6 +138,8 @@ } initPersistentAlarm( ALARM_ID_UV_REACTOR_NOT_HEALTHY, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ); + initPersistentAlarm( ALARM_ID_DG_INLET_UV_REACTOR_ON_WITH_NO_FLOW, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ); + initPersistentAlarm( ALARM_ID_DG_OUTLET_UV_REACTOR_ON_WITH_NO_FLOW, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ); } /*********************************************************************//** @@ -196,11 +198,12 @@ reactorsStatus[ reactor ].execState = handleUVReactorStateOn( reactor ); break; +#ifndef _VECTORCAST_ default: - SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_EXEC_STATE, - reactorsStatus[ reactor ].execState ); + SET_ALARM_WITH_2_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_EXEC_STATE, reactorsStatus[ reactor ].execState ); reactorsStatus[ reactor].execState = UV_REACTOR_STATE_OFF; break; +#endif } } @@ -252,7 +255,7 @@ if ( TURN_OFF == reactorsStatus[ reactor ].switchState ) { reactorsStatus[ reactor ].switchState = TURN_ON; - result = TRUE; + result = TRUE; } } else @@ -374,16 +377,8 @@ // Check if the a reactor is requested to be on and it is off if ( TURN_ON == reactorsStatus[ reactor ].switchState ) { - // Check if the flow is below minimum - reactorsStatus[ reactor ].isFlowBelowMin = ( getMeasuredROFlowRateLPM() < MIN_RO_UV_FLOWRATE_LPM ? TRUE : FALSE ); - - // If the flow is no longer below minimum and the reactor is requested to be on, turn it back on - if ( FALSE == reactorsStatus[ reactor ].isFlowBelowMin ) - { - setReactorEnableStatus( reactor, PIN_SIGNAL_HIGH ); - - state = UV_REACTOR_STATE_ON; - } + setReactorEnableStatus( reactor, PIN_SIGNAL_HIGH ); + state = UV_REACTOR_STATE_ON; } return state; @@ -400,50 +395,50 @@ static UV_REACTOR_STATE_T handleUVReactorStateOn( UV_REACTORS_T reactor ) { UV_REACTOR_STATE_T state = UV_REACTOR_STATE_ON; + BOOL isReactorUnhealthy = ( UV_REACTOR_HEALTHY == getUVReactorHealth( reactor ) ? FALSE : TRUE ); // Update the UV reactor's health. It should be either healthy (1) or not healthy (0) reactorsStatus[ reactor ].healthStatus.data = getReactorHealth( reactor ); - // Get the health of the reactor (override or non-override) and decide the status - BOOL isReactorUnhealthy = ( UV_REACTOR_HEALTHY == getUVReactorHealth( reactor ) ? FALSE : TRUE ); - #ifndef _RELEASE_ if ( getSoftwareConfigStatus( SW_CONFIG_DISABLE_UV_REACTORS ) != SW_CONFIG_ENABLE_VALUE ) #endif { - // Check if the alarm has been active - if ( TRUE == checkPersistentAlarm( ALARM_ID_UV_REACTOR_NOT_HEALTHY, isReactorUnhealthy, (U32)reactor, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ) ) + checkPersistentAlarm( ALARM_ID_UV_REACTOR_NOT_HEALTHY, isReactorUnhealthy, (U32)reactor, MAX_ALLOWED_UNHEALTHY_REACTOR_PERIOD ); + + if ( TRUE == isAlarmActive( ALARM_ID_UV_REACTOR_NOT_HEALTHY ) ) { + // The UV reactor is not healthy turn it off and trigger the alarm reactorsStatus[ reactor ].switchState = TURN_OFF; } } - // Check if the flow is below minimum - BOOL isFlowBelowMin = ( getMeasuredROFlowRateLPM() < MIN_RO_UV_FLOWRATE_LPM ? TRUE : FALSE ); - - if ( TRUE == isFlowBelowMin ) + switch( reactor ) { - // If the flow is below minimum for the first time, start the timer - if ( FALSE == reactorsStatus[ reactor ].isFlowBelowMin ) + case INLET_UV_REACTOR: { - reactorsStatus[ reactor ].isFlowBelowMin = TRUE; - reactorsStatus[ reactor ].reactorOnWithNoFlowTimer = getMSTimerCount(); + BOOL isVPIClosed = ( VALVE_STATE_CLOSED == getValveStateName( VPI ) ? TRUE : FALSE ); + checkPersistentAlarm( ALARM_ID_DG_INLET_UV_REACTOR_ON_WITH_NO_FLOW, isVPIClosed, (F32)VALVE_STATE_CLOSED, (F32)VALVE_STATE_OPEN ); } - else if ( TRUE == didTimeout( reactorsStatus[ reactor ].reactorOnWithNoFlowTimer, UV_REACTORS_ON_NO_FLOW_TIMEOUT_MS ) ) + break; + + case OUTLET_UV_REACTOR: { - // If the flow is below minimum and the allowed time has elapsed, set the reactor's signal to be low and set its state - // to be off. - setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); - // The state is directly changed here because the switch state is not changed to be off - reactorsStatus[ reactor ].execState = UV_REACTOR_STATE_OFF; + F32 flow = getMeasuredFlowRateLPM( RO_FLOW_SENSOR ); + BOOL isFlowBelowMin = ( flow < MIN_RO_UV_FLOWRATE_LPM ? TRUE : FALSE ); + checkPersistentAlarm( ALARM_ID_DG_OUTLET_UV_REACTOR_ON_WITH_NO_FLOW, isFlowBelowMin, flow, MIN_RO_UV_FLOWRATE_LPM ); } + break; + + default: + SET_ALARM_WITH_1_U32_DATA( ALARM_ID_DG_SOFTWARE_FAULT, SW_FAULT_ID_UV_REACTORS_INVALID_REACTOR_SELECTD ) + break; } // Check if it has been requested to turn off a reactor if ( TURN_OFF == reactorsStatus[ reactor ].switchState ) { setReactorEnableStatus( reactor, PIN_SIGNAL_LOW ); - state = UV_REACTOR_STATE_OFF; }