| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678 | using System;using Aitex.Core.Equipment.SusceptorDefine;using Aitex.Core.RT.Event;using Aitex.Core.RT.Routine;using Aitex.Core.RT.SCCore;using MECF.Framework.Common.DBCore;using VirgoCommon;//using Virgo.Common;using VirgoRT.Devices;namespace VirgoRT.Modules.PMs{    public enum MonitorStepState    {        Continue,        Failed,        Break,    }    class PMRoutineBase : ModuleRoutine    {        // ----------------------------Fields--------------------------        //        //private SCConfigItem scOpenGasValveTimeout = null;        private int dOpenGasValveTimeout = 1;  //1S        //private SCConfigItem scCloseGasValveTimeout = null;        public int dCloseGasValveTimeout = 2;  //2s        //private SCConfigItem scOpenCloseSlitValveTimeout = null;        protected int valveOpenCloseTimeout = 2;  //2s        protected int _PressureTrip1 = 80;        protected bool bUINotify;        protected readonly JetPM _chamber;        // --------------------------Properties------------------------        //        public string Display { get; set; }        public string WaferID { get; set; }        // Constructor        protected PMRoutineBase(JetPM chamber)        {            this.Module = chamber.Module.ToString();            _chamber = chamber;            bUINotify = true;            dOpenGasValveTimeout = SC.GetValue<int>($"{Module}.OpenGasValveTimeout");            dCloseGasValveTimeout = SC.GetValue<int>($"{Module}.TimeLimitOfCloseGasValve");            valveOpenCloseTimeout = SC.GetValue<int>($"{Module}.OpenCloseSlitValveTimeout");        }        public Result CheckLid()        {            if (!_chamber.IsLidClosed)            {                this.Stop("The chamber lid must be closed");                return Result.FAIL;            }            return Result.RUN;        }        protected Result CheckSlitDoor()        {            if (!_chamber.IsSlitDoorClosed)            {                Stop("Slit door must be closed");                return Result.FAIL;            }            return Result.RUN;        }        protected Result CheckDryPump()        {            if (!_chamber.IsPumpRunning)            {                Stop("The pump has not started");                return Result.FAIL;            }            if (_chamber.HasPumpError)            {                Stop("The pump status error");                return Result.FAIL;            }            return Result.RUN;        }        public void CheckThrottleValveFullOpen(int id)        {            bool execute()            {                Notify("Open the throttle valve");                _chamber.FullOpenTV();                return true;            }            bool? Check1()            {                if (_chamber.TVPosition >= 98)                {                    Notify("The throttle valve is opened");                    return true;                }                return false;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, execute, Check1, 20 * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    Stop("Not open the throttle valve");                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    Stop("Start the throttle valve timeout");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected Result CheckCDA()        {            if (!_chamber.IsCDA_OK)            {                Stop("The CDA pressure signal is incorrect");                return Result.FAIL;            }            return Result.RUN;        }        protected void CloseAllValve(int id, int time)        {            bool execute()            {                Notify("Close all valve");                _chamber.CloseValves();                return true;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, execute, () => true, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void SetValve(int id, ValveType vlv, bool bOpen)        {            bool exec()            {                _chamber.SetValveOnOff(vlv, bOpen);                Notify($"{(bOpen ? "open" : "close")} {vlv} valve");                return true;            }            bool? Check1()            {                if (vlv == ValveType.FAST_PUMP && bOpen)                    return _chamber.IsFastPumpOpened;                else if (vlv == ValveType.FAST_PUMP && !bOpen)                    return !_chamber.IsFastPumpOpened;                else if (vlv == ValveType.SOFT_PUMP && bOpen)                    return _chamber.IsSoftPumpOpened;                else if (vlv == ValveType.SOFT_PUMP && !bOpen)                    return !_chamber.IsSoftPumpOpened;                else                    return true;            }            var res = ExecuteAndWait(id, exec, Check1, 500);            if (res.Item1)            {                throw new RoutineBreakException();            }        }        protected void CheckATM2(int id, bool on, int time)        {            bool? check()            {                //if (!_chamber.IsATM)                //{                //    Notify("ATM is OFF");                //}                return on ? _chamber.IsATM : !_chamber.IsATM;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Wait ATM sensor {(on ? "ON" : "OFF")}");                return true;            }, check, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL || ret.Item2 == Result.TIMEOUT)                {                    Stop($"ATM sensor {(_chamber.IsATM ? "ON" : "OFF")}");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CheckPressure(int id, int targetPressure, bool morethan, int time)        {            bool? Check1()            {                bool res = morethan ? _chamber.ChamberPressure > targetPressure : _chamber.ChamberPressure < targetPressure;                if (res)                {                    Notify($"The pressure has reached {targetPressure:N} mTorr");                }                return res;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Wait pressure {(morethan ? "rise" : "decline")} to {targetPressure:N} mTorr");                return true;            }, Check1, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    Stop($"Current pressure [{_chamber.ChamberPressure}], not equal to [{targetPressure}]");                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    Stop($"Check chamber pressuer timeout, current value [{_chamber.ChamberPressure*0.001:F2}] Torr");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CheckForeline(int id, uint target, int time)        {            bool Func()            {                Notify($"Check foreline pressure, target {target} mTorr");                return true;            }            bool? Check1()            {                return _chamber.ForelinePressure < target;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    Stop($"Check foreline pressure timeout, current foreline pressure value {_chamber.ForelinePressure}");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CheckVAC(int id, double targetPressure, int time)        {            bool? Check1()            {                if (_chamber.ChamberPressure < targetPressure)                {                    Notify($"Pump below [{targetPressure}]");                    return true;                }                return false;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, () => true, Check1, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT) //timeout                {                    //Warning($"Can not pump to base pressure {target} in {time} seconds");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CheckVAC(int id, int time)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () => true, () => _chamber.IsVAC, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    Stop("VAC sensor NOT ON");                    throw new RoutineFaildException();                }                if (Result.TIMEOUT == ret.Item2)                {                    Stop($"VAC sensor timeout, chamber pressure {_chamber.ChamberPressure}");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        public void SetLiftPinPos(int id, MovementPosition pos, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Set lift pin {_chamber.Name}  {pos}" );                if (!_chamber.SetLiftPin(pos, out string reason))                {                    Stop(reason);                    return false;                }                return true;            }, () => _chamber.CheckLiftPinPos(pos), timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    Stop($"Set lift pin {pos} in {timeout} seconds");                    throw new RoutineFaildException();                }                else                    throw new RoutineBreakException();            }        }        protected void End(int id)        {            bool Func()            {                double duration_min = counter.GetElapseTime();                TimeSpan ts = TimeSpan.FromMilliseconds(duration_min);                string info = $"Finished in {ts.Minutes} minutes {ts.Seconds} seconds";                Notify(info);                //if (bUINotify)                //    EV.PostPopDialogMessage(EventLevel.Information, Name, $"{Module} {info} Finished");                return true;            }            Tuple<bool, Result> ret = Execute(id, Func);        }        public virtual void Abort()        {            _chamber.GeneratorPowerOn(false);            _chamber.GeneratorBiasPowerOn(false);            _chamber.StopAllGases();        }        /// <summary>        ///         /// </summary>        /// <param name="stepId"></param>        /// <param name="delayTime">单位:秒</param>        public void CloseValve(int stepId, float delayTime)        {            bool Func()            {                Notify("Vent End Close Vent Valve");                _chamber.SetValveOnOff(ValveType.PURGE, false);                _chamber.SetValveOnOff(ValveType.FAST_VENT, false);                _chamber.SetValveOnOff(ValveType.PROCESS, false);                //_chamber.OpenValve(ValveType.SOFT_PUMP, true);                //_chamber.OpenValve(ValveType.FAST_PUMP, true);                return true;            }            Tuple<bool, Result> ret = Delay(stepId, Func, delayTime * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void StartLoop(int id, string name, int count, Action<string> notify, Action<string> error)        {            bool Func()            {                Notify($"{name} loop {LoopCounter + 1}");                return true;            }            Tuple<bool, Result> ret = Loop(id, Func, count);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                    throw new RoutineFaildException();            }        }        protected void EndLoop(int id, Action<string> notify, Action<string> error)        {            Tuple<bool, Result> ret = EndLoop(id, () => true);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                    throw new RoutineFaildException();                throw new RoutineBreakException();            }        }        protected void CyclePump(int id, int target, int timeLimit, bool isStopPumpOnceDone)        {            bool Func()            {                Notify($"Pumping to {target} mTorr");                _chamber.SetValveOnOff(ValveType.PROCESS, false);                _chamber.SetValveOnOff(ValveType.PURGE, false);                _chamber.SetValveOnOff(ValveType.FAST_VENT, false);                _chamber.SetValveOnOff(ValveType.FAST_PUMP, true);                return true;            }            bool? Check1()            {                if (_chamber.ChamberPressure < target)                {                    if (isStopPumpOnceDone)                    {                        _chamber.SetValveOnOff(ValveType.FAST_PUMP, false);                    }                    return true;                }                return true;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, timeLimit * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    Stop($"Set pump pressure {target} timeout in time {timeLimit}");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CycleVent(int id, int target, int timeLimit, bool isStopVentOnceDone)        {            bool Func()            {                Notify($"Venting to {target} mTorr");                _chamber.SetValveOnOff(ValveType.FAST_PUMP, false);                _chamber.SetValveOnOff(ValveType.PROCESS, true);                _chamber.SetValveOnOff(ValveType.PURGE, true);                return true;            }            bool? Check1()            {                if (_chamber.ChamberPressurePressure > target)                {                    if (isStopVentOnceDone)                    {                        _chamber.SetValveOnOff(ValveType.PROCESS, false);                        _chamber.SetValveOnOff(ValveType.PURGE, false);                        _chamber.SetValveOnOff(ValveType.FAST_VENT, false);                    }                    return true;                }                return false;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, timeLimit * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT) //timeout                {                    Stop($"Set vent pressure {target} timeout in vent time {timeLimit}");                    if (isStopVentOnceDone)                    {                        _chamber.SetValveOnOff(ValveType.PROCESS, false);                        _chamber.SetValveOnOff(ValveType.PURGE, false);                        _chamber.SetValveOnOff(ValveType.FAST_VENT, false);                    }                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CheckSubstrateTemp(int id, double target, int time, double tolerance)        {            bool Func()            {                if (_chamber.SubstrateTempFB > target)                {                    Notify($"Substrate current temp {_chamber.SubstrateTempFB} ℃, greater than target {target.ToString()} ℃");                    //return true;                }                _chamber.HeatSubstrate(target);                Notify($"Check substrate temp,current temp{_chamber.SubstrateTempFB} ℃, target {target.ToString()} ℃");                return true;            }            bool? Check1()            {                if (Math.Abs( target) <= 0.1)                    return true;                if (Math.Abs(_chamber.SubstrateTempFB - target) <= tolerance)                     return true;                                  return false;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    Stop($"Check substrate temp timeout, current Substrate temp value {_chamber.SubstrateTempFB}");                    throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void CheckCoolantTemp(int id, double target, double offset, int time, double tolerance)        {            bool Func()            {                if (_chamber.CoolantOutletTempFB > target)                {                    Notify($"Chiller current temp {_chamber.CoolantOutletTempFB} ℃, greater than target value {target.ToString()} ℃");                    //return true;                }                _chamber.HeatChiller(target, offset);                Notify($"Check chiller temp,current temp {_chamber.CoolantOutletTempFB} ℃, target {target.ToString()} ℃");                return true;            }            bool? Check1()            {                if (!_chamber.CheckChillerStatus())                    return false;                 return Math.Abs(_chamber.CoolantOutletTempFB - target) <= tolerance;            }            Tuple<bool, Result> ret = ExecuteAndWait(id, Func, Check1, time * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                if (ret.Item2 == Result.TIMEOUT)                {                    if (!_chamber.CheckChillerStatus())                    {                        Stop($"Chiller not connected or in error");                    }                    else                    {                        Stop($"Check chiller temp timeout, current chiller temp value {_chamber.CoolantOutletTempFB}");                    }                                        throw new RoutineFaildException();                }                throw new RoutineBreakException();            }        }        protected void SetSlitDoor(int id, bool isOpen, int timeout)        {            Tuple<bool, Result> ret = ExecuteAndWait(id, () =>            {                Notify($"Set slit door {_chamber.Name} " + (isOpen ? "open" : "close"));                _chamber.SetSlitDoor(isOpen, out _);                return true;            }, () => isOpen ? _chamber.CheckSlitDoorOpen() : _chamber.CheckSlitDoorClose(), timeout * 1000);            if (ret.Item1)            {                if (ret.Item2 == Result.FAIL)                {                    throw new RoutineFaildException();                }                else if (ret.Item2 == Result.TIMEOUT) //timeout                {                    Stop($"Set slit door {(isOpen ? "open" : "close")} timeout  in {timeout} seconds");                    throw new RoutineFaildException();                }                else                    throw new RoutineBreakException();            }        }    }}
 |