using System; 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.Equipment; using MECF.Framework.Common.SubstrateTrackings; using Venus_Core; using Venus_RT.Modules.PMs; using Aitex.Core.RT.Log; namespace Venus_RT.Modules { class RouteManager : Entity, IEntity { public enum MSG { MoveWafer, ReturnWafer, HomeUnit, PauseAuto, ResumeAuto, Stop, StartCycle, 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, } 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 string Name { get; set; } private TMCycle _TMCycle; 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); fsm = new StateMachine(Name, (int)RtState.Init, 200); SubscribeOperation(); } 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 SubscribeOperation() { OP.Subscribe("CreateWafer", InvokeCreateWafer); OP.Subscribe("DeleteWafer", InvokeDeleteWafer); } 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)) { EV.PostInfoLog("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) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferCreate, chamber.ToString(), slot + 1, state.ToString()); } } else { EV.PostWarningLog("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 { EV.PostInfoLog("System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1)); } } else { EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString())); return false; } return true; } 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; } protected override bool Init() { PMA?.Initialize(); PMB?.Initialize(); TM?.Initialize(); LLA?.Initialize(); LLB?.Initialize(); _TMCycle = new TMCycle(); BuildTransitionTable(); return true; } private void BuildTransitionTable() { fsm = new StateMachine(ModuleName.System.ToString(), (int)RtState.Init, 50); //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.Initializing, fStartInit, FSM_MSG.NONE, null); /// 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.ABORT, FsmAbort, 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"); return true; } private bool FsmMonitorHome(object[] objs) { bool CheckHomed(string name, bool bValid, bool bDone) { if (bValid && !bDone) { if (fsm.ElapsedTime > 20 * 1000) { LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"{name} home timeout"); PostMsg(MSG.ERROR); return true; } else return false; } return true; } return CheckHomed("PMA", PMA != null, PMA != null&&PMA.IsIdle) && CheckHomed("PMB", PMB != null, PMB != null&&PMA.IsIdle) && CheckHomed("PMC", PMC != null, PMC != null&&PMC.IsIdle) && CheckHomed("PMD", PMD != null, PMD != null&&PMD.IsIdle) && CheckHomed("LLA", LLA != null, LLA != null&&LLA.IsIdle) && CheckHomed("LLB", LLB != null, LLB != null&&LLB.IsIdle) && CheckHomed("TM", TM != null, TM != null&&TM.IsIdle); } private bool FsmError(object[] objs) { return true; } private bool FsmAbort(object[] objs) { return true; } private bool FsmStartTMCycle(object[] objs) { return _TMCycle.Start() == 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 void _debugRoutine() { int flag = 0; // Test Home routine if (flag == 1) { PostMsg(MSG.HOME); } else if (flag == 2) { PostMsg(MSG.TMCycle); } } } }