using System; using System.Collections.Generic; using System.Threading; using System.Diagnostics; using System.Linq; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using MECF.Framework.Common.DataCenter; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using Venus_Core; using Venus_RT.Devices; using Venus_RT.Modules; using Venus_RT.Modules.PMs; using MECF.Framework.Common.Routine; namespace Venus_RT.Modules.PMs { public class RecipeRunningInfo { public Guid InnerId { get; set; } public RecipeHead Head { get; set; } public List RecipeStepList { get; set; } public string RecipeName { get; set; } public DateTime BeginTime { get; set; } public DateTime EndTime { get; set; } public int StepNumber { get; set; } public string StepName { get; set; } public double StepTime { get; set; } public double StepElapseTime { get; set; } public double TotalTime { get; set; } public double TotalElapseTime { get; set; } } public class PMEntity : Entity, IModuleEntity { public enum MSG { Home, Transfer, PrepareTransfer, PostTransfer, Reset, Abort, Error, LaunchPump, LaunchTurboPump, Pump, Vent, PumpLoadLock, VentLoadLock, PurgeLoadLock, LoadLockLeakCheck, CyclePurge, GasLinePurge, Heat, TransferHandoff, StartTransfer, LeakCheck, GasLeakCheck, MoveLiftPin, MoveGuidePin, LLPlace, LLPick, Process, RunRecipe, PostProcess, RecipeSkipStep, RecipeUpdate, RecipeResume, RecipePause, RecipeAbort, PreProcess, AutoMode, ManualMode, LockLid, Online, Offline, GasFlow, StopGasFlow, RfPower, MaxMsg } private readonly JetPM _chamber; public ModuleName Module { get; } public Action TransferPrepared; private readonly PMHomeRoutine _home; private readonly StartDryPumpRoutine _startDryPumpRoutine; private readonly StartTurboPumpRoutine _startTurboPumpRoutine; private readonly VentRoutine _ventRoutine; private readonly PumpDownRoutine _pumpRoutine; private readonly LoadLockVentRoutine _ventLoadLockRoutine; private readonly LoadLockPumpRoutine _pumpLoadLockRoutine; private readonly LoadLockPurgeRoutine _purgeLoadLockRoutine; private readonly LoadLockLeakCheckRoutine _loadLockLeakCheckRoutine; private readonly PMPurgeRoutine _purgeRoutine; private readonly PMGaslinePurgeRoutine _gaslinePurgeRoutine; private readonly PMLeakCheckRoutine _leakCheckRoutine; private readonly GasBoxLeakCheckRoutine _gasBoxLeakCheckRoutine; private readonly LLPlaceRoutine _llPlaceRoutine; private readonly LLPickRoutine _llPickRoutine; public bool IsIdle { get { return fsm.State == (int)PMState.Idle; } } public bool IsError { get { return fsm.State == (int)PMState.Error; } } public bool IsInit { get { return fsm.State == (int)PMState.Init; } } public bool IsBusy { get { return !IsInit && !IsError && !IsIdle; } } public bool IsProcessing { get { return fsm.State == (int)PMState.PreProcess || fsm.State == (int)PMState.Processing || fsm.State == (int)PMState.PostProcess; } } public bool Check(int msg, out string reason, object[] objs) { reason = ""; return true; } // private bool CheckToPostMessage(int msg, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { EV.PostWarningLog(Module.ToString(), $"{Module} is in { (PMState)fsm.State} state,can not do {(MSG)msg}"); return false; } fsm.PostMsg(msg, args); return true; } public int Invoke(string function, params object[] args) { switch (function) { case "Home": CheckToPostMessage((int)MSG.Home); return (int)MSG.Home; } return (int)FSM_MSG.NONE; } public bool CheckAcked(int msg) { return fsm.CheckExecuted(msg); } public PMEntity(ModuleName module) { Module = module; _chamber = DEVICE.GetDevice(Module.ToString()); _home = new PMHomeRoutine(_chamber); _startDryPumpRoutine = new StartDryPumpRoutine(_chamber); _startTurboPumpRoutine = new StartTurboPumpRoutine(_chamber); _ventRoutine = new VentRoutine(_chamber); _pumpRoutine = new PumpDownRoutine(_chamber); _ventLoadLockRoutine = new LoadLockVentRoutine(_chamber); _pumpLoadLockRoutine = new LoadLockPumpRoutine(_chamber); _purgeLoadLockRoutine = new LoadLockPurgeRoutine(_chamber); _loadLockLeakCheckRoutine = new LoadLockLeakCheckRoutine(_chamber); _purgeRoutine = new PMPurgeRoutine(_chamber); _gaslinePurgeRoutine = new PMGaslinePurgeRoutine(_chamber); _leakCheckRoutine = new PMLeakCheckRoutine(_chamber); _gasBoxLeakCheckRoutine = new GasBoxLeakCheckRoutine(_chamber); _llPlaceRoutine = new LLPlaceRoutine(_chamber); _llPickRoutine = new LLPickRoutine(_chamber, _ventLoadLockRoutine); fsm = new StateMachine(Module.ToString(), (int)PMState.Init, 50); //Idle EnterExitTransition((int)PMState.Idle, FnIdle, (int)FSM_MSG.NONE, null); EnterExitTransition(PMState.Error, fEnterError, FSM_MSG.NONE, null); //Home //EnterExitTransition((int)PMState.Homing, FnEnterHome, (int)FSM_MSG.NONE, FnExitHome); AnyStateTransition(MSG.Error, FnError, PMState.Error); Transition(PMState.Init, FSM_MSG.TIMER, FnTimeout, PMState.Init); Transition(PMState.Init, MSG.Home, FnStartHome, PMState.Homing); Transition(PMState.Error, MSG.Home, FnStartHome, PMState.Homing); Transition(PMState.Idle, MSG.Home, FnStartHome, PMState.Homing); Transition(PMState.Homing, FSM_MSG.TIMER, FnMonitorHome, PMState.Idle); Transition(PMState.Idle, FSM_MSG.TIMER, FnIdleTimeout, PMState.Idle); Transition(PMState.Error, FSM_MSG.TIMER, FnErrorTimeout, PMState.Error); //Launch DryPump sequence Transition(PMState.Idle, MSG.LaunchPump, FnLaunchPump, PMState.LaunchingPump); Transition(PMState.LaunchingPump, FSM_MSG.TIMER, FnLaunchPumpTimeout, PMState.Idle); Transition(PMState.LaunchingPump, MSG.Abort, FnAbortStartPumping, PMState.Idle); //Launch TurboPump sequence Transition(PMState.Idle, MSG.LaunchTurboPump, FnLaunchTurboPump, PMState.LaunchingTurboPump); Transition(PMState.LaunchingTurboPump, FSM_MSG.TIMER, FnLaunchTurboPumpTimeout, PMState.Idle); Transition(PMState.LaunchingTurboPump, MSG.Abort, FnAbortStartTurboPumping, PMState.Idle); //vent sequence Transition(PMState.Idle, MSG.Vent, FnStartVent, PMState.Venting); Transition(PMState.Pumping, MSG.Vent, FnVentToPumping, PMState.Venting); Transition(PMState.Venting, FSM_MSG.TIMER, FnVentTimeout, PMState.Idle); Transition(PMState.Venting, MSG.Abort, FnAbortVent, PMState.Idle); //Pump sequence Transition(PMState.Idle, MSG.Pump, FnStartPumpDown, PMState.Pumping); Transition(PMState.Venting, MSG.Pump, FnVentToPumping, PMState.Pumping); Transition(PMState.Pumping, FSM_MSG.TIMER, FnPumpDownTimeout, PMState.Idle); Transition(PMState.Pumping, MSG.Abort, FnAbortPumping, PMState.Idle); //Pump Loadlock sequence Transition(PMState.Idle, MSG.PumpLoadLock, FnStartPumpDownLoadLock, PMState.PumpingLoadLock); Transition(PMState.VentingLoadLock, MSG.PumpLoadLock, FnVentLoadLockToPumpingLoadLock, PMState.PumpingLoadLock); Transition(PMState.PumpingLoadLock, FSM_MSG.TIMER, FnPumpDownLoadLockTimeout, PMState.Idle); Transition(PMState.PumpingLoadLock, MSG.Abort, FnAbortPumpingLoadLock, PMState.Idle); //Vent Loadlock sequence Transition(PMState.Idle, MSG.VentLoadLock, FnStartVentLoadlock, PMState.VentingLoadLock); Transition(PMState.PumpingLoadLock, MSG.VentLoadLock, FnPumpingLoadLockToVentLoadLock, PMState.VentingLoadLock); Transition(PMState.VentingLoadLock, FSM_MSG.TIMER, FnVentLoadLockTimeout, PMState.Idle); Transition(PMState.VentingLoadLock, MSG.Abort, FnAbortVentLoadLock, PMState.Idle); // Purge LoadLock sequence Transition(PMState.Idle, MSG.PurgeLoadLock, FnStartPurgeLoadlock, PMState.PurgingLoadLock); Transition(PMState.PurgingLoadLock, FSM_MSG.TIMER, FnPurgeLoadLockTimeout, PMState.Idle); Transition(PMState.PurgingLoadLock, MSG.Abort, FnAbortPurgeLoadLock, PMState.Idle); //LoadLock Leak check sequence Transition(PMState.Idle, MSG.LoadLockLeakCheck, FnStartLoadLockLeakCheck, PMState.LoadLockLeakCheck); Transition(PMState.LoadLockLeakCheck, FSM_MSG.TIMER, FnLoadLockLeakCheckTimeout, PMState.Idle); Transition(PMState.LoadLockLeakCheck, MSG.Abort, FnAbortLoadLockLeakCheck, PMState.Idle); // PM Purge sequence Transition(PMState.Idle, MSG.CyclePurge, FnStartPurge, PMState.Purging); Transition(PMState.Purging, FSM_MSG.TIMER, FnPurgeTimeout, PMState.Idle); Transition(PMState.Purging, MSG.Abort, FnAbortPurge, PMState.Idle); // PM GasLine Purge sequence Transition(PMState.Idle, MSG.GasLinePurge, FnStartGasLinePurge, PMState.GasLinePurge); Transition(PMState.GasLinePurge, FSM_MSG.TIMER, FnGasLinePurgeTimeout, PMState.Idle); Transition(PMState.GasLinePurge, MSG.Abort, FnAbortGasLinePurge, PMState.Idle); //PM Leak check sequence Transition(PMState.Idle, MSG.LeakCheck, FnStartPMLeakCheck, PMState.LeakCheck); Transition(PMState.LeakCheck, FSM_MSG.TIMER, FnPMLeakCheckTimeout, PMState.Idle); Transition(PMState.LeakCheck, MSG.Abort, FnAbortPMLeakCheck, PMState.Idle); //PM Leak check sequence Transition(PMState.Idle, MSG.GasLeakCheck, FnStartGasBoxLeakCheck, PMState.GasBoxLeakCheck); Transition(PMState.GasBoxLeakCheck, FSM_MSG.TIMER, FnGasBoxLeakCheckTimeout, PMState.Idle); Transition(PMState.GasBoxLeakCheck, MSG.Abort, FnAbortGasBoxLeakCheck, PMState.Idle); // PlaceWafer from LoadLock Arm sequence Transition(PMState.Idle, MSG.LLPlace, FnStartLLPlace, PMState.LLPlacing); Transition(PMState.LLPlacing, FSM_MSG.TIMER, FnLLPlaceTimeout, PMState.Idle); Transition(PMState.LLPlacing, MSG.Abort, FnAbortLLPlace, PMState.Idle); // PickWafer to LoadLock Arm sequence Transition(PMState.Idle, MSG.LLPick, FnStartLLPick, PMState.LLPicking); Transition(PMState.LLPicking, FSM_MSG.TIMER, FnLLPickTimeout, PMState.Idle); Transition(PMState.LLPicking, MSG.Abort, FnAbortLLPick, PMState.Idle); Running = true; } private bool FnIdle(object[] objs) { Running = false; return true; } private bool fEnterError(object[] objs) { return true; } private bool FnError(object[] objs) { Running = false; if (((PMState)fsm.State == PMState.Processing) || ((PMState)fsm.State == PMState.PreProcess) || ((PMState)fsm.State == PMState.Homing) || ((PMState)fsm.State == PMState.LoadProcessRecipe)) return false; if (IsProcessing) { WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed); } return true; } private bool FnTimeout(object[] objs) { _debugRoutine(); return true; } private bool FnIdleTimeout(object[] objs) { _debugRoutine(); return true; } private bool FnErrorTimeout(object[] objs) { _debugRoutine(); return true; } private bool FnStartHome(object[] objs) { return _home.Start() == RState.Running; } private bool FnMonitorHome(object[] objs) { RState ret = _home.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnLaunchPump(object[] param) { return _startDryPumpRoutine.Start() == RState.Running; } private bool FnLaunchPumpTimeout(object[] param) { RState ret = _startDryPumpRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortStartPumping(object[] param) { _startDryPumpRoutine.Abort(); return true; } private bool FnLaunchTurboPump(object[] param) { return _startTurboPumpRoutine.Start() == RState.Running; } private bool FnLaunchTurboPumpTimeout(object[] param) { RState ret = _startTurboPumpRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortStartTurboPumping(object[] param) { _startTurboPumpRoutine.Abort(); return true; } private bool FnStartVent(object[] param) { return _ventRoutine.Start() == RState.Running; } private bool FnVentTimeout(object[] param) { RState ret = _ventRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnVentToPumping(object[] param) { _ventRoutine.Abort(); return true; // FnStartPumpDown(param); } private bool FnAbortVent(object[] param) { _ventRoutine.Abort(); return true; } private bool FnStartPumpDown(object[] param) { return _pumpRoutine.Start() == RState.Running; } private bool FnPumpDownTimeout(object[] param) { RState ret = _pumpRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortPumping(object[] param) { _pumpRoutine.Abort(); return true; } private bool FnStartVentLoadlock(object[] param) { return _ventLoadLockRoutine.Start() == RState.Running; } private bool FnVentLoadLockTimeout(object[] param) { RState ret = _ventLoadLockRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnVentLoadLockToPumpingLoadLock(object[] param) { _ventLoadLockRoutine.Abort(); return FnStartPumpDownLoadLock(param); } private bool FnAbortVentLoadLock(object[] param) { _ventLoadLockRoutine.Abort(); return true; } private bool FnStartPumpDownLoadLock(object[] param) { return _pumpLoadLockRoutine.Start() == RState.Running; } private bool FnPumpDownLoadLockTimeout(object[] param) { RState ret = _pumpLoadLockRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnPumpingToVent(object[] param) { _pumpRoutine.Abort(); return FnStartVent(param); } private bool FnPumpingLoadLockToVentLoadLock(object[] param) { _pumpLoadLockRoutine.Abort(); return FnStartVentLoadlock(param); } private bool FnAbortPumpingLoadLock(object[] param) { _pumpLoadLockRoutine.Abort(); return true; } private bool FnStartPurgeLoadlock(object[] param) { return _purgeLoadLockRoutine.Start() == RState.Running; } private bool FnPurgeLoadLockTimeout(object[] param) { RState ret = _purgeLoadLockRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortPurgeLoadLock(object[] param) { _purgeLoadLockRoutine.Abort(); return true; } private bool FnStartLoadLockLeakCheck(object[] param) { return _loadLockLeakCheckRoutine.Start() == RState.Running; } private bool FnLoadLockLeakCheckTimeout(object[] param) { RState ret = _loadLockLeakCheckRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortLoadLockLeakCheck(object[] param) { _loadLockLeakCheckRoutine.Abort(); return true; } private bool FnStartPurge(object[] param) { return _purgeRoutine.Start() == RState.Running; } private bool FnPurgeTimeout(object[] param) { RState ret = _purgeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortPurge(object[] param) { _purgeRoutine.Abort(); return true; } private bool FnStartGasLinePurge(object[] param) { return _gaslinePurgeRoutine.Start() == RState.Running; } private bool FnGasLinePurgeTimeout(object[] param) { RState ret = _gaslinePurgeRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortGasLinePurge(object[] param) { _gaslinePurgeRoutine.Abort(); return true; } private bool FnStartPMLeakCheck(object[] param) { return _leakCheckRoutine.Start() == RState.Running; } private bool FnPMLeakCheckTimeout(object[] param) { RState ret = _leakCheckRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortPMLeakCheck(object[] param) { _leakCheckRoutine.Abort(); return true; } private bool FnStartGasBoxLeakCheck(object[] param) { return _gasBoxLeakCheckRoutine.Start() == RState.Running; } private bool FnGasBoxLeakCheckTimeout(object[] param) { RState ret = _gasBoxLeakCheckRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortGasBoxLeakCheck(object[] param) { _gasBoxLeakCheckRoutine.Abort(); return true; } private bool FnStartLLPlace(object[] param) { return _llPlaceRoutine.Start() == RState.Running; } private bool FnLLPlaceTimeout(object[] param) { RState ret = _llPlaceRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortLLPlace(object[] param) { _llPlaceRoutine.Abort(); return true; } private bool FnStartLLPick(object[] param) { return _llPickRoutine.Start() == RState.Running; } private bool FnLLPickTimeout(object[] param) { RState ret = _llPickRoutine.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FnAbortLLPick(object[] param) { _llPickRoutine.Abort(); return true; } private void _debugRoutine() { int flag = 0; // Test Home routine if (flag == 1) { PostMsg(MSG.Home); } else if (flag == 2) { PostMsg(MSG.Vent); } else if (flag == 3) { PostMsg(MSG.Pump); } else if(flag == 4) { PostMsg(MSG.PumpLoadLock); } else if(flag == 5) { PostMsg(MSG.VentLoadLock); } else if(flag == 6) { PostMsg(MSG.PurgeLoadLock); } else if(flag == 7) { PostMsg(MSG.LaunchPump); } else if(flag == 8) { PostMsg(MSG.LaunchTurboPump); } else if(flag == 9) { PostMsg(MSG.LoadLockLeakCheck); } else if(flag == 10) { PostMsg(MSG.CyclePurge); } else if(flag == 11) { PostMsg(MSG.GasLinePurge); } else if(flag == 12) { PostMsg(MSG.LeakCheck); } else if(flag == 13) { PostMsg(MSG.GasLeakCheck); } else if(flag == 14) { PostMsg(MSG.LLPlace); } else if(flag == 15) { PostMsg(MSG.LLPick); } } } }