Browse Source

Manual Return wafer while running cycle.

sangwq 1 year ago
parent
commit
e61f018b66

+ 133 - 11
Venus/Venus_RT/Modules/AutoCycle.cs

@@ -653,10 +653,11 @@ namespace Venus_RT.Modules
 
         private void driveVacSystem()
         {
-            //PumpingTMRobotTask();
-            //ProcessTMRobotTask();
-            RoutingInnerPart();
-            RuningTMRobotTask();
+            if (_tmRobot.IsAvailable && _movingItems.Count == 0 && _tmRobot.RobotStatus != RState.Running)
+            {
+                RoutingInnerPart();
+                RuningTMRobotTask();
+            }
         }
 
         #region Vacuum System
@@ -1265,9 +1266,74 @@ namespace Venus_RT.Modules
             return _movingItems.Count > 0;
         }
 
+        private bool ProcessVacManaulReturnWafers()
+        {
+            if (_lstReturnWafers.Count == 0)
+                return false;
+
+            Queue<SlotItem> returnSlots = new Queue<SlotItem>();
+            for(int i = 0;  i< 2; i++)
+            {
+                if(WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, i))
+                {
+                    var wafer_id = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).InnerId;
+                    if(_lstReturnWafers.FindIndex(item => item == wafer_id) != -1)
+                    {
+                        returnSlots.Enqueue(new SlotItem(ModuleName.TMRobot, i));
+                    }
+                }
+            }
+
+            foreach(var mod in _vacModules)
+            {
+                if(ModuleHelper.IsPm(mod.Key) && WaferManager.Instance.CheckHasWafer(mod.Key, 0) && _vacSchedulers[mod.Key].IsIdle)
+                {
+                    var wafer_id = WaferManager.Instance.GetWafer(mod.Key, 0).InnerId;
+                    if(_lstReturnWafers.FindIndex(item => item == wafer_id) != -1)
+                    {
+                        returnSlots.Enqueue(new SlotItem(mod.Key, 0));
+                    }
+                }
+            }
+
+            if (returnSlots.Count == 0)
+                return false;
+
+            var llaSlotStatus = GetLLProcessStatusCount(ModuleName.LLA);
+            var llbSlotStatus = GetLLProcessStatusCount(ModuleName.LLB);
+
+            ModuleName destLL = ModuleName.System;
+            if (IsLoadReadyForTM(ModuleName.LLA) && llaSlotStatus.empty > 0 && (!IsLoadReadyForTM(ModuleName.LLB) || (!_vacSchedulers[ModuleName.LLB].IsVac && llaSlotStatus.empty == llbSlotStatus.empty) || llaSlotStatus.empty > llbSlotStatus.empty))
+            {
+                destLL = ModuleName.LLA;
+            }
+            else if(IsLoadReadyForTM(ModuleName.LLB) && llbSlotStatus.empty > 0)
+            {
+                destLL = ModuleName.LLB;
+            }
+
+            if(destLL != ModuleName.System)
+            {
+                int slotNumber = destLL == ModuleName.LLA ? _LLASlotNumber : _LLBSlotNumber;
+                for(int i = 0; i < slotNumber; i++)
+                {
+                    if(WaferManager.Instance.CheckNoWafer(destLL, i))
+                    {
+                        if (_movingItems.Count >= 2 || returnSlots.Count == 0)
+                            break;
+
+                        var source = returnSlots.Dequeue();
+                        _movingItems.Add(new MoveItem(source.Module, source.Slot, destLL, i, Hand.None));
+                    }
+                }
+            }
+
+            return _movingItems.Count > 0;
+        }
+
         private void RoutingInnerPart()
         {
-            if (_tmRobot.RobotStatus == RState.Running || !_tmRobot.IsAvailable)
+            if (ProcessVacManaulReturnWafers())
                 return;
 
             if (PushTMRobotWafers())
@@ -1334,7 +1400,7 @@ namespace Venus_RT.Modules
 
         private void RuningTMRobotTask()
         {
-            if (_tmRobot.IsAvailable && _movingItems.Count > 0)
+            if (_movingItems.Count > 0)
             {
                 if (_tmRobot.PostMoveItems(_movingItems.ToArray()))
                 {
@@ -1346,7 +1412,7 @@ namespace Venus_RT.Modules
                         {
                             // post alarm
                             _cycleState = RState.Failed;
-                            LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Cannot run TM moving task as Get {item.SourceModule}{item.SourceModule} Wafer Info failed");
+                            LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Cannot run TM moving task as Get {item.SourceModule}{item.SourceSlot} Wafer Info failed");
                             return;
                         }
 
@@ -1553,7 +1619,10 @@ namespace Venus_RT.Modules
 
         private void PumpingEFEMRobotTask()
         {
-            var aligners = _atmSchedulers.Select(x => x).Where(x => ModuleHelper.IsAligner(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
+            if (ProcessAtmManaulReturnWafers())
+                return;
+
+            var aligners = _atmSchedulers.Where(x => ModuleHelper.IsAligner(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
             foreach (var aligner in aligners)
             {
                 if (_atmModules[aligner.Key].MovingStatus != MovingStatus.Idle)
@@ -1567,14 +1636,14 @@ namespace Venus_RT.Modules
                     return;
             }
 
-            var lls = _atmSchedulers.Select(x => x).Where(x => ModuleHelper.IsLoadLock(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
+            var lls = _atmSchedulers.Where(x => ModuleHelper.IsLoadLock(x.Key) && x.Value.IsAvailable && !IsLoadLockReservedByTM(x.Key)).ToDictionary(k => k.Key, v => v.Value);
             foreach(var ll in lls)
             {
                 if (ProcessLLEFEMRobotTask(ll.Key))
                     return;
             }
 
-            var lps = _atmSchedulers.Select(x => x).Where(x => ModuleHelper.IsLoadPort(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
+            var lps = _atmSchedulers.Where(x => ModuleHelper.IsLoadPort(x.Key) && x.Value.IsAvailable).ToDictionary(k => k.Key, v => v.Value);
             foreach(var lp in lps)
             {
                 if (ProcessLPEFEMRobotTask(lp.Key))
@@ -1623,6 +1692,9 @@ namespace Venus_RT.Modules
             if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
                 return false;
 
+            if (_lstReturnWafers.Contains(wafer.InnerId))
+                return false;
+
             if (wafer.NextSequenceStep == wafer.ProcessJob.Sequence.Steps.Count)
             {
                 // need return
@@ -1651,7 +1723,7 @@ namespace Venus_RT.Modules
         }
         private bool ProcessLLEFEMRobotTask(ModuleName ll)
         {
-            if (_vacModules[ll].MovingStatus != MovingStatus.Idle || IsLoadLockReservedByTM(ll))
+            if (_vacModules[ll].MovingStatus != MovingStatus.Idle)
                 return false;
 
             var robotSlots = GetEfemRobotWaferReadyInHands(ll);
@@ -1790,6 +1862,11 @@ namespace Venus_RT.Modules
             return _vacSchedulers[ll].IsAvailable && _vacModules[ll].MovingStatus == MovingStatus.Idle && !IsLoadLockReservedByEFEM(ll);
         }
 
+        private bool IsLoadLockReadyForEFEMManualMove(ModuleName ll)
+        {
+            return (_vacSchedulers[ll].IsIdle && !_vacSchedulers[ll].IsOnline) || (_vacSchedulers[ll].IsAvailable && _vacModules[ll].MovingStatus == MovingStatus.Idle && !IsLoadLockReservedByTM(ll));
+        }
+
         private bool IsPMKeepEmpty(ModuleName pm)
         {
             return WaferManager.Instance.CheckNoWafer(pm, 0) && _movingItems.FindIndex(item => item.DestinationModule == pm) == -1;
@@ -2200,6 +2277,51 @@ namespace Venus_RT.Modules
             }
         }
 
+        private bool ProcessAtmManaulReturnWafers()
+        {
+            if (_lstReturnWafers.Count == 0)
+                return false;
+
+            for(int i = 0; i < 2; i++)
+            {
+                if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, i))
+                {
+                    var wafer = WaferManager.Instance.GetWafer(ModuleName.EfemRobot, i);
+                    if (_lstReturnWafers.FindIndex(id => id == wafer.InnerId) != -1)
+                    {
+                        _efemMovingItems.Add(new MoveItem(ModuleName.EfemRobot, i, (ModuleName)wafer.OriginStation, wafer.OriginSlot, (Hand)i));
+                        _lstReturnWafers.Remove(wafer.InnerId);
+                    }
+                }
+            }
+
+            if (_efemMovingItems.Count > 0)
+                return true;
+
+            var lls = _atmSchedulers.Where(x => ModuleHelper.IsLoadLock(x.Key) && IsLoadLockReadyForEFEMManualMove(x.Key)).ToDictionary(k => k.Key, v => v.Value);
+            foreach (var ll in lls)
+            {
+                int slotNumber = ll.Key == ModuleName.LLA ? _LLASlotNumber : _LLBSlotNumber;
+                for(int i = 0; i < slotNumber; i++)
+                {
+                    if (_efemMovingItems.Count >= 2)
+                        return true;
+
+                    if(WaferManager.Instance.CheckHasWafer(ll.Key, i))
+                    {
+                        var wafer = WaferManager.Instance.GetWafer(ll.Key, i);
+                        var robotHand = GetEFEMRobotFreeHand();
+                        if (robotHand != Hand.None && _lstReturnWafers.FindIndex(id => id == wafer.InnerId) != -1)
+                        {
+                            _efemMovingItems.Add(new MoveItem(ll.Key, i, ModuleName.EfemRobot, (int)robotHand, robotHand));
+                        }
+                    }
+                }
+            }
+
+            return _efemMovingItems.Count > 0;
+        }
+
         #endregion Atm System
 
         #region Sequence validation

+ 1 - 1
Venus/Venus_RT/Modules/EFEM/EfemSwapRoutine.cs

@@ -194,7 +194,7 @@ namespace Venus_RT.Modules.EFEM
             }
             else
             {
-                LOG.Write(eEvent.ERR_EFEM_ROBOT, ModuleName.TM, $"Invalid move parameter, source:{_currentAction.SourceModule},{_currentAction.SourceSlot}, destination: {_currentAction.DestinationModule}, {_currentAction.DestinationSlot}");
+                LOG.Write(eEvent.ERR_EFEM_ROBOT, ModuleName.EfemRobot, $"Invalid move parameter, source:{_currentAction.SourceModule},{_currentAction.SourceSlot}, destination: {_currentAction.DestinationModule}, {_currentAction.DestinationSlot}");
                 return false;
             }
         }

+ 6 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerAligner.cs

@@ -31,6 +31,12 @@ namespace Venus_RT.Modules.Schedulers
             get { return _entity.IsError; }
 
         }
+
+        public override bool IsIdle
+        {
+            get { return _entity.IsIdle; }
+        }
+
         private EfemEntity _entity = null;
         private bool _isCooling;
 

+ 5 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerEfemRobot.cs

@@ -42,6 +42,11 @@ namespace Venus_RT.Scheduler
 
         }
 
+        public override bool IsIdle
+        {
+            get { return _entity.IsIdle; }
+        }
+
         public RState RobotStatus
         {
             get { return _entity.RobotStatus; }

+ 5 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerLoadLock.cs

@@ -31,6 +31,11 @@ namespace Venus_RT.Modules.Schedulers
 
         }
 
+        public override bool IsIdle
+        {
+            get { return _entity.IsIdle; }
+        }
+
         public override bool IsVac
         {
             get { return _entity.IsVac; }

+ 5 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerLoadPort.cs

@@ -32,6 +32,11 @@ namespace Venus_RT.Modules.Schedulers
 
         }
 
+        public override bool IsIdle
+        {
+            get { return _entity.IsIdle; }
+        }
+
         public bool IsLoaded
         {
             get { return _entity.EfemDevice[Module].IsLoaded; }

+ 1 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerModule.cs

@@ -96,6 +96,7 @@ namespace Venus_RT.Scheduler
         }
         public virtual bool IsAvailable { get; }
         public virtual bool IsOnline { get; }
+        public virtual bool IsIdle { get; }
         public virtual bool IsError { get; }
         public virtual bool IsAtm { get { return true; } }
         public virtual bool IsVac { get { return false; } }

+ 3 - 3
Venus/Venus_RT/Modules/Schedulers/SchedulerPM.cs

@@ -44,10 +44,10 @@ namespace Venus_RT.Scheduler
             get { return _entity.IsError; }
 
         }
-        public bool IsIdle
-        {
-            get { return _entity.IsIdle && _entity.IsOnline && CheckTaskDone() ; }
 
+        public override bool IsIdle
+        {
+            get { return _entity.IsIdle; }
         }
 
         public override bool IsVac

+ 6 - 0
Venus/Venus_RT/Modules/Schedulers/SchedulerTMRobot.cs

@@ -35,6 +35,12 @@ namespace Venus_RT.Modules.Schedulers
             get { return _entity.IsOnline; }
 
         }
+
+        public override bool IsIdle
+        {
+            get { return _entity.IsIdle; }
+        }
+
         public override bool IsError
         {
             get { return _entity.IsError; }