| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 | using System;using System.Collections.Generic;using Aitex.Core.Equipment.SusceptorDefine;using Aitex.Core.RT.Event;using Aitex.Core.RT.Log;using Aitex.Core.RT.Routine;using Aitex.Core.RT.SCCore;using MECF.Framework.Common.DBCore;using VirgoRT.Devices;using VirgoCommon;namespace VirgoRT.Modules.PMs{    class PostProcessRoutine : PMRoutineBase    {        private enum PostProcessSequence        {            DelayForTest,            RFPowerOff,            StopGasFlow,            CloseAllValves,            ClosePumpValve,            DelayWaitValve,            Loop,            SetLiftPin,            Pump,            PumpDelay,            Vent,            VentDelay,            EndLoop,            ClosePurgeValve,            VentEndToPrecision,            VentEndDelay,            VentEndCloseVentValve,            VentAndPinDown,            End,        };        private RecipeHead head;        private int _purgeCycleCount;        private int _purgeVentPressure;        private int _purgePumpPressure;        private int _purgeVentTimeLimit;        private int _purgePumpTimeLimit;        private int _purgeVentStableTime;        private int _purgePumpStableTime;        private int _ventTime;        //private int _ventTimeLimit;        private readonly RfPowerRoutine _rfPowerRoutine;        private readonly VentRoutine _ventRoutine;        private readonly int _VentingAndPinUpTimeout = 60 * 1000;        //---------------------------------Properties------------------------------------        //         public string RecipeName { get; private set; }        public string RecipeContext { get; private set; }        private bool PurgeActive        {            get            {                if (head != null)                {                    if (!string.IsNullOrEmpty(head.PurgeActive))                    {                        return Convert.ToBoolean(head.PurgeActive);                    }                }                return true;            }        }        //For keep vacuum after idle clean        private bool NotToPurgeOrVent        {            get            {                if (head != null)                {                    if (!string.IsNullOrEmpty(head.NotToPurgeOrVent))                    {                        return Convert.ToBoolean(head.NotToPurgeOrVent);                    }                }                return false;            }        }        public MovementPosition LiftPinPosition        {            get            {                if (head != null)                {                    if (!string.IsNullOrEmpty(head.VentingPinState))                    {                        switch (head.VentingPinState)                        {                            case "Up":                                return MovementPosition.Up;                            case "Middle":                                return MovementPosition.Middle;                            case "Down":                                return MovementPosition.Down;                        }                    }                }                return MovementPosition.Down;            }        }        //--------------------------------Constructor------------------------------------        //         public PostProcessRoutine(JetPM chamber, VentRoutine _vRoutine) : base(chamber)        {            Name = "PostProcess";            _rfPowerRoutine = new RfPowerRoutine(_chamber, false);            _ventRoutine = _vRoutine;        }        public void Terminate()        {        }        public Result Start(params object[] objs)        {            try            {                Reset();                //this.UpdateSCValue();                RecipeName = (string)objs[0];                RecipeContext = (string)objs[1];                List<RecipeStep> recipeSteps;                if (!Recipe.Parse(Module, RecipeContext, out head, out recipeSteps))                {                    return Result.FAIL;                }                _purgeCycleCount = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeCycleCount");                _purgeVentPressure = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeVentPressure");                _purgePumpPressure = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgePumpPressure");                _purgeVentTimeLimit = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeVentTimeLimit");                _purgePumpTimeLimit = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgePumpTimeLimit");                _purgeVentStableTime = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeVentStableTime");                _purgePumpStableTime = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgePumpStableTime");                _ventTime = (int)SC.GetValue<double>($"{_chamber.Module}.VentTime");                //_ventTimeLimit = (int)SC.GetSC<double>(SCName.System_VentTimeLimit).Value;            }            catch (Exception ex)            {                LOG.Write(ex, "Post process Start has exception");                return Result.FAIL;            }            Notify("Start");            return Result.RUN;        }        public Result Monitor()        {            try            {                if (SC.GetValue<bool>("System.IsSimulatorMode"))                {                    TimeDelay((int)PostProcessSequence.DelayForTest, 10);                }                ExecuteRoutine((int)PostProcessSequence.RFPowerOff, _rfPowerRoutine);                CloseAllValve((int)PostProcessSequence.CloseAllValves, 1);                if (!NotToPurgeOrVent)   //For keep vacuum after idle clean                {                    if (PurgeActive)                    {                        StartLoop((int)PostProcessSequence.Loop, "", _purgeCycleCount, Notify, Stop);                        CyclePump((int)PostProcessSequence.Pump, _purgePumpPressure, _purgePumpTimeLimit, true);                        TimeDelay((int)PostProcessSequence.PumpDelay, _purgePumpStableTime);                        CycleVent((int)PostProcessSequence.Vent, _purgeVentPressure, _purgeVentTimeLimit, true);                        TimeDelay((int)PostProcessSequence.VentDelay, _purgeVentStableTime);                        EndLoop((int)PostProcessSequence.EndLoop, Notify, Stop);                    }                    ParallellyVentAndLiftPin((int)PostProcessSequence.VentAndPinDown);                    CloseValve((int)PostProcessSequence.VentEndCloseVentValve, valveOpenCloseTimeout);                }                End((int)PostProcessSequence.End);            }            catch (RoutineBreakException)            {                return Result.RUN;            }            catch (RoutineFaildException)            {                Notify("Error");                return Result.FAIL;            }            catch (Exception ex)            {                Stop(ex.Message);                return Result.FAIL;            }            Notify("Finish");            return Result.DONE;        }        public void Exit()        {            //ProcessDataRecorder.End(RecipeRunGuid.ToString(), SusceptorStatus.Processed.ToString(), Module);            //if (DeviceModel.SignalTower != null)            //{            //    DeviceModel.SignalTower.BuzzerBlinking(SC.GetValue<double>(SCName.System_BuzzerBlinkingTime));            //}            //update processing end time            //Singleton<ProcessRecorder>.Instance.EndRecipeProcess(Singleton<PMEntity>.Instance.CurrentRunningJob.RecipeRunId, SusceptorStatus.Processed);        }        private void ParallellyVentAndLiftPin(int id)        {            bool Func()            {                Notify($"Set lift pin {_chamber.Name}  {LiftPinPosition}");                if (!_chamber.SetLiftPin(LiftPinPosition, out string reason))                {                    Stop(reason);                    return false;                }                _ventRoutine.Start();                return true;            }            bool? Check1()            {                bool res1 = _chamber.CheckLiftPinPos(LiftPinPosition);                var result = _ventRoutine.Monitor();                return res1 && result == Result.DONE;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, _VentingAndPinUpTimeout);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    Stop(_chamber.CheckLiftPinPos(LiftPinPosition) ? $"Set Pin Up timeout in {_VentingAndPinUpTimeout / 1000} seconds" : $"Venting timeout  in {_VentingAndPinUpTimeout / 1000} seconds");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }    }}
 |