using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Core.Utilities; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.ModuleLibrary.VceModules; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using Venus_Core; using Venus_RT.Devices; using Venus_RT.Devices.SMIF; using Venus_RT.Devices.VCE; using Venus_RT.Modules.PMs; using Venus_RT.Modules.TM; using Venus_RT.Modules.TM.VenusEntity; namespace Venus_RT.Modules.VCE { #region 状态和消息 public enum VceMSG { Home, Error, DoorOpen, DoorClose, Map, ReadMap, Load, UnLoad, LoadPrepare, LoadWithSMIF, UnLoadWithSMIF, Reset, Goto, GotoLP, SafeLoad, SafeUnload, Pump, Vent, Abort, None, ClearError } #endregion public class VceEntity : Entity, IEntity, IModuleEntity { private ModuleName _modulename; private readonly VceModuleBase _vce; private readonly ISMIF _smif; private bool _CassetteArrive; public bool IsIdle => fsm.State == (int)VceSTATE.Idle; public bool IsInit => fsm.State == (int)VceSTATE.Init || fsm.State == (int)VceSTATE.Unknown; public bool IsBusy => !IsInit && !IsError && !IsIdle; public bool IsError => fsm.State == (int)VceSTATE.Error; public bool VCEOutDoorClosed => !_vce.OutDoorIsOpen; public bool CassetteArrive => _CassetteArrive; public int CurrentSlot => currentSlot; private int currentSlot; private int targetSlot; private LoadRoutine _loadRoutine; private LoadPrepareRoutine _prepareRoutine; private UnloadRoutine _unloadRoutine; private LoadWithSMIFRoutine _loadwithSMIFRoutine; private UnloadWithSMIFRoutine _unloadwithSMIFRoutine; private readonly SEMFPumpRoutine _pumpRoutine; private readonly SEMFVentRoutine _ventRoutine; public VceEntity(ModuleName moduleName) { currentSlot = 0; _modulename = moduleName; _vce = new HongHuVce(25, _modulename); _smif = new FortrendPLUS500(_modulename); _loadRoutine = new LoadRoutine(_modulename, _vce); _prepareRoutine = new LoadPrepareRoutine(_modulename, _vce); _unloadRoutine = new UnloadRoutine(_modulename, _vce); _loadwithSMIFRoutine = new LoadWithSMIFRoutine(_modulename, _vce, _smif); _unloadwithSMIFRoutine = new UnloadWithSMIFRoutine(_modulename, _vce, _smif); _pumpRoutine = new SEMFPumpRoutine(DEVICE.GetDevice("SETM"), _modulename); _ventRoutine = new SEMFVentRoutine(DEVICE.GetDevice("SETM"), _modulename); InitFsmMap(); } protected override bool Init() { DATA.Subscribe($"{_modulename}.VCEOutDoorClosed", () => !VCEOutDoorClosed); DATA.Subscribe($"{_modulename}.CurrentSlot", () => currentSlot); DATA.Subscribe($"{_modulename}.FsmState", () => ((VceSTATE)fsm.State).ToString()); DATA.Subscribe($"{_modulename}.CassetteArrive", () => CassetteArrive); //DATA.Subscribe($"{_modulename}.IsRunning", () => IsIdle); OP.Subscribe($"{_modulename}.HOME", (cmd, args) => { PostMsg(VceMSG.Home); return true; }); OP.Subscribe($"{_modulename}.DoorOpen", (cmd, args) => { PostMsg(VceMSG.DoorOpen); return true; }); OP.Subscribe($"{_modulename}.DoorClose", (cmd, args) => { PostMsg(VceMSG.DoorClose); return true; }); OP.Subscribe($"{_modulename}.Map", (cmd, args) => { PostMsg(VceMSG.Map); return true; }); OP.Subscribe($"{_modulename}.ReadMap", (cmd, args) => { PostMsg(VceMSG.ReadMap); return true; }); OP.Subscribe($"{_modulename}.Load", (cmd, args) => { PostMsg(VceMSG.Load); return true; }); OP.Subscribe($"{_modulename}.UnLoad", (cmd, args) => { PostMsg(VceMSG.UnLoad); return true; }); OP.Subscribe($"{_modulename}.Reset", (cmd, args) => { PostMsg(VceMSG.Reset); return true; }); OP.Subscribe($"{_modulename}.Goto", (cmd, args) => { PostMsg(VceMSG.Goto, args[0]); return true; }); OP.Subscribe($"{_modulename}.GotoLP", (cmd, args) => { PostMsg(VceMSG.GotoLP); return true; }); OP.Subscribe($"{_modulename}.Abort", (cmd, args) => { PostMsg(VceMSG.Abort); return true; }); OP.Subscribe($"{_modulename}.PumpDown", (cmd, args) => { PostMsg(VceMSG.Pump); return true; }); OP.Subscribe($"{_modulename}.Vent", (cmd, args) => { PostMsg(VceMSG.Vent); return true; }); OP.Subscribe($"{_modulename}.ClearError", (cmd, args) => { PostMsg(VceMSG.ClearError); return true; }); OP.Subscribe($"{_modulename}.LoadPrepare", (cmd, args) => { PostMsg(VceMSG.LoadPrepare); return true; }); OP.Subscribe($"{_modulename}.SafeLoad", (cmd, args) => { PostMsg(VceMSG.SafeLoad); return true; }); OP.Subscribe($"{_modulename}.SafeUnload", (cmd, args) => { PostMsg(VceMSG.SafeUnload); return true; }); OP.Subscribe($"{_modulename}.LoadWithSMIF", (cmd, args) => { PostMsg(VceMSG.LoadWithSMIF); return true; }); OP.Subscribe($"{_modulename}.UnLoadWithSMIF", (cmd, args) => { PostMsg(VceMSG.UnLoadWithSMIF); return true; }); return true; } /// /// 定义状态机的迁移表 /// private void InitFsmMap() { fsm = new StateMachine(_modulename.ToString(), (int)VceSTATE.Init, 50); fsm.EnableRepeatedMsg(true); AnyStateTransition(VceMSG.Error, fnError, VceSTATE.Error); AnyStateTransition(VceMSG.Abort, fnAbort, VceSTATE.Idle); AnyStateTransition(VceMSG.Home, fnStartHome, VceSTATE.Homing); //HOME init->homing idle->homing Transition(VceSTATE.Init, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Idle, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Error, VceMSG.Home, fnStartHome, VceSTATE.Homing); Transition(VceSTATE.Homing, FSM_MSG.TIMER, fnHomeTimeout, VceSTATE.Idle); //clear Error Transition(VceSTATE.Error, VceMSG.ClearError, fnStartClearError,VceSTATE.ClearError); Transition(VceSTATE.ClearError, FSM_MSG.TIMER, fnClearErrorTimeout, VceSTATE.Idle); //Open Door 开门 Transition(VceSTATE.Idle, VceMSG.DoorOpen, fnStartOpenDoor, VceSTATE.DoorOpenning); Transition(VceSTATE.DoorOpenning, FSM_MSG.TIMER, fnOpenDoorTimeout, VceSTATE.Idle); //Close Door 关门 Transition(VceSTATE.Idle, VceMSG.DoorClose, fnStartCloseDoor, VceSTATE.DoorClosing); Transition(VceSTATE.DoorClosing, FSM_MSG.TIMER, fnCloseDoorTimeout, VceSTATE.Idle); //Map 扫片 Transition(VceSTATE.Idle, VceMSG.Map, fnStartMapping, VceSTATE.Mapping); Transition(VceSTATE.Mapping, FSM_MSG.TIMER, fnMappingTimeout, VceSTATE.Idle); //Load 取cassette Transition(VceSTATE.Idle, VceMSG.Load, fnStartLoading, VceSTATE.Loading); Transition(VceSTATE.Loading, FSM_MSG.TIMER, fnLoadingTimeout, VceSTATE.Idle); //UnLoad 放cassette Transition(VceSTATE.Idle, VceMSG.UnLoad, fnStartUnLoading, VceSTATE.UnLoading); Transition(VceSTATE.UnLoading, FSM_MSG.TIMER, fnUnLoadingTimeout, VceSTATE.Idle); //Goto 指定槽对准窗口 Transition(VceSTATE.Idle, VceMSG.Goto, fnStartGoto, VceSTATE.Goting); Transition(VceSTATE.Goting, FSM_MSG.TIMER, fnGotingTimeout, VceSTATE.Idle); //ReadMap Transition(VceSTATE.Idle, VceMSG.ReadMap, fnStartReadingMap, VceSTATE.ReadingMap); Transition(VceSTATE.ReadingMap, FSM_MSG.TIMER, fnReadingMapTimeout, VceSTATE.Idle); //Load Prepare Transition(VceSTATE.Idle, VceMSG.LoadPrepare, fnStartLoadPrepare, VceSTATE.LoadPreparing); Transition(VceSTATE.LoadPreparing, FSM_MSG.TIMER, fnLoadingPrepareTimeout, VceSTATE.Idle); //Safe Load Transition(VceSTATE.Idle, VceMSG.SafeLoad, fnStartSafeLoad, VceSTATE.SafeLoading); Transition(VceSTATE.SafeLoading, FSM_MSG.TIMER, fnSafeLoadTimeout, VceSTATE.Idle); //LoadWithSMIF => LoadPrepare & SMIF Load & Load Transition(VceSTATE.Idle, VceMSG.LoadWithSMIF, fnStartLoadWithSMIF, VceSTATE.LoadingWithSMIF); Transition(VceSTATE.LoadingWithSMIF, FSM_MSG.TIMER, fnLoadWithSMIFTimeout, VceSTATE.Idle); //Safe UnLoad Transition(VceSTATE.Idle, VceMSG.SafeUnload, fnStartSafeUnLoad, VceSTATE.SafeUnloading); Transition(VceSTATE.SafeUnloading, FSM_MSG.TIMER, fnSafeUnLoadTimeout, VceSTATE.Idle); //UnLoad With SMIF => UnLoad with smif Transition(VceSTATE.Idle, VceMSG.UnLoadWithSMIF, fnStartUnLoadWithSMIF, VceSTATE.UnLoadingWithSMIF); Transition(VceSTATE.UnLoadingWithSMIF, FSM_MSG.TIMER, fnUnLoadWithSMIFTimeout, VceSTATE.Idle); //Goto LP Transition(VceSTATE.Idle, VceMSG.GotoLP, fnStartGotoLP, VceSTATE.GotingLP); Transition(VceSTATE.GotingLP, FSM_MSG.TIMER, fnGotoLPTimeout, VceSTATE.Idle); //Pump Transition(VceSTATE.Idle, VceMSG.Pump, fnStartPump, VceSTATE.Pumping); Transition(VceSTATE.Pumping, FSM_MSG.TIMER, fnPumpTimeout, VceSTATE.Idle); Transition(VceSTATE.Pumping, VceMSG.Abort, fnAbortPump, VceSTATE.Idle); //Vent Transition(VceSTATE.Idle, VceMSG.Vent, fnStartVent, VceSTATE.Venting); Transition(VceSTATE.Venting, FSM_MSG.TIMER, fnVentTimeout, VceSTATE.Idle); Transition(VceSTATE.Venting, VceMSG.Abort, fnAbortVent, VceSTATE.Idle); EnumLoop.ForEach((item) => { fsm.MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { fsm.MapMessage((int)item, item.ToString()); }); Running = true; } private bool fnAbortVent(object[] param) { _ventRoutine.Abort(); return true; } private bool fnVentTimeout(object[] param) { RState ret = _ventRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartVent(object[] param) { return _ventRoutine.Start(param) == RState.Running; } private bool fnAbortPump(object[] param) { _pumpRoutine.Abort(); return true; } private bool fnPumpTimeout(object[] param) { RState ret = _pumpRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartPump(object[] param) { return _pumpRoutine.Start(param) == RState.Running; } private bool fnGotoLPTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (_vce.Status == RState.End) { currentSlot = targetSlot; } return _vce.Status == RState.End; } private bool fnStartGotoLP(object[] param) { if (_vce.GotoLP()) { targetSlot = -1; return true; } else return false; } private bool fnSafeUnLoadTimeout(object[] param) { RState ret = _unloadRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = false; WaferManager.Instance.DeleteWafer(_modulename, 0, 25); } return ret == RState.End; } private bool fnStartClearError(object[] param) { if (_vce.ClearError()) { return true; } else return false; } private bool fnClearErrorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (_vce.Status == RState.End) { currentSlot = targetSlot; } return _vce.Status == RState.End; } private bool fnStartSafeUnLoad(object[] param) { return _unloadRoutine.Start(param) == RState.Running; } private bool fnSafeLoadTimeout(object[] param) { RState ret = _loadRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = true; } return ret == RState.End; } private bool fnStartLoadWithSMIF(object[] param) { return _loadwithSMIFRoutine.Start(param) == RState.Running; } private bool fnLoadWithSMIFTimeout(object[] param) { RState ret = _loadwithSMIFRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = true; } return ret == RState.End; } private bool fnStartUnLoadWithSMIF(object[] param) { return _unloadwithSMIFRoutine.Start(param) == RState.Running; } private bool fnUnLoadWithSMIFTimeout(object[] param) { RState ret = _unloadwithSMIFRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } if (ret == RState.End) { _CassetteArrive = false; WaferManager.Instance.DeleteWafer(_modulename, 0, 25); } return ret == RState.End; } private bool fnStartSafeLoad(object[] param) { return _loadRoutine.Start(param) == RState.Running; } private bool fnLoadingPrepareTimeout(object[] param) { RState ret = _prepareRoutine.Monitor(); if (ret == RState.Timeout || ret == RState.Failed) { PostMsg(VceMSG.Error); return false; } return ret == RState.End; } private bool fnStartLoadPrepare(object[] param) { return _prepareRoutine.Start(param) == RState.Running; } private bool fnReadingMapTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartReadingMap(object[] param) { return _vce.ReadMap(); } //急停 private bool fnAbort(object[] param) { return true; } //升降到槽位 private bool fnStartGoto(object[] param) { if (_vce.Goto(Convert.ToInt32(param[0]))) { targetSlot = Convert.ToInt32(param[0]); return true; } else return false; } private bool fnGotingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } if(_vce.Status == RState.End) currentSlot = targetSlot; return _vce.Status == RState.End; } private bool fnError(object[] param) { return true; } private bool fnStartHome(object[] param) { return _vce.HomeALL(); } private bool fnHomeTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartOpenDoor(object[] param) { if (Singleton.Instance.seTM.VCEIsATM && Singleton.Instance.seTM.VCEPressure >= SC.GetValue($"{_modulename}.OutDoorOpenPressure")) { return _vce.OpenDoor(); } else { LOG.Write(eEvent.ERR_VCE_COMMON_Failed, _modulename, $"{_modulename} is not ATM or Pressure not arrive {SC.GetValue($"{_modulename}.OutDoorOpenPressure")}"); return false; } } private bool fnOpenDoorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartCloseDoor(object[] param) { return _vce.CloseDoor(); } private bool fnCloseDoorTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartMapping(object[] param) { return _vce.Map(); } private bool fnMappingTimeout(object[] param) { if(_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartLoading(object[] param) { return _vce.Load(); } private bool fnLoadingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } private bool fnStartUnLoading(object[] param) { return _vce.UnLoad(); } private bool fnUnLoadingTimeout(object[] param) { if (_vce.Status == RState.Timeout || _vce.Status == RState.Failed) { PostMsg(VceMSG.Error); return false; } return _vce.Status == RState.End; } public bool Check(int msg, out string reason, params object[] args) { reason = ""; return true; } public int Invoke(string function, params object[] args) { switch (function) { case "Home": CheckToPostMessage((int)VceMSG.Home); return (int)VceMSG.Home; } return (int)VceMSG.None; } public bool CheckToPostMessage(int msg, params object[] args) { if (!fsm.FindTransition(fsm.State, msg)) { LOG.Write(eEvent.WARN_FSM_WARN, _modulename, $"{_modulename} is in {(VceSTATE)fsm.State} state,can not do {(VceMSG)msg}"); return false; } Running = true; fsm.PostMsg(msg, args); return true; } public bool CheckAcked(int msg) { return fsm.CheckExecuted(msg); } public bool IsPrepareTransferReady(ModuleName module, EnumTransferType transferType, int slot) { return false; } } }