using System; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using JetVirgoPM.Devices; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs; namespace JetVirgoPM.PMs.Routines { public enum MonitorStepState { Continue, Failed, Break, } class PMRoutineBase : ModuleRoutineBase { // ----------------------------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; //public static Guid RecipeRunGuid; protected readonly JetDualPM _chamber; // --------------------------Properties------------------------ // //状态持续时间,单位为秒 public int Elapsed { get { return (int)(counter.GetElapseTime() / 1000); } } public string Display { get; set; } public string WaferID { get; set; } // Constructor protected PMRoutineBase(JetDualPM chamber):base(chamber.Module.ToString()) { _chamber = chamber; bUINotify = true; dOpenGasValveTimeout = SC.GetValue($"{Module}.OpenGasValveTimeout"); dCloseGasValveTimeout = SC.GetValue($"{Module}.TimeLimitOfCloseGasValve"); valveOpenCloseTimeout = SC.GetValue($"{Module}.OpenCloseSlitValveTimeout"); } public RState CheckLid() { if (!_chamber.IsLidClosed) { this.Stop("Chamber 盖子必须关"); return RState.Failed; } return RState.Running; } protected RState CheckSlitDoor1() { if (!_chamber.IsSlitDoor1Closed) { Stop("传送门1必须关"); return RState.Failed; } return RState.Running; } protected RState CheckSlitDoor2() { if (!_chamber.IsSlitDoor2Closed) { Stop("传送门2必须关"); return RState.Failed; } return RState.Running; } protected RState CheckDryPump() { if (!_chamber.IsPumpRunning) { Stop("泵没有启动"); return RState.Failed; } if (_chamber.HasPumpError) { Stop("泵状态有错误"); return RState.Failed; } return RState.Running; } protected bool FullOpenTV() { Notify("完全打开蝶阀"); _chamber.FullOpenTV(); return true; } protected bool CheckFullOpenTV() { if (_chamber.TVPosition >= 98) { Notify("蝶阀已经完全打开"); return true; } return false; } protected bool CloseAllValve() { Notify("关闭所有的阀门"); _chamber.CloseValves(); return true; } protected bool OpenValve(ValveType vlv, bool bOpen) { _chamber.OpenValve(vlv, bOpen); Notify($"{(bOpen ? "打开" : "关闭")} {vlv} 阀"); return true; } protected bool CheckValve(ValveType vlv, bool bOpen) { return _chamber.CheckValveSwitchStatus(vlv, bOpen); } protected bool ATM2(bool on) { Notify($"等待 ATM 信号 {(on ? "ON" : "OFF")}"); return true; } protected bool CheckATM2(bool on) { return on ? _chamber.IsATM : !_chamber.IsATM; } protected bool WaitPressure(int targetPressure, bool morethan) { Notify($"等待压力{(morethan ? "上升" : "下降")} 到 {targetPressure:N} mTorr"); return true; } protected bool CheckPressure(int targetPressure, bool morethan) { bool res = morethan ? _chamber.ChamberPressure > targetPressure : _chamber.ChamberPressure < targetPressure; if (res) { Notify($"压力已经到达 {targetPressure:N} mTorr"); } return res; } protected bool Foreline(uint target) { Notify($"Check foreline pressure, 目标 {target} mTorr"); return true; } protected bool CheckForeline(uint target) { return _chamber.ForelinePressure < target; } protected bool CheckVAC() { return _chamber.IsVAC; } protected bool SetLiftPinUpDown(EnumDualPM pos, bool isUp) { if (pos == EnumDualPM.Left || pos == EnumDualPM.Both) { Notify($"设置 lift pin 1 {_chamber.Name} " + (isUp ? "升" : "降")); if (!_chamber.SetLiftPin1(isUp ? MovementPosition.Up : MovementPosition.Down, out string reason)) { Stop(reason); return false; } } if (pos == EnumDualPM.Right || pos == EnumDualPM.Both) { Notify($"设置 lift pin 2 {_chamber.Name} " + (isUp ? "升" : "降")); if (!_chamber.SetLiftPin2(isUp ? MovementPosition.Up : MovementPosition.Down, out string reason)) { Stop(reason); return false; } } return true; } protected bool ChecktLiftPinUpDown(EnumDualPM pos, bool isUp) { return ((pos != EnumDualPM.Left && pos != EnumDualPM.Both) || (isUp ? _chamber.CheckLift1Up() : _chamber.CheckLift1Down())) && ((pos != EnumDualPM.Right && pos != EnumDualPM.Both) || (isUp ? _chamber.CheckLift2Up() : _chamber.CheckLift2Down())); } protected bool SetSlitDoor(EnumDualPM pos, bool isOpen) { if(pos == EnumDualPM.Left || pos == EnumDualPM.Both) { Notify($"设置 {_chamber.Name} Slit Door 1 {(isOpen ? "开" : "关")} "); if (!_chamber.SetSlitDoor1(isOpen, out string reason1)) { Stop(reason1); return false; } } if (pos == EnumDualPM.Right || pos == EnumDualPM.Both) { Notify($"设置 {_chamber.Name} Slit Door 2 {(isOpen ? "开" : "关")} "); if (!_chamber.SetSlitDoor2(isOpen, out string reason2)) { Stop(reason2); return false; } } return true; } protected bool CheckSlitDoor(EnumDualPM pos, bool isOpen) { return ((pos != EnumDualPM.Left && pos != EnumDualPM.Both) || (isOpen ? _chamber.CheckSlitDoor1Open() : _chamber.CheckSlitDoor1Close())) && ((pos != EnumDualPM.Right && pos != EnumDualPM.Both) || (isOpen ? _chamber.CheckSlitDoor2Open() : _chamber.CheckSlitDoor2Close())); } protected void End(int id) { bool Func() { double duration_min = counter.GetElapseTime(); TimeSpan ts = TimeSpan.FromMilliseconds(duration_min); string info = $"完成 in {ts.Minutes} minutes {ts.Seconds} seconds"; Notify(info); //if (bUINotify) // EV.PostPopDialogMessage(EventLevel.Information, Name, $"{Module} {info} Finished"); return true; } //Runner.End(id, Func, _delay_1s); } protected bool EndFunc() { double duration_min = counter.GetElapseTime(); TimeSpan ts = TimeSpan.FromMilliseconds(duration_min); string info = $"完成 in {ts.Minutes} minutes {ts.Seconds} seconds"; Notify(info); return true; } public virtual void Abort() { _chamber.Generator1PowerOn(false); _chamber.GeneratorBias1PowerOn(false); _chamber.Generator2PowerOn(false); _chamber.GeneratorBias2PowerOn(false); _chamber.StopAllGases(); //ProcessDataRecorder.UpdateStatus(RecipeRunGuid.ToString(), SusceptorStatus.Failed.ToString(), Module); } public bool CloseValve() { Notify("Vent End Close Vent Valve"); _chamber.OpenValve(ValveType.PURGE, false); _chamber.OpenValve(ValveType.FAST_VENT, false); _chamber.OpenValve(ValveType.PROCESS, false); //_chamber.OpenValve(ValveType.SOFT_PUMP, true); //_chamber.OpenValve(ValveType.FAST_PUMP, true); return true; } protected bool Pump(int target) { Notify($"Pumping to {target} mTorr"); _chamber.OpenValve(ValveType.PROCESS, false); _chamber.OpenValve(ValveType.PURGE, false); _chamber.OpenValve(ValveType.FAST_VENT, false); _chamber.OpenValve(ValveType.FAST_PUMP, true); return true; } protected bool CheckPump(int target, bool isStopPumpOnceDone) { if (_chamber.ChamberPressure < target) { if (isStopPumpOnceDone) { _chamber.OpenValve(ValveType.FAST_PUMP, false); } return true; } return false; } protected bool Vent(int target) { Notify($"Venting to {target} mTorr"); _chamber.OpenValve(ValveType.FAST_VENT, false); _chamber.OpenValve(ValveType.FAST_PUMP, false); _chamber.OpenValve(ValveType.PROCESS, true); _chamber.OpenValve(ValveType.PURGE, true); _chamber.OpenValve(ValveType.N2, true); return true; } protected bool CheckVent(int target, bool isStopVentOnceDone) { if (_chamber.ChamberPressurePressure > target) { if (isStopVentOnceDone) { _chamber.OpenValve(ValveType.PROCESS, false); _chamber.OpenValve(ValveType.PURGE, false); _chamber.OpenValve(ValveType.N2, false); } return true; } return false; } protected bool SetLETemp(double target1, double target2, double tolerance, bool enableLE1, bool enableLE2) { if (enableLE1) { if (_chamber.LETempFB1 > target1) { Notify($"{_chamber.LETempFB1Name}当前温度{_chamber.LETempFB1} ℃, 大于目标 {target1.ToString()} ℃"); //return true; } //if (!(Math.Abs(_chamber.LETempFB1 - target1) <= tolerance)) { _chamber.HeatLE1(target1); } Notify($"检查底座温度值,{_chamber.LETempFB1Name}当前温度{_chamber.LETempFB1} ℃, 目标 {target1.ToString()} ℃"); } if (enableLE2) { if (_chamber.LETempFB2 > target2) { Notify($"{_chamber.LETempFB2Name}当前温度{_chamber.LETempFB2} ℃, 大于目标 {target2.ToString()} ℃"); //return true; } //if (!(Math.Abs(_chamber.LETempFB2 - target2) <= tolerance)) { _chamber.HeatLE2(target2); } Notify($"检查底座温度值,{_chamber.LETempFB2Name}当前温度{_chamber.LETempFB2} ℃, 目标 {target2.ToString()} ℃"); } return true; } protected bool CheckLETemp(double target1, double target2, double tolerance, bool enableLE1, bool enableLE2) { return (!enableLE1 || Math.Abs(_chamber.LETempFB1 - target1) <= tolerance) && (!enableLE2 || Math.Abs(_chamber.LETempFB2 - target2) <= tolerance); } protected bool SetCoolant1Temp(double target, double offset, double tolerance) { if (_chamber.CoolantOutletTempFB1 > target) { Notify($"水冷当前温度{_chamber.CoolantOutletTempFB1} ℃, 大于目标 {target.ToString()} ℃"); //return true; } //if (!(Math.Abs(_chamber.CoolantOutletTempFB1 - target) <= tolerance)) { _chamber.HeatChiller1(target, offset); } Notify($"检查水冷温度值,当前温度{_chamber.CoolantOutletTempFB1} ℃, 目标 {target.ToString()} ℃"); return true; } protected bool CheckCoolant1Temp(double target, double offset, double tolerance) { return Math.Abs(_chamber.CoolantOutletTempFB1 - target) <= tolerance; } protected bool SetCoolant2Temp(double target, double offset, double tolerance) { if (_chamber.CoolantOutletTempFB2 > target) { Notify($"水冷当前温度{_chamber.CoolantOutletTempFB2} ℃, 大于目标 {target.ToString()} ℃"); //return true; } //if (!(Math.Abs(_chamber.CoolantOutletTempFB2 - target) <= tolerance)) { _chamber.HeatChiller2(target, offset); } Notify($"检查水冷温度值,当前温度{_chamber.CoolantOutletTempFB2} ℃, 目标 {target.ToString()} ℃"); return true; } protected bool CheckCoolant2Temp(double target, double offset, double tolerance) { return Math.Abs(_chamber.CoolantOutletTempFB2 - target) <= tolerance; } } }