using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Aitex.Core.Common; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using Aitex.Core.RT.SCCore; namespace VirgoRT.Modules { public class ReturnAllWafer : TransferModule { private Queue _moveTaskQueue = new Queue(); private IRoutine _activeTask; private bool _cooling; private int _coolingTime; private bool _aligning; private int _alignAngle; private int _flipOption = 0; public Result Start(object[] objs) { _moveTaskQueue.Clear(); _activeTask = null; if (objs.Length >= 4) { _aligning = (bool)objs[2]; _alignAngle = (int)objs[3]; } if (objs.Length >= 2) { _cooling = (bool)objs[0]; _coolingTime = (int)objs[1]; } else { _cooling = false; _aligning = false; } _flipOption = SC.GetValue("EFEM.FlipReturnWaferOption"); return Result.RUN; } public Result Monitor(object[] objs) { if (_activeTask == null ) { return StartNewReturnTask(); } Result ret = _activeTask.Monitor(); if (ret == Result.FAIL) return ret; if (ret == Result.DONE) { if (_moveTaskQueue.Count > 0) { _activeTask = _moveTaskQueue.Dequeue(); return _activeTask.Start(); } else { _activeTask = null; } } return Result.RUN; } public void Clear() { _moveTaskQueue.Clear(); _activeTask = null; } private Result StartNewReturnTask() { ModuleName[] modules = new[] {ModuleName.EfemRobot, ModuleName.Aligner1, ModuleName.Aligner2, ModuleName.Cooling1, ModuleName.Cooling2, ModuleName.PMA, ModuleName.PMB, ModuleName.Flipper}; ModuleName source = ModuleName.System; WaferInfo wafer = null; Hand hand = SelectFreeArm(); int sourceSlot = 0; foreach (var moduleName in modules) { if (ModuleHelper.IsInstalled(moduleName) && WaferManager.Instance.CheckHasWafer(moduleName, 0)) { source = moduleName; wafer = WaferManager.Instance.GetWafer(source, 0); break; } } if (wafer == null) { if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { source = ModuleName.EfemRobot; wafer = WaferManager.Instance.GetWafer(source, 1); hand = Hand.Blade2; sourceSlot = 1; } } if (wafer == null && ModuleHelper.IsInstalled(ModuleName.Buffer)) { for (int i = 0; i < SC.GetValue("EFEM.Buffer.SlotNumber"); i++) { if (WaferManager.Instance.CheckHasWafer(ModuleName.Buffer, i)) { source = ModuleName.Buffer; wafer = WaferManager.Instance.GetWafer(source, i); sourceSlot = i; break; } } } if (source == ModuleName.System || wafer==null || wafer.IsEmpty) { EV.PostInfoLog("Scheduler", "All wafers returned."); return Result.DONE; } ModuleName transferModule = source; int transferSlot = sourceSlot; if ((_flipOption == 1 && wafer.IsReversed) || (_flipOption == 2 && !wafer.IsReversed) || (_flipOption == 3) || (source == ModuleName.EfemRobot && _flipOption != 0)) { string flipOrient = _flipOption == 1 ? "FaceUp" : (_flipOption == 2 ? "FaceDown" : "AlwaysReverse"); if (_aligning && WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0)) { if (WaferManager.Instance.CheckHasWafer(ModuleName.Flipper, 0)) { EV.PostWarningLog("System", "Cannot auto Flip and Align wafer while return wafers as both modules have wafer"); return Result.FAIL; } hand = SelectFreeArm(); if (hand == Hand.Both) { EV.PostWarningLog("System", "No free arm while return wafer"); return Result.FAIL; } // handle the aligner wafer first while return wafer need both flip and aligning wafer = WaferManager.Instance.GetWafer(ModuleName.Aligner1, 0); _moveTaskQueue.Enqueue(new AlignRoutine(ModuleName.Aligner1.ToString())); _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(ModuleName.Aligner1, 0, ModuleName.Flipper, 0, 0, hand))); _moveTaskQueue.Enqueue(new FlipRoutine(ModuleName.Flipper.ToString(), flipOrient)); _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(ModuleName.Flipper, 0, (ModuleName)wafer.OriginStation, wafer.OriginSlot, 0, hand))); _activeTask = _moveTaskQueue.Dequeue(); return _activeTask.Start(); } if (WaferManager.Instance.CheckNoWafer(ModuleName.Flipper, 0)) { _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(source, sourceSlot, ModuleName.Flipper, 0, 0, hand))); } else { hand = SelectFreeArm(); if (hand == Hand.Both) { EV.PostWarningLog("System", "No free arm while return wafer"); return Result.FAIL; } wafer = WaferManager.Instance.GetWafer(ModuleName.Flipper, 0); } _moveTaskQueue.Enqueue(new FlipRoutine(ModuleName.Flipper.ToString(), flipOrient)); transferModule = ModuleName.Flipper; transferSlot = 0; } else if (ModuleHelper.IsFlipper(source)) { _moveTaskQueue.Enqueue(new FlipRoutine(source.ToString(), _flipOption == 2 ? "FaceDown" : "FaceUp")); } if (_cooling && !ModuleHelper.IsCooling(transferModule) && !ModuleHelper.IsAligner(transferModule)) { ModuleName cooling = ModuleName.System; if (ModuleHelper.IsInstalled(ModuleName.Cooling1) && WaferManager.Instance.CheckNoWafer(ModuleName.Cooling1, 0)) cooling = ModuleName.Cooling1; else if (ModuleHelper.IsInstalled(ModuleName.Cooling2) && WaferManager.Instance.CheckNoWafer(ModuleName.Cooling2, 0)) cooling = ModuleName.Cooling2; else { EV.PostWarningLog("System", "No valid cooling station for auto cooling"); return Result.FAIL; } _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(transferModule, transferSlot, cooling, 0, _coolingTime, hand))); _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(cooling, 0, (ModuleName)wafer.OriginStation, wafer.OriginSlot, 0, hand))); } else if (_aligning) { ModuleName aligner = transferModule; bool needMoveToAligner = true; if (!ModuleHelper.IsAligner(transferModule)) { if (ModuleHelper.IsInstalled(ModuleName.Aligner1) && WaferManager.Instance.CheckNoWafer(ModuleName.Aligner1, 0)) aligner = ModuleName.Aligner1; else if (ModuleHelper.IsInstalled(ModuleName.Aligner2) && WaferManager.Instance.CheckNoWafer(ModuleName.Aligner2, 0)) aligner = ModuleName.Aligner2; else if (transferModule == ModuleName.EfemRobot && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1 - transferSlot)) { if (ModuleHelper.IsInstalled(ModuleName.Aligner1) && WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0)) aligner = ModuleName.Aligner1; else if (ModuleHelper.IsInstalled(ModuleName.Aligner2) && WaferManager.Instance.CheckHasWafer(ModuleName.Aligner2, 0)) aligner = ModuleName.Aligner2; else { EV.PostWarningLog("System", "No aligner station installed"); return Result.FAIL; } // return aligner wafer first hand = (Hand)(1 - transferSlot); needMoveToAligner = false; wafer = WaferManager.Instance.GetWafer(aligner, 0); } else { EV.PostWarningLog("System", "No valid aligner station for auto aligning"); return Result.FAIL; } if(needMoveToAligner) _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(transferModule, transferSlot, aligner, 0, _coolingTime, hand))); } _moveTaskQueue.Enqueue(new AlignRoutine(aligner.ToString())); _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(aligner, 0, (ModuleName)wafer.OriginStation, wafer.OriginSlot, 0, hand))); } else { _moveTaskQueue.Enqueue(new EfemRobotMover(new MoveItemEx(transferModule, transferSlot, (ModuleName)wafer.OriginStation, wafer.OriginSlot, 0, hand))); } _activeTask = _moveTaskQueue.Dequeue(); return _activeTask.Start() ; } private Hand SelectFreeArm() { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0) && SC.GetValue("EFEM.EfemRobot.LowerBladeEnable")) return Hand.Blade1; else if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1) && SC.GetValue("EFEM.EfemRobot.UpperBladeEnable")) return Hand.Blade2; else return Hand.Both; } } }