using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.Utilities; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.RT.ModuleLibrary.LPModules; using System; using Aitex.Core.RT.SCCore; using CyberX8_RT.Devices; using CyberX8_RT.Devices.EFEM; using CyberX8_Core; using Aitex.Core.Common; using Aitex.Core.Util; namespace CyberX8_RT.Modules.LPs { /// /// LP entity /// sealed class LoadPortModule : LoadPortModuleBase { public event Action OnEnterError; private enum STATE { Unknown, Idle, // 1 Init, Error, Homing, // 2 Mapping, // 4 Loading, ReadingCarrierId, Unloading, Docking, Undocking, Clamping, Unclamping, WritingCarrierId, ReadingTagData, WritingTagData, CycleLoadUnloading } public enum MSG { Home, // 0 Map, // 1 ActionDone, // 2 Abort, // 5 Online, // 6 Error, // 7 Reset, EnterIdle, ReadCarrierId, WriteCarrierID, Load, Unload, Dock, Undock, Clamp, Unclamp, ToInit, ToIdle, ReadTagData, WriteTagData, CloseDoor, OpenDoor, CycleLoadUnload } public EfemBase JetEfem { get { return _efem; } } private readonly EfemBase _efem; private Loadport _lpDevice; public Loadport LPDevice { get { return _lpDevice; } } public override bool IsReady { get { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); } } public override bool IsError { get { return FsmState == (int)STATE.Error; } } public override bool IsInit { get { return FsmState == (int)STATE.Init; } } public override bool IsIdle { get { return FsmState == (int)STATE.Idle; } } public bool IsBusy { get { return !IsInit && !IsError && !IsIdle; } } /// /// wafer尺寸 /// public WaferSize WaferSize { get { return _lpDevice.WaferSize; } } public bool IsRobotIdle { get { return Singleton.Instance.EFEM.RobotStatus == RState.End; } } private LoadPortHomeRoutine _home; private LoadPortMapRoutine _map; //private LoadPortCloseDoorRoutine _closeDoor; private LoadPortDockRoutine _dockRoutine; private LoadPortUnDockRoutine _undockRoutine; private LoadPortClampRoutine _clamp; private LoadPortReadCarrierIdRoutine _readCarrierId; private LoadPortWriteCarrierIdRoutine _writeCarrierId; private LoadPortReadTagDataRoutine _readTag; private LoadPortWriteTagDataRoutine _writeTag; private LoadPortUnclampRoutine _unclamp; //private LoadPortUndockRoutine _undock; private LoadPortLoadRoutine _load; private LoadPortUnloadRoutine _unload; private LoadPortCycleLoadUnloadRoutine _cycleLoadUnloadRoutine; //private bool _isInit; public LoadPortModule(ModuleName module, EfemBase efem) : base(SC.GetValue("EFEM.LoadPort.SlotNumber")) { Name = module.ToString(); Module = module.ToString(); _efem = efem; InitFsmMap(); _lpDevice = new Loadport(module,efem); OP.Subscribe($"{Module}.ReadCarrierId", (cmd, args) => { PostMsg(MSG.ReadCarrierId); return true; }); OP.Subscribe($"{Module}.WriteCarrierID", (cmd, args) => { PostMsg(MSG.WriteCarrierID, args[0]); return true; }); OP.Subscribe($"{Module}.ReadTagData", (cmd, args) => { PostMsg(MSG.ReadTagData); return true; }); OP.Subscribe($"{Module}.WriteTagData", (cmd, args) => { PostMsg(MSG.WriteTagData, args[0]); return true; }); OP.Subscribe($"{Module}.Load", (cmd, args) => { PostMsg(MSG.Load); return true; }); OP.Subscribe($"{Module}.Unload", (cmd, args) => { PostMsg(MSG.Unload); return true; }); OP.Subscribe($"{Module}.Clamp", (cmd, args) => { PostMsg(MSG.Clamp); return true; }); OP.Subscribe($"{Module}.Unclamp", (cmd, args) => { PostMsg(MSG.Unclamp); return true; }); OP.Subscribe($"{Module}.Dock", (cmd, args) => { PostMsg(MSG.Dock); return true; }); OP.Subscribe($"{Module}.Undock", (cmd, args) => { PostMsg(MSG.Undock); return true; }); OP.Subscribe($"{Module}.Map", (cmd, args) => { PostMsg(MSG.Map); return true; }); OP.Subscribe($"{Module}.Home", (cmd, args) => { PostMsg(MSG.Home); return true; }); OP.Subscribe($"{Module}.Abort", (cmd, args) => { PostMsg(MSG.Abort); return true; }); OP.Subscribe($"{Module}.Online", (cmd, args) => { PostMsg(MSG.Online); return true; }); OP.Subscribe($"{Name}.OpenDoor", (string cmd, object[] args) =>{return CheckToPostMessage((int)MSG.OpenDoor);}); OP.Subscribe($"{Name}.CloseDoor", (string cmd, object[] args) =>{return CheckToPostMessage((int)MSG.CloseDoor);}); OP.Subscribe($"{Module}.CycleLoadUnload", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.CycleLoadUnload,args); }); DATA.Subscribe($"{Module}.Status", () => ((STATE)FsmState).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.FsmState", () => ((STATE)FsmState).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.FsmPrevState", () => ((STATE)FsmPreviousState).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.FsmLastMessage", GetFsmLastMessage, SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.State", () => ((STATE)FsmState).ToString(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Module}.IsError", ()=>IsError, SubscriptionAttribute.FLAG.SaveDB); DATA.Subscribe($"{Module}.IsIdle", () => IsIdle, SubscriptionAttribute.FLAG.SaveDB); DATA.Subscribe($"{Module}.IsBusy", () => IsBusy, SubscriptionAttribute.FLAG.SaveDB); InitRoutine(); } private void InitRoutine() { _home = new LoadPortHomeRoutine(this); //_closeDoor = new LoadPortCloseDoorRoutine(this); _clamp = new LoadPortClampRoutine(this); //_dock = new LoadPortDockRoutine(this); _map = new LoadPortMapRoutine(this,_efem); //_openDoor = new LoadPortOpenDoorRoutine(this); _readCarrierId = new LoadPortReadCarrierIdRoutine(this); _writeCarrierId = new LoadPortWriteCarrierIdRoutine(this); _readTag = new LoadPortReadTagDataRoutine(this); _writeTag = new LoadPortWriteTagDataRoutine(this); _unclamp = new LoadPortUnclampRoutine(this); //_undock = new LoadPortUndockRoutine(this); //_MapDT = new LoadPortGetMapInfoRoutine(this); _load = new LoadPortLoadRoutine(this); _unload = new LoadPortUnloadRoutine(this); _dockRoutine = new LoadPortDockRoutine(this); _undockRoutine = new LoadPortUnDockRoutine(this); _cycleLoadUnloadRoutine=new LoadPortCycleLoadUnloadRoutine(this); } private string GetFsmLastMessage() { int msg = FsmLastMessage; if (msg >= (int)MSG.Home && msg <= (int)MSG.Error) return ((MSG)msg).ToString(); if (msg == (int)FSM_MSG.TIMER) return "Timer"; return msg.ToString(); } private void InitFsmMap() { EnableFsm(50, STATE.Idle); //online AnyStateTransition(MSG.Online, fnOnline, FSM_STATE.SAME); //Error AnyStateTransition(MSG.Error, FsmOnError, STATE.Error); Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle); Transition(STATE.Idle, MSG.Reset, FsmReset, STATE.Idle); AnyStateTransition(MSG.EnterIdle, FsmEnterIdle, STATE.Idle); EnterExitTransition(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError); //Init Transition(STATE.Init, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Error, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Idle, MSG.Home, FsmStartHome, STATE.Homing); Transition(STATE.Homing, FSM_MSG.TIMER, FsmMonitorHomeTask, STATE.Idle); Transition(STATE.Homing, MSG.Error, null, STATE.Init); Transition(STATE.Homing, MSG.Abort, FsmAbortTask, STATE.Init); //load Transition(STATE.Idle, MSG.Load, FsmStartLoad, STATE.Loading); Transition(STATE.Loading, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Loading, MSG.Abort, FsmAbortTask, STATE.Idle); //unload Transition(STATE.Idle, MSG.Unload, FsmStartUnload, STATE.Unloading); Transition(STATE.Unloading, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Unloading, MSG.Abort, FsmAbortTask, STATE.Idle); //read carrier id Transition(STATE.Idle, MSG.ReadCarrierId, FsmStartReadCarrierId, STATE.ReadingCarrierId); Transition(STATE.ReadingCarrierId, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ReadingCarrierId, MSG.Abort, FsmAbortTask, STATE.Idle); //write carrier id Transition(STATE.Idle, MSG.WriteCarrierID, FsmStartWriteCarrierId, STATE.WritingCarrierId); Transition(STATE.WritingCarrierId, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.WritingCarrierId, MSG.Abort, FsmAbortTask, STATE.Idle); //clamp Transition(STATE.Idle, MSG.Clamp, FsmStartClamp, STATE.Clamping); Transition(STATE.Clamping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Clamping, MSG.Abort, FsmAbortTask, STATE.Idle); //unclamp Transition(STATE.Idle, MSG.Unclamp, FsmStartUnclamp, STATE.Unclamping); Transition(STATE.Unclamping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Unclamping, MSG.Abort, FsmAbortTask, STATE.Idle); //dock Transition(STATE.Idle, MSG.Dock, FsmStartDock, STATE.Docking); Transition(STATE.Docking, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Docking, MSG.Abort, FsmAbortTask, STATE.Idle); //undock Transition(STATE.Idle, MSG.Undock, FsmStartUndock, STATE.Undocking); Transition(STATE.Undocking, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Undocking, MSG.Abort, FsmAbortTask, STATE.Idle); //Map Transition(STATE.Idle, MSG.Map, FsmStartMap, STATE.Mapping); Transition(STATE.Mapping, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Mapping, MSG.Abort, FsmAbortTask, STATE.Idle); //read tag data Transition(STATE.Idle, MSG.ReadTagData, FsmStartReadTagData, STATE.ReadingTagData); Transition(STATE.ReadingTagData, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.ReadingTagData, MSG.Abort, FsmAbortTask, STATE.Idle); //write tag data Transition(STATE.Idle, MSG.WriteTagData, FsmStartWriteTagData, STATE.WritingTagData); Transition(STATE.WritingTagData, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.WritingTagData, MSG.Abort, FsmAbortTask, STATE.Idle); //Cycle Load Transition(STATE.Idle, MSG.CycleLoadUnload, CycleLoadUnload, STATE.CycleLoadUnloading); Transition(STATE.CycleLoadUnloading, FSM_MSG.TIMER, CycleLoadUnloadMonitor, STATE.Idle); Transition(STATE.CycleLoadUnloading, MSG.Abort, CycleLoadUnloadAbort, STATE.Idle); EnumLoop.ForEach((item) => { MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { MapMessage((int)item, item.ToString()); }); } private bool FsmAbortTask(object[] param) { AbortRoutine(); LPDevice.Abort(); return true; } private bool FsmEnterIdle(object[] param) { return true; } private bool FsmReset(object[] param) { //if (!_isInit) //{ // PostMsg(MSG.ToInit); // return false; //} return true; } private bool FsmOnError(object[] param) { if (FsmState == (int)STATE.Error) { return false; } AbortRoutine(); if (FsmState == (int)STATE.Init) return false; return true; } private bool FsmExitError(object[] param) { return true; } private bool FsmEnterError(object[] param) { if (OnEnterError != null) OnEnterError(Module); return true; } private bool FsmMonitorTask(object[] param) { RState ret = MonitorRoutine(); if (ret == RState.Failed || ret == RState.Timeout) { PostMsg(MSG.Error); return false; } return ret == RState.End; } private bool FsmStartHome(object[] param) { RState ret = StartRoutine(_home); if (ret == RState.Failed || ret == RState.End) return false; //_isInit = false; return ret == RState.Running; } private bool FsmMonitorHomeTask(object[] param) { RState ret = MonitorRoutine(); if (ret == RState.Failed||ret==RState.Timeout) { LPDevice.OnError(); PostMsg(MSG.Error); return false; } if (ret == RState.End) { //_isInit = true; return true; } return false; } private bool FsmStartUndock(object[] param) { RState ret = StartRoutine(_undockRoutine); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartDock(object[] param) { RState ret = StartRoutine(_dockRoutine); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartMap(object[] param) { RState ret = StartRoutine(_map); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartUnclamp(object[] param) { RState ret = StartRoutine(_unclamp); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartClamp(object[] param) { _clamp.IsUnloadClamp = false; RState ret = StartRoutine(_clamp); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartReadCarrierId(object[] param) { RState ret = StartRoutine(_readCarrierId); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartWriteCarrierId(object[] param) { _writeCarrierId.CarrierIdSetPoint = (string) param[0]; RState ret = StartRoutine(_writeCarrierId); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartReadTagData(object[] param) { RState ret = StartRoutine(_readTag); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartWriteTagData(object[] param) { _writeTag.TagDataSetPoint = (string)param[0]; RState ret = StartRoutine(_writeTag); if (ret == RState.Failed || ret == RState.End) return false; return ret == RState.Running; } private bool FsmStartUnload(object[] param) { RState ret = StartRoutine(_unload); if (ret == RState.Failed || ret == RState.End) return false; if(ret == RState.Running) { _lpDevice.UnloadStart(); } return ret == RState.Running; } private bool FsmStartLoad(object[] param) { RState ret = StartRoutine(_load); if (ret == RState.Failed || ret == RState.End) return false; if (ret == RState.Running) { _lpDevice.LoadStart(); } return ret == RState.Running; } private bool CycleLoadUnload(object[] param) { return _cycleLoadUnloadRoutine.Start(param) == RState.Running; } private bool CycleLoadUnloadMonitor(object[] param) { RState state = _cycleLoadUnloadRoutine.Monitor(); if(state==RState.Failed||state==RState.Timeout) { PostMsg(MSG.Error); return false; } return state == RState.End; } private bool CycleLoadUnloadAbort(object[] param) { _cycleLoadUnloadRoutine.Abort(); return true; } private bool fnOnline(object[] param) { bool online = (bool)param[0]; //_efem.SetOnline(ModuleHelper.Converter(Module), online); return true; } public bool IsPrepareTransferReady(ModuleName module, EnumTransferType type, int slot) { if (type == EnumTransferType.Pick) { //需要补充:判断LP 放好了,而且已经map过。 //return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid; } else if (type == EnumTransferType.Place) { //需要补充:判断LP 放好了,而且已经map过。 //return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid; } return false; } internal bool CheckReadyRunNewJob(ModuleName module) { return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid; } internal bool CheckReadyTransfer(ModuleName module) { return _efem[module].HasCassette && _efem[module].IsMapped && _efem[module].IsThicknessValid; } public override bool Home(out string reason) { throw new NotImplementedException(); } public override void NoteJobStart() { throw new NotImplementedException(); } public override void NoteJobComplete() { throw new NotImplementedException(); } public override bool PrepareTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { throw new NotImplementedException(); } public override bool TransferHandoff(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { throw new NotImplementedException(); } public override bool PostTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { throw new NotImplementedException(); } public override bool CheckReadyForTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { throw new NotImplementedException(); } public override void NoteTransferStart(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType) { throw new NotImplementedException(); } public override void NoteTransferStop(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType) { throw new NotImplementedException(); } public override bool CheckReadyForMap(ModuleName robot, Hand blade, out string reason) { throw new NotImplementedException(); } } }