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.HostWrapper; using Venus_RT.Modules.VCE; using Venus_RT.Devices.PreAligner; using Venus_RT.Modules.TM.VenusEntity; namespace Venus_RT.Modules { class RouteManager : Entity, IEntity { 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 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 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 AutoCycle _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.SETM)) { seTM = new SETMEntity(); } 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.IsConnected, 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; 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) 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) 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("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; } 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) { 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)) { return VCE; } 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(); seTM?.Initialize(); _TMCycle = new TMCycle(); _AutoCycle = new AutoCycle(); _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.Idle); 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); // 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); // 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) { PMA?.Invoke("Home"); PMB?.Invoke("Home"); PMC?.Invoke("Home"); PMD?.Invoke("Home"); TM?.Invoke("Home"); LLA?.Invoke("Home"); LLB?.Invoke("Home"); EFEM?.Invoke("Home"); seTM?.Invoke("Home"); VCE?.Invoke("Home"); return true; } private bool FsmMonitorHome(object[] objs) { bool CheckHomed(string name, bool bValid, bool bDone) { if (bValid && !bDone) { if (fsm.ElapsedTime > 100 * 1000) { LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"{name} home timeout"); PostMsg(MSG.ERROR); return true; } else return false; } return true; } return CheckHomed("PMA", ModuleHelper.IsInstalled(ModuleName.PMA) && PMA != null, ModuleHelper.IsInstalled(ModuleName.PMA) && PMA != null&&PMA.IsIdle) && CheckHomed("PMB", ModuleHelper.IsInstalled(ModuleName.PMB) && PMB != null, ModuleHelper.IsInstalled(ModuleName.PMB) && PMB != null&&PMB.IsIdle) && CheckHomed("PMC", ModuleHelper.IsInstalled(ModuleName.PMC) && PMC != null, ModuleHelper.IsInstalled(ModuleName.PMC) && PMC != null&&PMC.IsIdle) && CheckHomed("PMD", ModuleHelper.IsInstalled(ModuleName.PMD) && PMD != null, ModuleHelper.IsInstalled(ModuleName.PMD) && PMD != null&&PMD.IsIdle) && CheckHomed("LLA", ModuleHelper.IsInstalled(ModuleName.LLA) && LLA != null, ModuleHelper.IsInstalled(ModuleName.LLA) && LLA != null&&LLA.IsIdle) && CheckHomed("LLB", ModuleHelper.IsInstalled(ModuleName.LLB) && LLB != null, ModuleHelper.IsInstalled(ModuleName.LLB) && LLB != null&&LLB.IsIdle) && CheckHomed("TM", ModuleHelper.IsInstalled(ModuleName.TM) && TM != null, ModuleHelper.IsInstalled(ModuleName.TM) && TM != null&&TM.IsIdle) && CheckHomed("EFEM", ModuleHelper.IsInstalled(ModuleName.EFEM) && EFEM != null, ModuleHelper.IsInstalled(ModuleName.EFEM) && EFEM != null && EFEM.IsIdle) && CheckHomed("SETM", ModuleHelper.IsInstalled(ModuleName.SETM) && seTM != null, ModuleHelper.IsInstalled(ModuleName.SETM) && seTM != null && seTM.IsIdle) && CheckHomed("VCE1", ModuleHelper.IsInstalled(ModuleName.VCE1) && VCE != null, ModuleHelper.IsInstalled(ModuleName.VCE1) && VCE != null && VCE.IsIdle); } 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) { _AutoCycle.CreateJob((Dictionary)objs[0]); return true; } private bool FsmStartJob(object[] objs) { _AutoCycle.StartJob((string)objs[0]); return true; } private bool FsmPauseJob(object[] objs) { _AutoCycle.PauseJob((string)objs[0]); return true; } private bool FsmResumeJob(object[] objs) { _AutoCycle.ResumeJob((string)objs[0]); return true; } private bool FsmStopJob(object[] objs) { _AutoCycle.StopJob((string)objs[0]); return true; } private bool FsmAbortJob(object[] objs) { _AutoCycle.AbortJob((string)objs[0]); 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 SEAbort(object[] objs) { _seTMCycle.Abort(); _setransfer.Abort(); _sereturnWafer.Abort(); seTM.CheckToPostMessage((int)SETMEntity.MSG.Abort); return true; } } }