using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.RT.Fsm; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Event; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Jobs; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using Venus_Core; using Venus_RT.Modules.PMs; using Aitex.Core.RT.Log; using Venus_RT.Modules.VCE; using Venus_RT.Devices.PreAligner; using Venus_RT.Modules.TM.VenusEntity; using SecsGem.Core.Application; using Aitex.Core.RT.RecipeCenter; using System.Reflection; using Venus_RT.Modules.LPs; using System.Runtime.InteropServices; using Venus_RT.Devices.EFEM; namespace Venus_RT.Modules { class RouteManager : Entity, IEntity, IEquipmentCommand { public enum MSG { MoveWafer, ReturnWafer, HomeUnit, PauseAuto, ResumeAuto, Stop, StartCycle, StopCycle, HOME, RESET, ABORT, ERROR, SetAutoMode, SetManualMode, ResetIdleCleanTime, ResetIdlePurgeTime, CreateJob, PauseJob, ResumeJob, StartJob, StopJob, AbortJob, JobDone, CassetteLeave, //For unload light control off afer job done Map, ReturnAllWafer, TMCycle, SETMCycle, StopSECycle, CreateSEJob, StartSEJob, AbortSEJob, SEMoveWafer, SEReturnWafer, SEAbort, } public PMEntity PMA { get; private set; } public PMEntity PMB { get; private set; } public PMEntity PMC { get; private set; } public PMEntity PMD { get; private set; } public TMEntity TM { get; private set; } public LLEntity LLA { get; private set; } public LLEntity LLB { get; private set; } public EfemEntity EFEM { get; private set; } public VceEntity VCE { get; private set; } public VceEntity VCEA { get; private set; } public VceEntity VCEB { get; private set; } public SETMEntity seTM { get; private set; } public string Name { get; set; } public bool IsAutoMode { get { return fsm.State == (int)RtState.AutoRunning || fsm.State == (int)RtState.AutoIdle; } } public bool IsInit { get { return fsm.State == (int)RtState.Init; } } public bool IsIdle { get { return fsm.State == (int)RtState.Idle || fsm.State == (int)RtState.AutoIdle; } } public bool IsAlarm { get { return fsm.State == (int)RtState.Error; } } public bool IsPaused { get { return _AutoCycle.CycleState == RState.Paused; } } public bool IsEntityError { get { return (EFEM?.IsError ?? false) || (PMA?.IsError ?? false) || (PMB?.IsError ?? false) || (PMC?.IsError ?? false) || (PMD?.IsError ?? false); } } public bool IsRunning { get { return !IsInit && !IsAlarm && !IsIdle; } } public static bool IsATMMode { get { if (_isATMMode == -1) { _isATMMode = SC.GetValue("System.IsATMMode") ? 1 : 0; } return _isATMMode == 1; } } public SequenceLLInOutPath LLInOutPath => _AutoCycle.LLInOutPath; private TMCycle _TMCycle; private ICycle _AutoCycle; private ManualTransfer _manualTransfer; private ReturnAllWafer _returnWafer; private SETMCycle _seTMCycle; private SEManualTransfer _setransfer; private SEReturnWafer _sereturnWafer; private bool _isWaitUnload; private static int _isATMMode = -1; public RouteManager() { Name = "System"; if (ModuleHelper.IsInstalled(ModuleName.PMA)) PMA = new PMEntity(ModuleName.PMA); if (ModuleHelper.IsInstalled(ModuleName.PMB)) PMB = new PMEntity(ModuleName.PMB); if (ModuleHelper.IsInstalled(ModuleName.PMC)) PMC = new PMEntity(ModuleName.PMC); if (ModuleHelper.IsInstalled(ModuleName.PMD)) PMD = new PMEntity(ModuleName.PMD); if (ModuleHelper.IsInstalled(ModuleName.TM)) TM = new TMEntity(); if (ModuleHelper.IsInstalled(ModuleName.LLA)) LLA = new LLEntity(ModuleName.LLA); if (ModuleHelper.IsInstalled(ModuleName.LLB)) LLB = new LLEntity(ModuleName.LLB); if (ModuleHelper.IsInstalled(ModuleName.EFEM)) EFEM = new EfemEntity(); if (ModuleHelper.IsInstalled(ModuleName.VCE1)) { //临时加 后改为配置项 VCE = new VceEntity(ModuleName.VCE1); } if (ModuleHelper.IsInstalled(ModuleName.VCEA)) { //临时加 后改为配置项 VCEA = new VceEntity(ModuleName.VCEA); } if (ModuleHelper.IsInstalled(ModuleName.VCEB)) { //临时加 后改为配置项 VCEB = new VceEntity(ModuleName.VCEB); } if (ModuleHelper.IsInstalled(ModuleName.SETM)) { seTM = new SETMEntity(ModuleName.SETM) ; } else if (ModuleHelper.IsInstalled(ModuleName.DETM)) { seTM = new SETMEntity(ModuleName.DETM); } fsm = new StateMachine(Name, (int)RtState.Init, 200); SubscribeOperation(); SubscribeDataVariable(); } public bool Check(int msg, out string reason, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { reason = String.Format("{0} is in {1} state,can not do {2}", Name, 0, (MSG)msg); return false; } if (msg == (int)MSG.StartCycle) { if (!IsAutoMode) { reason = String.Format("can not do {0}, isn't auto mode.", msg.ToString()); return false; } } reason = ""; return true; } void SubscribeDataVariable() { DATA.Subscribe("Rt.Status", () => ((RtState)fsm.State).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe(ModuleName.System.ToString(), "AlarmEvent", EV.GetAlarmEvent, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("System.IsAutoMode", () => IsAutoMode, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("System.IsIdle", () => IsIdle || IsInit, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("System.IsAlarm", () => IsAlarm || IsEntityError, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("System.IsBusy", () => IsRunning, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("System.IsWaitUnload", () => _isWaitUnload && IsAutoMode, SubscriptionAttribute.FLAG.IgnoreSaveDB); //DATA.Subscribe("System.IsConnectedWithHost", () => Singleton.Instance., SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("EquipmentMode", () => IsAutoMode ? 0 : 1, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe("EquipmentStatus", () => { //"0 = Uninit //1 = Idle //2 = Running //3 = Error //4 = Pause //" if (IsInit) return 0; if (IsIdle) return 1; if (IsAlarm) return 3; if (IsPaused) return 4; return 2; }, SubscriptionAttribute.FLAG.IgnoreSaveDB); } void SubscribeOperation() { OP.Subscribe("CreateWafer", InvokeCreateWafer); OP.Subscribe("DeleteWafer", InvokeDeleteWafer); OP.Subscribe("System.Home", (cmd, args) => CheckToPostMessage((int)MSG.HOME, args)); OP.Subscribe("TMCycle.Start", (cmd, args) => CheckToPostMessage((int)MSG.TMCycle, args)); OP.Subscribe("TMCycle.Abort", (cmd, args) => CheckToPostMessage((int)MSG.StopCycle, args)); OP.Subscribe("System.StopSECycle", (cmd, args) => CheckToPostMessage((int)MSG.StopSECycle, args)); DATA.Subscribe("SYSTEM.FsmState", () => (((RtState)fsm.State).ToString())); DATA.Subscribe("TMCycle.CycleIndex", () => (_TMCycle?.CycleIndex)); OP.Subscribe("ReturnWafer", InvokeReturnWafer); OP.Subscribe("System.ReturnAllWafer", (string cmd, object[] args) => { if (seTM != null && (VCE != null || VCEA !=null || VCEB != null)) return CheckToPostMessage((int)MSG.SEReturnWafer, args); else return CheckToPostMessage((int)MSG.ReturnAllWafer, args[0], args[1], args[2], args[3]); }); OP.Subscribe("System.MoveWafer", (string cmd, object[] args) => { if (!Enum.TryParse((string)args[0], out ModuleName source)) { EV.PostWarningLog(Name, $"Parameter source {(string)args[0]} not valid"); return false; } if (!Enum.TryParse((string)args[2], out ModuleName destination)) { EV.PostWarningLog(Name, $"Parameter destination {(string)args[1]} not valid"); return false; } if (seTM != null && (VCE != null || VCEA != null || VCEB != null)) return CheckToPostMessage((int)MSG.SEMoveWafer, source, (int)args[1], destination, (int)args[3], args[4], args[5], args[6], args[7], (string)args[8]); else return CheckToPostMessage((int)MSG.MoveWafer, source, (int)args[1], destination, (int)args[3], args[4], args[5], args[6], args[7], (string)args[8]); }); OP.Subscribe("System.HomeAll", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.HOME); }); OP.Subscribe("System.Abort", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.ABORT); }); OP.Subscribe("System.Reset", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.RESET); }); OP.Subscribe("System.SetAutoMode", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.SetAutoMode); }); OP.Subscribe("System.SetManualMode", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.SetManualMode); }); OP.Subscribe("System.CreateJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.CreateJob, args[0]); }); OP.Subscribe("System.StartJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.StartJob, args[0]); }); OP.Subscribe("System.PauseJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.PauseJob, args[0]); }); OP.Subscribe("System.ResumeJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.ResumeJob, args[0]); }); OP.Subscribe("System.StopJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.StopJob, args[0]); }); OP.Subscribe("System.AbortJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.AbortJob, args[0]); }); OP.Subscribe("SE.AbortJob", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.AbortSEJob, args[0]); }); OP.Subscribe("LP1.Map", (string cmd, object[] args) => { if (IsAutoMode) { return CheckToPostMessage((int)MSG.Map, ModuleName.LP1.ToString()); } return EFEM.InvokeMap(ModuleName.LP1.ToString()) != (int)FSM_MSG.NONE; }); OP.Subscribe("LP2.Map", (string cmd, object[] args) => { if (IsAutoMode) { return CheckToPostMessage((int)MSG.Map, ModuleName.LP2.ToString()); } return EFEM.InvokeMap(ModuleName.LP2.ToString()) != (int)FSM_MSG.NONE; }); OP.Subscribe(RtOperation.SetConfig.ToString(), (name, args) => { string sc_key = args[0] as string; if (!string.IsNullOrWhiteSpace(sc_key) && args.Length > 1) { SC.SetItemValue(sc_key, args[1]); } return true; }); OP.Subscribe("System.ResetIdleCleanTime", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.ResetIdleCleanTime, args[0]); }); OP.Subscribe("System.ResetIdlePurgeTime", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.ResetIdlePurgeTime, args[0]); }); OP.Subscribe("System.SetWaferSize", (string cmd, object[] args) => { string module = (string)args[0]; string size = (string)args[1]; switch (size) { case "3": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS3); break; case "4": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS4); break; case "6": WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS6); break; default: EV.PostWarningLog("System", $"wafer size {size} not valid"); break; } return true; }); OP.Subscribe("System.CassetteLeave", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.CassetteLeave); }); OP.Subscribe("System.IsModuleInstalled", (string cmd, object[] args) => { return ModuleHelper.IsInstalled((ModuleName)args[0]); }); OP.Subscribe("System.SETMCycle", (cmd, args) => CheckToPostMessage((int)MSG.SETMCycle, args)); OP.Subscribe("System.CreateSEJob", (cmd, args) => CheckToPostMessage((int)MSG.CreateSEJob, args)); OP.Subscribe("System.StartSEJob", (cmd, args) => CheckToPostMessage((int)MSG.StartSEJob, args)); OP.Subscribe("System.ReturnAllSEWafer", (cmd, args) => CheckToPostMessage((int)MSG.SEReturnWafer, args)); OP.Subscribe("System.SEAbort", (cmd, args) => CheckToPostMessage((int)MSG.SEAbort, args)); } public bool CheckToPostMessage(int msg, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, $"System is in {(RtState)fsm.State} state,can not do {(MSG)msg}"); return false; } Running = true; fsm.PostMsg(msg, args); return true; } public bool InvokeAbort(object[] args) { return CheckToPostMessage((int)MSG.ABORT, args); } private bool InvokeCreateWafer(string arg1, object[] args) { ModuleName chamber = ModuleHelper.Converter(args[0].ToString()); int slot = (int)args[1]; WaferStatus state = WaferStatus.Normal; if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot)) { if (WaferManager.Instance.CheckHasWafer(chamber, slot)) { LOG.Write(eEvent.EV_ROUTER, "System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot)); } else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null) { LOG.Write(eEvent.EV_WAFER_CREATE, ModuleName.System, chamber.ToString(), (slot + 1).ToString(), state.ToString()); } } else { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString())); return false; } return true; } private bool InvokeDeleteWafer(string arg1, object[] args) { ModuleName chamber = ModuleHelper.Converter(args[0].ToString()); int slot = (int)args[1]; if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot)) { if (WaferManager.Instance.CheckHasWafer(chamber, slot)) { WaferManager.Instance.DeleteWafer(chamber, slot); EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDelete, chamber.ToString(), slot + 1); } else { LOG.Write(eEvent.EV_ROUTER, "System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1)); } } else { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString())); return false; } return true; } private bool InvokeReturnWafer(string arg1, object[] args) { ModuleName target = ModuleHelper.Converter(args[0].ToString()); int slot = (int)args[1]; if (seTM != null && (VCE != null || VCEA != null || VCEB != null)) { if (ModuleHelper.IsVCE(target)) { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Wafer already at vce {0} {1}, return operation is not valid", target.ToString(), slot + 1)); return false; } WaferInfo wafer = WaferManager.Instance.GetWafer(target, slot); if (wafer.IsEmpty) { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("No wafer at {0} {1}, return operation is not valid", target.ToString(), slot + 1)); return false; } return CheckToPostMessage((int)MSG.SEMoveWafer, target, slot, (ModuleName)wafer.OriginStation, wafer.OriginSlot, false, 0, false, 0, "Blade1"); } else { if (ModuleHelper.IsLoadPort(target)) { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Wafer already at LoadPort {0} {1}, return operation is not valid", target.ToString(), slot + 1)); return false; } if (!WaferManager.Instance.IsWaferSlotLocationValid(target, slot)) { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", target.ToString(), slot.ToString())); return false; } WaferInfo wafer = WaferManager.Instance.GetWafer(target, slot); if (wafer.IsEmpty) { LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("No wafer at {0} {1}, return operation is not valid", target.ToString(), slot + 1)); return false; } return CheckToPostMessage((int)MSG.MoveWafer, target, slot, (ModuleName)wafer.OriginStation, wafer.OriginSlot, false, 0, false, 0, "Blade1"); } } public PMEntity GetPM(ModuleName mod) { if (ModuleHelper.IsInstalled(mod)) { switch (mod) { case ModuleName.PMA: return PMA; case ModuleName.PMB: return PMB; case ModuleName.PMC: return PMC; case ModuleName.PMD: return PMD; } } return null; } public LLEntity GetLL(ModuleName mod) { if (ModuleHelper.IsInstalled(mod)) { switch (mod) { case ModuleName.LLA: return LLA; case ModuleName.LLB: return LLB; } } return null; } public VceEntity GetVCE(ModuleName mod) { if (ModuleHelper.IsInstalled(mod)) { switch (mod) { case ModuleName.VCE1: return VCE; case ModuleName.VCEA: return VCEA; case ModuleName.VCEB: return VCEB; } } return null; } public TMEntity GetTM() { return TM; } protected override bool Init() { PMA?.Initialize(); PMB?.Initialize(); PMC?.Initialize(); PMD?.Initialize(); TM?.Initialize(); LLA?.Initialize(); LLB?.Initialize(); EFEM?.Initialize(); VCE?.Initialize(); VCEA?.Initialize(); VCEB?.Initialize(); seTM?.Initialize(); _TMCycle = new TMCycle(); //_AutoCycle = new AutoCycle(); _AutoCycle = new SystemDispatcher(); _manualTransfer = new ManualTransfer(); _returnWafer = new ReturnAllWafer(_manualTransfer); _seTMCycle = new SETMCycle(ModuleName.SETM); _setransfer = new SEManualTransfer(); _sereturnWafer = new SEReturnWafer(_setransfer); BuildTransitionTable(); return true; } private void BuildTransitionTable() { //Init sequence Transition(RtState.Init, MSG.HOME, FsmStartHome, RtState.Initializing); Transition(RtState.Idle, MSG.HOME, FsmStartHome, RtState.Initializing); Transition(RtState.Error, MSG.HOME, FsmStartHome, RtState.Initializing); EnterExitTransition(RtState.AutoRunning, FsmEnterAutoRunning, FSM_MSG.NONE, FsmExitAutoTransfer); EnterExitTransition(RtState.Transfer, null, FSM_MSG.NONE, FsmExitTransfer); EnterExitTransition(RtState.ReturnWafer, null, FSM_MSG.NONE, FsmExitReturnWafer); AnyStateTransition(MSG.ERROR, FsmError, RtState.Error); Transition(RtState.Idle, FSM_MSG.TIMER, FsmMonitor, RtState.Idle); Transition(RtState.Init, FSM_MSG.TIMER, FsmMonitor, RtState.Init); Transition(RtState.Initializing, FSM_MSG.TIMER, FsmMonitorHome, RtState.Idle); Transition(RtState.Initializing, MSG.ERROR, FsmError, RtState.Error); Transition(RtState.Initializing, MSG.ABORT, FsmAbort, RtState.Init); // TM Cycle Transition(RtState.Idle, MSG.TMCycle, FsmStartTMCycle, RtState.TMCycle); Transition(RtState.TMCycle, FSM_MSG.TIMER, FsmMonitorTMCycle, RtState.Idle); Transition(RtState.TMCycle, MSG.StopCycle, FsmStopTMCycle, RtState.Idle); //Auto/manual Transition(RtState.Idle, MSG.SetAutoMode, FsmStartAutoTransfer, RtState.AutoIdle); Transition(RtState.AutoRunning, FSM_MSG.TIMER, FsmAutoTransfer, RtState.AutoIdle); Transition(RtState.AutoRunning, MSG.ABORT, FsmAbortAutoTransfer, RtState.Idle); //Transition(RtState.AutoRunning, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle); Transition(RtState.AutoRunning, MSG.JobDone, FsmJobDone, RtState.AutoIdle); //Transition(RtState.AutoRunning, MSG.CassetteLeave, fCassetteLeave, RtState.AutoRunning); //For unload light control off afer job done Transition(RtState.AutoRunning, MSG.CreateJob, FsmCreateJob, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.StartJob, FsmStartJob, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.PauseJob, FsmPauseJob, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.ResumeJob, FsmResumeJob, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.StopJob, FsmStopJob, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.AbortJob, FsmAbortJob, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.MoveWafer, FsmAutoReturnWafer, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.Map, FsmMap, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.ResetIdleCleanTime, FsmResetIdleCleanTime, RtState.AutoRunning); Transition(RtState.AutoRunning, MSG.ResetIdlePurgeTime, FsmResetIdlePurgeTime, RtState.AutoRunning); Transition(RtState.AutoIdle, FSM_MSG.TIMER, FsmMonitorAutoIdle, RtState.AutoIdle); Transition(RtState.AutoIdle, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle); Transition(RtState.AutoIdle, MSG.CreateJob, FsmCreateJob, RtState.AutoIdle); Transition(RtState.AutoIdle, MSG.StartJob, FsmStartJob, RtState.AutoRunning); Transition(RtState.AutoIdle, MSG.PauseJob, FsmPauseJob, RtState.AutoIdle); Transition(RtState.AutoIdle, MSG.ResumeJob, FsmResumeJob, RtState.AutoIdle); Transition(RtState.AutoIdle, MSG.StopJob, FsmStopJob, RtState.AutoIdle); Transition(RtState.AutoIdle, MSG.AbortJob, FsmAbortJob, RtState.AutoIdle); Transition(RtState.AutoIdle, MSG.Map, FsmMap, RtState.AutoIdle); //Transfer Transition(RtState.Idle, MSG.MoveWafer, FsmStartTransfer, RtState.Transfer); Transition(RtState.Transfer, FSM_MSG.TIMER, FsmMonitorTransfer, RtState.Idle); Transition(RtState.Transfer, MSG.ABORT, FsmAbort, RtState.Idle); //Return Wafer Transition(RtState.Idle, MSG.ReturnAllWafer, FsmStartReturnWafer, RtState.ReturnWafer); Transition(RtState.ReturnWafer, FSM_MSG.TIMER, FsmMonitorReturnWafer, RtState.Idle); Transition(RtState.ReturnWafer, MSG.ABORT, FsmAbort, RtState.Idle); // SETM Cycle Transition(RtState.Idle, MSG.SETMCycle, FsmStartSETMCycle, RtState.SETMCycle); Transition(RtState.SETMCycle, FSM_MSG.TIMER, FsmMonitorSETMCycle, RtState.Idle); Transition(RtState.SETMCycle, MSG.SEAbort, SEAbort, RtState.Idle); Transition(RtState.SETMCycle, MSG.AbortSEJob, SEAbortJob, RtState.Idle); // SETM CreateCycle Transition(RtState.Idle, MSG.CreateSEJob, FsmStartCreateSEJob, RtState.Idle); // SETM StartCycle Transition(RtState.Idle, MSG.StartSEJob, FsmStartSEJob, RtState.SERunning); Transition(RtState.SERunning, FSM_MSG.TIMER, FsmSEJobMonitor, RtState.Idle); Transition(RtState.SERunning, MSG.SEAbort, SEAbort, RtState.Idle); Transition(RtState.SERunning, MSG.AbortSEJob, SEAbortJob, RtState.Idle); Transition(RtState.Idle, MSG.AbortSEJob, SEAbortJob, RtState.Idle); // SE Transfer Transition(RtState.Idle, MSG.SEMoveWafer, FsmStartSEMoveWafer, RtState.SETransfer); Transition(RtState.SETransfer, FSM_MSG.TIMER, FsmMonitorSEMoveWafer, RtState.Idle); Transition(RtState.SETransfer, MSG.SEAbort, SEAbort, RtState.Idle); // SE ReturnWafer Transition(RtState.Idle, MSG.SEReturnWafer, FsmStartSEReturnWafer, RtState.SEReturnWafer); Transition(RtState.SEReturnWafer, FSM_MSG.TIMER, FsmMonitorSEReturnWafer, RtState.Idle); Transition(RtState.SEReturnWafer, MSG.SEAbort, SEAbort, RtState.Idle); } private bool FsmMonitor(object[] objs) { _debugRoutine(); return true; } private bool FsmStartHome(object[] objs) { TM?.Invoke("Home"); EFEM?.Invoke("Home"); seTM?.Invoke("Home"); VCE?.Invoke("Home"); VCEA?.Invoke("Home"); VCEB?.Invoke("Home"); foreach (var mod in ModuleHelper.InstalledModules) { if (ModuleHelper.IsPm(mod)) { if (GetPM(mod).IsInclude) { GetPM(mod).Invoke("Home"); } } else if (ModuleHelper.IsLoadLock(mod)) { if (GetLL(mod).IsInclude) { GetLL(mod).Invoke("Home"); } } } return true; } private bool FsmMonitorHome(object[] objs) { ModuleName notReadyModule = ModuleName.System; foreach (var mod in ModuleHelper.InstalledModules) { if ((ModuleHelper.IsPm(mod) && GetPM(mod).IsInclude && !GetPM(mod).IsIdle) || (ModuleHelper.IsLoadLock(mod) && GetLL(mod).IsInclude && !GetLL(mod).IsIdle) || (ModuleHelper.IsTM(mod) && !GetTM().IsIdle) || (ModuleHelper.IsVCE(mod) && !GetVCE(mod).IsIdle) || (ModuleHelper.IsEFEM(mod) && !EFEM.IsIdle) || (ModuleHelper.isSETM(mod) && !seTM.IsIdle)) { notReadyModule = mod; break; } } if (notReadyModule != ModuleName.System) { if (fsm.ElapsedTime > 100 * 1000) { LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"{notReadyModule} home timeout"); PostMsg(MSG.ERROR); return true; } else return false; } return true; } private bool FsmEnterAutoRunning(object[] objs) { return true; } private bool FsmExitAutoTransfer(object[] objs) { _AutoCycle.Clear(); return true; } private bool FsmExitTransfer(object[] objs) { _manualTransfer.Clear(); return true; } private bool FsmExitReturnWafer(object[] objs) { _returnWafer.Clear(); return true; } private bool FsmError(object[] objs) { return true; } private bool FsmAbort(object[] objs) { _manualTransfer.Clear(); _returnWafer.Clear(); _AutoCycle.Clear(); return true; } private bool FsmStartTMCycle(object[] objs) { return _TMCycle.Start(objs) == RState.Running; } private bool FsmMonitorTMCycle(object[] objs) { RState ret = _TMCycle.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.ERROR); return false; } return ret == RState.End; } private bool FsmStopTMCycle(object[] objs) { _TMCycle.Abort(); return true; } private bool FsmStartAutoTransfer(object[] objs) { return _AutoCycle.Start(objs) == RState.Running; } private bool FsmAutoTransfer(object[] objs) { RState ret = _AutoCycle.Monitor(); if (ret == RState.Failed) { if (!CheckToPostMessage((int)MSG.ERROR)) return false; } if (_AutoCycle.CheckJobJustDone(out string jobInfo)) { EV.PostPopDialogMessage(EventLevel.InformationNoDelay, "Job complete", jobInfo); } if (_AutoCycle.CheckAllJobDone()) { if (!CheckToPostMessage((int)MSG.JobDone)) return false; } //_isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone"); return ret == RState.End; } private bool FsmAbortAutoTransfer(object[] objs) { _AutoCycle.Clear(); return true; } private bool FsmJobDone(object[] objs) { _isWaitUnload = true; return true; } private bool FsmCreateJob(object[] objs) { Dictionary obj = (Dictionary)objs[0]; var moduleName = (ModuleName)Enum.Parse(typeof(ModuleName), obj["Module"].ToString()); if (EFEM.EfemDevice[moduleName].IsLoaded) { return _AutoCycle.CreateJob(obj, out var reason); } else { LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, $"{obj["Module"]} is unload,can not create job"); return false; } } private bool FsmStartJob(object[] objs) { _AutoCycle.StartJob((string)objs[0], out var reason); return true; } private bool FsmPauseJob(object[] objs) { _AutoCycle.PauseJob((string)objs[0], out var reason); return true; } private bool FsmResumeJob(object[] objs) { _AutoCycle.ResumeJob((string)objs[0], out var reason); return true; } private bool FsmStopJob(object[] objs) { _AutoCycle.StopJob((string)objs[0], out var reason); return true; } private bool FsmAbortJob(object[] objs) { _AutoCycle.AbortJob((string)objs[0], out var reason); return true; } private bool FsmStartTransfer(object[] objs) { return _manualTransfer.Start(objs) == RState.Running; } private bool FsmMonitorTransfer(object[] objs) { RState ret = _manualTransfer.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.ERROR); return false; } return ret == RState.End; } private bool FsmStartReturnWafer(object[] objs) { //return _returnWafer.Start(objs) == RState.Running; return _AutoCycle.CheckManualReturnWafer() == RState.Running; } private bool FsmMonitorReturnWafer(object[] objs) { //RState ret = _returnWafer.Monitor(); RState ret = _AutoCycle.ReturnAllWafers(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.ERROR); return false; } return ret == RState.End; } private bool FsmMap(object[] objs) { return true; } private bool FsmResetIdleCleanTime(object[] objs) { return true; } private bool FsmResetIdlePurgeTime(object[] objs) { return true; } private bool FsmAutoReturnWafer(object[] objs) { return _AutoCycle.ManualReturnWafer(objs); } private bool FsmMonitorAutoIdle(object[] objs) { RState ret = _AutoCycle.Monitor(); //if (_AutoCycle.CheckAllJobDone()) //{ // if (!CheckToPostMessage((int)MSG.JobDone)) // return false; //} //_isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone"); _debugRoutine(); return ret == RState.End; } private bool FsmStartSetManualMode(object[] objs) { if (_AutoCycle.HasJobRunning) { LOG.Write(eEvent.WARN_ROUTER, "System", "Can not change to manual mode, abort running job first"); return false; } return true; } private void _debugRoutine() { int flag = 0; // Test Home routine if (flag == 1) { PostMsg(MSG.HOME); } else if (flag == 2) { PostMsg(MSG.TMCycle); } else if (flag == 3) { PostMsg(MSG.SetAutoMode); } else if (flag == 4) { PostMsg(MSG.ReturnAllWafer); } else if (flag == 5) { PostMsg(MSG.StartJob, "CJ_Local_LP1"); } } private bool FsmStartSETMCycle(object[] objs) { return _seTMCycle.Start(objs) == RState.Running; } private bool FsmMonitorSETMCycle(object[] objs) { RState ret = _seTMCycle.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.ERROR); return false; } return ret == RState.End; } private bool FsmStopSETMCycle(object[] objs) { _seTMCycle.Abort(); return true; } private bool FsmStartCreateSEJob(object[] objs) { _seTMCycle.CreateJob((Dictionary)objs[0]); return true; } private bool FsmStartSEJob(object[] objs) { return _seTMCycle.StartJob(objs[0].ToString()) == RState.Running; } private bool FsmSEJobMonitor(object[] objs) { RState ret = _seTMCycle.Monitor(); return ret == RState.End; } private bool FsmStartSEMoveWafer(object[] objs) { return _setransfer.Start(objs) == RState.Running; } private bool FsmMonitorSEMoveWafer(object[] objs) { RState ret = _setransfer.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.ERROR); return false; } return ret == RState.End; } private bool FsmStartSEReturnWafer(object[] objs) { return _sereturnWafer.Start(objs) == RState.Running; } private bool FsmMonitorSEReturnWafer(object[] objs) { RState ret = _sereturnWafer.Monitor(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.ERROR); return false; } return ret == RState.End; } private bool SEAbortJob(object[] objs) { _seTMCycle.AbortJob((string)objs[0], out var reason); return true; } private bool SEAbort(object[] objs) { //_seTMCycle.Abort(); _setransfer.Abort(); _sereturnWafer.Abort(); seTM.CheckToPostMessage((int)SETMEntity.MSG.Abort); return true; } #region Fa接口 /// /// 接口指令 /// /// /// /// /// public bool ExcuteCommand(string command, object[] paras, out string reason) { reason = ""; switch (command) { case "PP-SELECT": return FaCreateJob(paras, out reason); case "StartJob": return FaStartJob(paras[0].ToString(), out reason); case "StopJob": return FaStopJob(paras[0].ToString(), out reason); case "AbortJob": return FaAbortob(paras[0].ToString(), out reason); case "PauseJob": return FaPauseJob(paras[0].ToString(), out reason); case "ResumeJob": return FaResumeJob(paras[0].ToString(), out reason); case "Load": return FaLoad(paras[0].ToString(), out reason); case "Unload": return FaUnLoad(paras[0].ToString(), out reason); case "ReadID": return FaReadId(paras[0].ToString(), out reason); } return true; } /// /// Fa创建任务 /// /// /// /// private bool FaCreateJob(object[] paras, out string reason) { if (!CheckAuto()) { reason = "System is not in Auto,cannot create job"; return false; } else { Dictionary createParams = new Dictionary(); createParams["Module"] = $"LP{paras[0]}"; createParams["JobId"] = paras[1].ToString(); createParams["SlotSequence"] = (string[])paras[3]; createParams["AutoStart"] = true; if (paras.Length >= 5) { createParams["PreCleanRecipeName"] = paras[4].ToString(); } if (paras.Length >= 6) { createParams["PostCleabRecipeName"] = paras[5].ToString(); } return _AutoCycle.CreateJob(createParams, out reason); } } /// /// Fa启动任务 /// /// /// /// private bool FaStartJob(string jobName, out string reason) { return _AutoCycle.StartJob(jobName, out reason); } /// /// Fa停止任务 /// /// /// /// private bool FaStopJob(string jobName, out string reason) { return _AutoCycle.StopJob(jobName, out reason); } /// /// Fa中止任务 /// /// /// /// private bool FaAbortob(string jobName, out string reason) { return _AutoCycle.AbortJob(jobName, out reason); } /// /// Fa暂停任务 /// /// /// /// private bool FaPauseJob(string jobName, out string reason) { return _AutoCycle.PauseJob(jobName, out reason); } /// /// Fa恢复任务 /// /// /// /// private bool FaResumeJob(string jobName, out string reason) { return _AutoCycle.ResumeJob(jobName, out reason); } /// /// Fa Load /// /// /// private bool FaLoad(string lp, out string reason) { reason = ""; Loadport loadport = FaGetLoadPort(lp, out reason); if (loadport != null) { loadport.Load(); return true; } else { return false; } } /// /// 获取LoadPort对象 /// /// /// /// private Loadport FaGetLoadPort(string lp, out string reason) { reason = ""; if (int.TryParse(lp, out var lpValue)) { LoadPortModule loadPortModule = EFEM.GetLoadportModule(lpValue); if (loadPortModule != null) { if (loadPortModule.LPDevice.HasCassette) { return loadPortModule.LPDevice; } else { reason = $"LP{lpValue} not found carrier, can not load"; return null; } } else { reason = $"LP{lp} is null"; return null; } } else { reason = $"{lp} is invalid data"; return null; } } /// /// 读取Id /// /// /// private bool FaReadId(string lp, out string reason) { reason = ""; Loadport loadport = FaGetLoadPort(lp, out reason); if (loadport != null) { loadport.ReadCarrierID(); return true; } else { return false; } } /// /// Fa Unload /// /// /// private bool FaUnLoad(string lp, out string reason) { reason = ""; Loadport loadport = FaGetLoadPort(lp, out reason); if (loadport != null) { loadport.Unload(); return true; } else { return false; } } /// /// 获取所有Sequence /// /// public string[] GetSequenceList() { return RecipeFileManager.Instance.GetSequenceNameList().ToArray(); } public string GetSequenceBody(string ppid) { return RecipeFileManager.Instance.GetSequence(ppid, false); } public List GetFormatedSequence(string ppid) { return null; } public bool deleteSequence(string ppid) { return true; } public bool UpdateSequence(string ppid, string body) { return true; } public void ShowTerminalMessage(string message) { } public bool CreateProcessJob(string processJobId, string sequenceName, string carrierId, out string reason) { reason = ""; return true; } public void UpdateProcessJobCarrierSlot(string processJobId, string moduleName, List slots) { } public void CreateControlJob(string controlJobId, string carrierId, List processJobs) { } public bool CheckCreateControlJobCondition(List modules, out string reason) { reason = ""; return true; } public bool StartControlJob(string controlJob) { return true; } public bool StopControlJob(string controlJob) { return true; } public bool AbortControlJob(string controlJob) { return true; } public bool PauseControlJob(string controlJob) { return true; } public bool ResumeControlJob(string controlJob) { return true; } public bool CheckAuto() { return fsm.State == (int)RtState.AutoIdle; } public void UpdateControlJobModule(string controlJobId, string moduleName) { } #endregion } }