using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.Fsm; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Utilities; using Aitex.Sorter.Common; using Mainframe.TMs; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Mainframe.LLs { public class LoadLockModule : LoadLockModuleBase { public enum STATE { NotInstall, Init, Idle, Homing, Pump, Vent, MoveLift, Purge, LeakCheck, Transfer, Error, PrepareTransfer, OpenDoor, CloseDoor, Cooling, } public enum MSG { Home, Reset, Abort, Error, Transfer, PrepareTransfer, MoveLift, Pump, Vent, Purge, LeakCheck, OpenDoor, CloseDoor, Cooling, SetOnline, SetOffline, ToInit, } public bool IsAlarm { get { return FsmState == (int)STATE.Error; } } 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 bool IsBusy { get { return !IsInit && !IsError && !IsReady; } } public override bool IsIdle { get { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); } } public int CurrentRoutineLoop { get { if (FsmState == (int)STATE.Purge) return _purgeRoutine.LoopCounter + 1; // CurrentLoop从0开始 return 0; } } public int CurrentRoutineLoopTotal { get { if (FsmState == (int)STATE.Purge) return _purgeRoutine.LoopTotalTime; return 0; } } public bool JobDone { get { if (_llDevice != null) { return _llDevice.JobDone; } return false; } } public event Action OnEnterError; private bool _isInit; public SicLoadLock _llDevice { get; set; } private LoadLockPumpRoutine _pumpRoutine; private LoadLockVentRoutine _ventRoutine; private LoadLockPurgeRoutine _purgeRoutine; private LoadLockLeakCheckRoutine _leakCheckRoutine; private LoadLockDoorRoutine _doorRoutine; private LoadLockCoolingRoutine _coolingRoutine; private LoadLockVerifyAtmDoorRoutine _verifyDoorRoutine; private LoadLockServoTo _llServoTo; private LoadLockPrepareTransferRoutine _prepareTransferRoutine; //private TMSlitValveRoutine _slitValveRoutine; public LoadLockModule(ModuleName module) : base(1) { Module = module.ToString(); Name = module.ToString(); IsOnline = false; EnumLoop.ForEach((item) => { MapState((int)item, item.ToString()); }); EnumLoop.ForEach((item) => { MapMessage((int)item, item.ToString()); }); EnableFsm(50, IsInstalled ? STATE.Init : STATE.NotInstall); } public override bool Initialize() { InitRoutine(); InitDevice(); InitFsm(); InitOp(); InitData(); return base.Initialize(); } private void InitRoutine() { ModuleName module = ModuleHelper.Converter(Module); _pumpRoutine = new LoadLockPumpRoutine(module); _ventRoutine = new LoadLockVentRoutine(module); _purgeRoutine = new LoadLockPurgeRoutine(module); _leakCheckRoutine = new LoadLockLeakCheckRoutine(module); _doorRoutine = new LoadLockDoorRoutine(module); _coolingRoutine = new LoadLockCoolingRoutine(module); _verifyDoorRoutine = new LoadLockVerifyAtmDoorRoutine(module); _llServoTo = new LoadLockServoTo(module); _prepareTransferRoutine = new LoadLockPrepareTransferRoutine(module); //_slitValveRoutine = new TMSlitValveRoutine(); } private void InitDevice() { _llDevice = DEVICE.GetDevice($"{Module}.{Module}"); } private void InitFsm() { //Error AnyStateTransition(MSG.Error, FsmOnError, STATE.Error); Transition(STATE.Error, MSG.Reset, FsmReset, STATE.Idle); EnterExitTransition(STATE.Error, FsmEnterError, FSM_MSG.NONE, FsmExitError); //Home 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); EnterExitTransition((int)STATE.Homing, FsmEnterIdle, (int)FSM_MSG.NONE, FsmExitIdle); AnyStateTransition(MSG.ToInit, FsmToInit, STATE.Init); //PrepareTransfer Transition(STATE.Idle, MSG.PrepareTransfer, FsmStartPrepareTransfer, STATE.PrepareTransfer); Transition(STATE.PrepareTransfer, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.PrepareTransfer, MSG.Abort, FsmAbortTask, STATE.Idle); ////Online //Transition(STATE.Idle, MSG.SetOnline, FsmStartSetOnline, STATE.Idle); //Transition(STATE.Idle, MSG.SetOffline, FsmStartSetOffline, STATE.Idle); //Pump Transition(STATE.Idle, MSG.Pump, FsmStartPump, STATE.Pump); Transition(STATE.Pump, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Pump, MSG.Abort, FsmAbortTask, STATE.Idle); //Vent Transition(STATE.Idle, MSG.Vent, FsmStartVent, STATE.Vent); Transition(STATE.Vent, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Vent, MSG.Abort, FsmAbortTask, STATE.Idle); //Purge Transition(STATE.Idle, MSG.Purge, FsmStartPurge, STATE.Purge); Transition(STATE.Purge, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Purge, MSG.Abort, FsmAbortTask, STATE.Idle); //Leak Check Transition(STATE.Idle, MSG.LeakCheck, FsmStartLeakCheck, STATE.LeakCheck); Transition(STATE.LeakCheck, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.LeakCheck, MSG.Abort, FsmAbortTask, STATE.Idle); //open door Transition(STATE.Idle, MSG.OpenDoor, FsmStartOpenDoor, STATE.OpenDoor); Transition(STATE.OpenDoor, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.OpenDoor, MSG.Abort, FsmAbortTask, STATE.Idle); //close door Transition(STATE.Idle, MSG.CloseDoor, FsmStartCloseDoor, STATE.CloseDoor); Transition(STATE.CloseDoor, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.CloseDoor, MSG.Abort, FsmAbortTask, STATE.Idle); //cooling Transition(STATE.Idle, MSG.Cooling, FsmStartCooling, STATE.Cooling); Transition(STATE.Cooling, FSM_MSG.TIMER, FsmMonitorTask, STATE.Idle); Transition(STATE.Cooling, MSG.Abort, FsmAbortTask, STATE.Idle); } private void InitOp() { OP.Subscribe($"{Name}.Home", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Home); }); OP.Subscribe($"{Name}.Pump", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Pump); }); OP.Subscribe($"{Name}.Vent", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Vent); }); OP.Subscribe($"{Name}.Purge", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Purge); }); OP.Subscribe($"{Name}.LeakCheck", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.LeakCheck, args); }); OP.Subscribe($"{Name}.MoveLift", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.MoveLift, args[0]); }); 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($"{Name}.Reset", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Reset); }); OP.Subscribe($"{Name}.Abort", (string cmd, object[] args) => { return CheckToPostMessage((int)MSG.Abort); }); OP.Subscribe($"{Module}.SetOnline", (string cmd, object[] args) => PutOnline()); OP.Subscribe($"{Module}.SetOffline", (string cmd, object[] args) => PutOffline()); } private void InitData() { DATA.Subscribe($"{Name}.Status", () => StringFsmStatus); DATA.Subscribe($"{Name}.IsOnline", () => IsOnline); DATA.Subscribe($"{Name}.IsBusy", () => IsBusy); DATA.Subscribe($"{Name}.CurrentRoutineLoop", () => CurrentRoutineLoop); DATA.Subscribe($"{Name}.CurrentRoutineLoopTotal", () => CurrentRoutineLoopTotal); DATA.Subscribe($"{Module}.IsAlarm", () => IsAlarm); DATA.Subscribe($"{Name}.LeakCheckElapseTime", () => { if (FsmState == (int)STATE.LeakCheck) return _leakCheckRoutine.ElapsedTime; return 0; }); DATA.Subscribe($"{Name}.AtATM", () => { if (_llDevice.CheckAtm()) { return true; } return false; }); DATA.Subscribe($"{Name}.UnderVAC", () => { if (_llDevice.CheckVacuum()) { return true; } return false; }); DATA.Subscribe($"{Name}.LidState", () => { if (_llDevice.CheckLidClosed()) { return "Closed"; } return "Open"; }); } private bool FsmOnError(object[] param) { IsOnline = false; if (FsmState == (int)STATE.Error) { return false; } if (FsmState == (int)STATE.Init) return false; return true; } private bool FsmReset(object[] param) { if (!_isInit) { PostMsg(MSG.ToInit); return false; } //LoadLock Reset时,需要添加执行关闭V79、V80、V85、V83、V84的动作 string reason; _llDevice.SetSlowPumpValve(false, out reason); _llDevice.SetFastPumpValve(false, out reason); _llDevice.SetFastVentValve(false, out reason); _llDevice.SetSlowVentValve(false, out reason); IoValve _TmToLLVent = DEVICE.GetDevice("TM.TMTOLLVent"); _TmToLLVent.TurnValve(false, out reason); return true; } private bool FsmExitError(object[] param) { return true; } private bool FsmEnterError(object[] param) { if (OnEnterError != null) OnEnterError(Module); return true; } private bool FsmStartHome(object[] param) { QueueRoutine.Clear(); if (SC.ContainsItem("LoadLock.IsVerifyDoorEnabled") && SC.GetValue("LoadLock.IsVerifyDoorEnabled")) { _verifyDoorRoutine.Init(); QueueRoutine.Enqueue(_verifyDoorRoutine); } else { return true; } Result ret = StartRoutine(); if (ret == Result.FAIL) return false; if (ret == Result.DONE) return true; _isInit = false; return ret == Result.RUN; } private bool FsmMonitorHomeTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } if (ret == Result.DONE) { _isInit = true; return true; } return false; } private bool FsmAbortTask(object[] param) { AbortRoutine(); return true; } private bool FsmExitIdle(object[] param) { return true; } private bool FsmEnterIdle(object[] param) { return true; } private bool FsmToInit(object[] param) { return true; } private bool FsmStartPrepareTransfer(object[] param) { QueueRoutine.Clear(); //double tragetPressure = SC.GetConfigItem("TM.PressureBalance.BalancePressureForLL").DoubleValue; //if (tragetPressure < 20) //{ // //_doorRoutine.Init(false); // //QueueRoutine.Enqueue(_doorRoutine); // //_pumpRoutine.Init(); // //QueueRoutine.Enqueue(_pumpRoutine); //} //else //{ // //_doorRoutine.Init(false); // //QueueRoutine.Enqueue(_doorRoutine); // //_pumpRoutine.Init(); // //QueueRoutine.Enqueue(_pumpRoutine); // //QueueRoutine.Enqueue(_prepareTransferRoutine); //} QueueRoutine.Enqueue(_prepareTransferRoutine); Result ret = StartRoutine(); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmMonitorTask(object[] param) { Result ret = MonitorRoutine(); if (ret == Result.FAIL) { PostMsg(MSG.Error); return false; } return ret == Result.DONE; } private bool FsmStartSetOffline(object[] param) { IsOnline = false; return true; } private bool FsmStartSetOnline(object[] param) { IsOnline = true; return true; } private bool FsmStartPump(object[] param) { Result ret = StartRoutine(_pumpRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartVent(object[] param) { Result ret = StartRoutine(_ventRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartPurge(object[] param) { Result ret = StartRoutine(_purgeRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartLeakCheck(object[] param) { if (param != null && param.Length >= 2) { _leakCheckRoutine.Init((int)param[0], (int)param[1]); } else { _leakCheckRoutine.Init(); } Result ret = StartRoutine(_leakCheckRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartOpenDoor(object[] param) { _doorRoutine.Init(true); Result ret = StartRoutine(_doorRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartCloseDoor(object[] param) { _doorRoutine.Init(false); Result ret = StartRoutine(_doorRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } private bool FsmStartCooling(object[] param) { _coolingRoutine.Init((int)param[0]); Result ret = StartRoutine(_coolingRoutine); if (ret == Result.FAIL || ret == Result.DONE) return false; return ret == Result.RUN; } public override bool Home(out string reason) { CheckToPostMessage((int)MSG.Home); reason = string.Empty; return true; } public override int InvokeCooling(int time) { if (CheckToPostMessage((int)MSG.Cooling, time)) return (int)MSG.Cooling; return (int)FSM_MSG.NONE; } public override int InvokeVent() { if (CheckToPostMessage((int)MSG.Vent)) { return (int)MSG.Vent; } return (int)FSM_MSG.NONE; } public override int InvokePump() { if (CheckToPostMessage((int)MSG.Pump)) return (int)MSG.Pump; return (int)FSM_MSG.NONE; } public override int InvokePurge() { if (CheckToPostMessage((int)MSG.Purge)) return (int)MSG.Purge; return (int)FSM_MSG.NONE; } public override bool CheckAcked(int entityTaskToken) { return FsmState == (int)STATE.Idle && CheckAllMessageProcessed(); //return true; } public override void NoteTransferStart(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType) { //CheckToPostMessage(MSG.InTransfer); } public override void NoteTransferStop(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType) { //if (FsmState == (int)STATE.InTransfer) // CheckToPostMessage(MSG.TransferComplete); } public override bool PrepareTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; if (CheckToPostMessage((int)MSG.PrepareTransfer, robot, targetSlot)) return true; return false; } public override bool TransferHandoff(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; return true; } public override bool PostTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; return true; } public override bool CheckReadyForTransfer(ModuleName robot, Hand blade, int targetSlot, EnumTransferType transferType, out string reason) { reason = string.Empty; if (SC.GetValue("System.IsATMMode")) { return true; } //else //{ // return _llDevice.ChamberPressure < SC.GetConfigItem("TM.PressureBalance.BalancePressureForLL").DoubleValue + SC.GetConfigItem("TM.PressureBalance.BalanceMaxDiffPressure").DoubleValue; //} return _llDevice.CheckVacuum() && !SC.GetValue("System.IsATMMode") || (_llDevice.CheckAtm() && SC.GetValue("System.IsATMMode")); } public override bool CheckReadyForMap(ModuleName robot, Hand blade, out string reason) { //return _lpDevice.IsEnableMapWafer(out reason) && IsReady; reason = string.Empty; return true; } private bool PutOnline() { IsOnline = true; return true; } private bool PutOffline() { IsOnline = false; return true; } public override void InvokeOffline() { PutOffline(); } public override void InvokeOnline() { PutOnline(); } public override bool CheckLidClose() { return _llDevice.CheckLidClosed(); } } }