using System; using System.Collections.Generic; using System.Linq; using Aitex.Core.Common; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.ModuleLibrary.SystemModules; using EfemDualSchedulerLib.Schedulers; namespace EfemDualSchedulerLib { public class ReturnAllWafer : SchedulerModuleFactory, IRoutine { Dictionary _checkPosition = new Dictionary() { {ModuleName.EfemRobot, 2}, {ModuleName.Aligner, 1}, {ModuleName.LLA, 8}, {ModuleName.LLB, 8}, {ModuleName.TMRobot, 2}, {ModuleName.PMA, 2}, {ModuleName.PMB, 2}, }; private List _lstPms = new List(); private List _lstLps = new List(); private List _lstLls = new List(); Queue tmRobotActions = new Queue() { }; public ReturnAllWafer(EquipmentManager equipment) : base() { if (SC.GetValueOrDefault("System.SetUp.PMA.IsInstalled")) _lstPms.Add(_pm1); if (SC.GetValueOrDefault("System.SetUp.PMB.IsInstalled")) _lstPms.Add(_pm2); //if (SC.GetValueOrDefault("System.SetUp.PMC.IsInstalled")) // _lstPms.Add(_pm3); if (SC.GetValueOrDefault("System.SetUp.LLA.IsInstalled")) _lstLls.Add(_loadlockA); if (SC.GetValueOrDefault("System.SetUp.LLB.IsInstalled")) _lstLls.Add(_loadlockB); if (SC.GetValueOrDefault("System.SetUp.LP1.IsInstalled")) _lstLps.Add(_lp1); if (SC.GetValueOrDefault("System.SetUp.LP2.IsInstalled")) _lstLps.Add(_lp2); if (SC.GetValueOrDefault("System.SetUp.LP3.IsInstalled")) _lstLps.Add(_lp3); tmRobotActions.Enqueue(MonitorTMRobotPMATask); tmRobotActions.Enqueue(MonitorTMRobotPMBTask); tmRobotActions.Enqueue(MonitorTMRobotLoadLockTask); } public Result Start(params object[] objs) { foreach (var positions in _checkPosition) { for (int i = 0; i < positions.Value; i++) { WaferInfo wafer = WaferManager.Instance.GetWafer(positions.Key, i); if (!wafer.IsEmpty) { ModuleName originLoadPort = (ModuleName)wafer.OriginStation; if (!ModuleHelper.IsLoadPort(originLoadPort)) { EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, origin is not LP"); return Result.FAIL; } if (wafer.Status == WaferStatus.Dummy) { EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, wafer is dummy"); return Result.FAIL; } if (WaferManager.Instance.CheckHasWafer(originLoadPort, wafer.OriginSlot)) { EV.PostWarningLog("System", $"Wafer {positions.Key}.{i + 1} can not return, origin has wafer"); return Result.FAIL; } if (!(GetModule(originLoadPort.ToString()) as SchedulerLoadPort).IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade1, wafer.OriginSlot)) { EV.PostWarningLog("System", $"{originLoadPort} not ready to place Wafer"); return Result.FAIL; } EV.PostInfoLog("System", $"Wafer return, {positions.Key}.{i + 1}=>{(ModuleName)wafer.OriginStation}.{wafer.OriginSlot + 1}"); } } } return Result.RUN; } public Result Monitor() { MonitorModuleTasks(); if (MonitorTaskDone()) { return Result.DONE; } return Result.RUN; } public void Clear() { } public void Abort() { } public Result MonitorModuleTasks() { MonitorPMTask(); MonitorTMRobotTask(); MonitorEfemRobotTask(); return Result.RUN; } private void MonitorTMRobotTask() { if (!_tmRobot.IsAvailable) return; //_tmRobot is idle, release all the target foreach (var ll in _lstLls) { if (ll.IsWaitTransfer(ModuleName.TMRobot)) ll.StopWaitTransfer(ModuleName.TMRobot); } foreach (var pm in _lstPms) { if (pm.IsWaitTransfer(ModuleName.TMRobot)) pm.StopWaitTransfer(ModuleName.TMRobot); } if (!_tmRobot.IsAvailable) return; var act = tmRobotActions.Peek(); act.Invoke(); if (!_tmRobot.IsAvailable) return; if (act == MonitorTMRobotLoadLockTask && _lstLls.Any(x => !x.IsAvailable)) return; tmRobotActions.Enqueue(tmRobotActions.Dequeue()); //MonitorTMRobotPMATask(); //if (!_tmRobot.IsAvailable) // return; //MonitorTMRobotPMBTask(); //if (!_tmRobot.IsAvailable) // return; //MonitorTMRobotLoadLockTask(); } private void MonitorTMRobotLoadLockTask() { if (!_tmRobot.IsAvailable) return; //place to loadlock { bool blade1HasWafer = _tmRobot.Blade1Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0); bool blade2HasWafer = _tmRobot.Blade2Enable && WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1); if (blade1HasWafer || blade2HasWafer) { Hand placeBlade = blade1HasWafer ? Hand.Blade1 : Hand.Blade2; foreach (var ll in _lstLls) { if (!ll.IsAvailable) continue; var slot = GetSlotCouldBePlace(ll.Module); if (slot != null && ll.IsReadyForPlace(ModuleName.TMRobot, placeBlade, (int)slot)) { if (_tmRobot.Place(ll.Module, (int)slot, placeBlade, 0, 0, false)) { ll.WaitTransfer(ModuleName.TMRobot); return; } } } } } } private void MonitorTMRobotPMATask() { if (!_tmRobot.IsAvailable) return; //pick from pm { bool blade1Empty = _tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0); bool blade2Empty = _tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1); if (blade1Empty || blade2Empty) { Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2; //foreach (var pm in _lstPms) { var pm = _pm1; if (!pm.IsAvailable) return; var slot = GetWaferCouldBeReturn(pm.Module); if (slot != null /*&& pm.IsReadyForPick(ModuleName.TMRobot, pickBlade, (int)slot)*/) { if (_tmRobot.Pick(pm.Module, (int)slot, pickBlade, 0, 0, false)) { pm.WaitTransfer(ModuleName.TMRobot); return; } } } } } } private void MonitorTMRobotPMBTask() { if (!_tmRobot.IsAvailable) return; //pick from pm { bool blade1Empty = _tmRobot.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0); bool blade2Empty = _tmRobot.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 1); if (blade1Empty || blade2Empty) { Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2; //foreach (var pm in _lstPms) { var pm = _pm2; if (!pm.IsAvailable) return; var slot = GetWaferCouldBeReturn(pm.Module); if (slot != null /*&& pm.IsReadyForPick(ModuleName.TMRobot, pickBlade, (int)slot)*/) { if (_tmRobot.Pick(pm.Module, (int)slot, pickBlade, 0, 0, false)) { pm.WaitTransfer(ModuleName.TMRobot); return; } } } } } } private bool MonitorTaskDone() { foreach (var positions in _checkPosition) { for (int i = 0; i < positions.Value; i++) { if (CheckWaferCouldBeReturn(positions.Key, i)) { return false; } } } foreach (var lp in _lstLps) { if (!lp.IsAvailable) return false; } if (!_tmRobot.IsAvailable) return false; if (!_efem.IsAvailable) return false; return true; } private void MonitorPMTask() { foreach (var pm in _lstPms) { if (!pm.IsAvailable) continue; var wafers = WaferManager.Instance.GetWafers(pm.Module); for (int i = 0; i < wafers.Length; i++) { if (!pm.IsAvailable) break; if (CheckWaferCouldBeReturn(pm.Module, i)) { if (!pm.IsReadyForPick(ModuleName.TMRobot, Hand.Blade1, i)) { pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, i); } } } } } private void MonitorEfemRobotTask() { if (!_efem.IsAvailable) return; //efem robot is idle, release all the target if (_aligner.IsWaitTransfer(ModuleName.EfemRobot)) _aligner.StopWaitTransfer(ModuleName.EfemRobot); foreach (var ll in _lstLls) { if (ll.IsWaitTransfer(ModuleName.EfemRobot)) ll.StopWaitTransfer(ModuleName.EfemRobot); } foreach (var lp in _lstLps) { if (lp.IsWaitTransfer(ModuleName.EfemRobot)) lp.StopWaitTransfer(ModuleName.EfemRobot); } MonitorEfemRobotAlignerTask(); if (!_efem.IsAvailable) return; MonitorEfemRobotLoadLockTask(); MonitorEfemRobotLoadPortTask(); } private void MonitorEfemRobotLoadPortTask() { if (!_efem.IsAvailable) return; //place bool blade0HasWaferAndProcessed = _efem.Blade1Enable && CheckWaferCouldBeReturn(ModuleName.EfemRobot, 0); bool blade1HasWaferAndProcessed = _efem.Blade2Enable && CheckWaferCouldBeReturn(ModuleName.EfemRobot, 1); if (blade0HasWaferAndProcessed || blade1HasWaferAndProcessed) { Hand placeBlade = blade0HasWaferAndProcessed ? Hand.Blade1 : Hand.Blade2; if (blade0HasWaferAndProcessed && blade1HasWaferAndProcessed) { if (WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 1).OriginSlot < WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).OriginSlot) { placeBlade = Hand.Blade2; } } SlotItem destination = GetWaferReturnLoadPort(ModuleName.EfemRobot, (int)placeBlade); if (destination != null) { SchedulerLoadPort lp = (SchedulerLoadPort)GetModule(destination.Module.ToString()); if (lp.IsReadyForPlace(ModuleName.EfemRobot, Hand.Blade1, destination.Slot)) { if (_efem.Place(destination.Module, destination.Slot, (Hand)placeBlade)) { lp.WaitTransfer(ModuleName.EfemRobot); return; } } } } } private void MonitorEfemRobotLoadLockTask() { if (!_efem.IsAvailable) return; foreach (var ll in _lstLls) { if (!ll.IsAvailable) continue; { bool blade1Empty = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0); bool blade2Empty = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1); if (blade1Empty || blade2Empty) { Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2; var slot = GetWaferCouldBeReturn(ll.Module); if (slot != null) { if (ll.IsReadyForPick(ModuleName.EfemRobot, pickBlade, (int)slot)) { if (_efem.Pick(ll.Module, (int)slot, pickBlade)) { ll.WaitTransfer(ModuleName.EfemRobot); return; } } } } } } } private void MonitorEfemRobotAlignerTask() { if (!_efem.IsAvailable) return; if (!_aligner.IsAvailable) return; //pick from aligner if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner, 0)) { bool blade1Empty = _efem.Blade1Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0); bool blade2Empty = _efem.Blade2Enable && WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1); if (blade1Empty || blade2Empty) { Hand pickBlade = blade1Empty ? Hand.Blade1 : Hand.Blade2; if (_aligner.IsReadyForPick(ModuleName.EfemRobot, pickBlade, 0)) { if (_efem.Pick(_aligner.Module, 0, pickBlade)) { _aligner.WaitTransfer(ModuleName.EfemRobot); return; } } } } } private int? GetWaferCouldBeReturn(ModuleName module) { var wafers = WaferManager.Instance.GetWafers(module); for (int i = 0; i < wafers.Length; i++) { if (CheckWaferCouldBeReturn(wafers[i])) return i; } return null; } private int? GetSlotCouldBePlace(ModuleName module) { var wafers = WaferManager.Instance.GetWafers(module); for (int i = 0; i < wafers.Length; i++) { if (wafers[i].IsEmpty) return i; } return null; } private bool CheckWaferCouldBeReturn(WaferInfo wafer) { if (!wafer.IsEmpty) { return ModuleHelper.IsLoadPort((ModuleName)wafer.OriginStation) && wafer.Status != WaferStatus.Dummy && WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot); } return false; } private bool CheckWaferCouldBeReturn(ModuleName module, int slot) { WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot); if (!wafer.IsEmpty) { return ModuleHelper.IsLoadPort((ModuleName)wafer.OriginStation) && wafer.Status != WaferStatus.Dummy && WaferManager.Instance.CheckNoWafer((ModuleName)wafer.OriginStation, wafer.OriginSlot); } return false; } private SlotItem GetWaferReturnLoadPort(ModuleName module, int slot) { WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot); if (!wafer.IsEmpty) { return new SlotItem((ModuleName)wafer.OriginStation, wafer.OriginSlot); } return null; } } }