Browse Source

Change the PreClean/PostClean design.

sangwq 9 months ago
parent
commit
260120e0d5
1 changed files with 119 additions and 58 deletions
  1. 119 58
      Venus/Venus_RT/Modules/VenusDispatcher.cs

+ 119 - 58
Venus/Venus_RT/Modules/VenusDispatcher.cs

@@ -37,11 +37,12 @@ namespace Venus_RT.Modules
 
     class VenusPMTask : ModuleTask
     {
-        enum RecipeJobType
+        public enum RecipeJobType
         {
             PreClean,
             Process,
             PostClean,
+            WtwClean,
         }
 
         public override int TimeToReady
@@ -54,6 +55,7 @@ namespace Venus_RT.Modules
                     case ModuleStatus.IdleClean:
                     case ModuleStatus.PreJobClean:
                     case ModuleStatus.PostJobClean:
+                    case ModuleStatus.WTWClean:
                     case ModuleStatus.Processing:
                         {
                             return Scheduler.IsAvailable ? 0 : (Scheduler.TimeToReady + 500) / 1000;
@@ -110,7 +112,7 @@ namespace Venus_RT.Modules
                                     }
                                     else
                                     {
-                                        LOG.Write(eEvent.WARN_ROUTER, Module, $"Run Prejob clean recipe{_runingWaferTask.Value.First().Value} failed");
+                                        LOG.Write(eEvent.WARN_ROUTER, Module, $"Run Prejob clean recipe {_runingWaferTask.Value.First().Value} failed");
                                         TryDequeueRuningTask(Status);
                                         Status = ModuleStatus.Idle;
                                     }
@@ -143,7 +145,24 @@ namespace Venus_RT.Modules
                                     }
                                     else
                                     {
-                                        LOG.Write(eEvent.WARN_ROUTER, Module, $"Run Postjob clean recipe{_runingWaferTask.Value.First().Value} failed");
+                                        LOG.Write(eEvent.WARN_ROUTER, Module, $"Run Postjob clean recipe {_runingWaferTask.Value.First().Value} failed");
+                                        TryDequeueRuningTask(Status);
+                                        Status = ModuleStatus.Idle;
+                                    }
+                                }
+                            }
+                            break;
+                        case RecipeJobType.WtwClean:
+                            {
+                                if (WaferManager.Instance.CheckNoWafer(Module, 0))
+                                {
+                                    if (_pmScheduler.RunJobCleanTask(_runingWaferTask.Value.First().Value))
+                                    {
+                                        Status = ModuleStatus.StartWTWClean;
+                                    }
+                                    else
+                                    {
+                                        LOG.Write(eEvent.WARN_ROUTER, Module, $"Run WTW clean recipe {_runingWaferTask.Value.First().Value} failed");
                                         TryDequeueRuningTask(Status);
                                         Status = ModuleStatus.Idle;
                                     }
@@ -180,12 +199,8 @@ namespace Venus_RT.Modules
                             }
                             break;
                         case ModuleStatus.PreJobClean:
-                            {
-                                TryDequeueRuningTask(Status);
-                                Status = ModuleStatus.Idle;
-                            }
-                            break;
                         case ModuleStatus.PostJobClean:
+                        case ModuleStatus.WTWClean:
                             {
                                 TryDequeueRuningTask(Status);
                                 Status = ModuleStatus.Idle;
@@ -222,6 +237,9 @@ namespace Venus_RT.Modules
                         case ModuleStatus.StartPostJobClean:
                             Status = ModuleStatus.PostJobClean;
                             break;
+                        case ModuleStatus.StartWTWClean:
+                            Status = ModuleStatus.WTWClean;
+                            break;
                     }
                 }
             }
@@ -257,13 +275,18 @@ namespace Venus_RT.Modules
                             bMatch = true;  
                         }
                         break;
-                    case ModuleStatus.WaitPreJobClean:
-                        _runingWaferTask.Value.Dequeue();
+                    case ModuleStatus.WTWClean:
+                        if(_runingWaferTask.Value.First().Key == RecipeJobType.WtwClean)
+                        {
+                            _runingWaferTask.Value.Dequeue();
+                            bMatch = true;
+                        }
                         break;
+                    case ModuleStatus.WaitPreJobClean:
                     case ModuleStatus.WaitProcess:
-                        _runingWaferTask.Value.Dequeue();
-                        break;
                     case ModuleStatus.WaitPostJobClean:
+                    case ModuleStatus.WaitWTWClean:
+                    case ModuleStatus.Idle:
                         _runingWaferTask.Value.Dequeue();
                         break;
                 }
@@ -272,7 +295,7 @@ namespace Venus_RT.Modules
             if(!bMatch)
             {
                 string runingTask = _runingWaferTask.Value.Count > 0 ? _runingWaferTask.Value.First().ToString() : "Empty";
-                LOG.Write(eEvent.WARN_ROUTER, Module, $"PM Status: {status}, runing task : {runingTask}");
+                LOG.Write(eEvent.WARN_ROUTER, Module, $"TryDequeueRuningTask() failed, PM Status: {status}, runing task : {runingTask}");
             }
         }
 
@@ -288,36 +311,63 @@ namespace Venus_RT.Modules
 
         public void SubscribeWaferTask(WaferTask waferTask)
         {
-            var venusWaferTask = waferTask as  VenusWaferTask;
             var waferRecipes = new Queue<KeyValuePair<RecipeJobType, string>>();
-            if (!string.IsNullOrWhiteSpace(venusWaferTask.preCleanRecipe))
+
+            if (!string.IsNullOrWhiteSpace(waferTask.processRecipe))
             {
-                waferRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(RecipeJobType.PreClean, venusWaferTask.preCleanRecipe));
+                waferRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(RecipeJobType.Process, waferTask.processRecipe));
             }
 
-            if (!string.IsNullOrWhiteSpace(venusWaferTask.processRecipe))
+            if (!string.IsNullOrWhiteSpace(waferTask.wtwCleanRecipe))
             {
-                waferRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(RecipeJobType.Process, venusWaferTask.processRecipe));
+                waferRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(RecipeJobType.WtwClean, waferTask.wtwCleanRecipe));
             }
 
-            if (!string.IsNullOrWhiteSpace(venusWaferTask.postCleanRecipe))
+            if(_runingWaferTask.Key == waferTask.waferId || _pendingWaferTasks.ToList().Exists(kv => kv.Key == waferTask.waferId))
             {
-                waferRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(RecipeJobType.PostClean, venusWaferTask.postCleanRecipe));
+                LOG.Write(eEvent.WARN_ROUTER, Module, $"wafer {waferTask.sourceMod}.{waferTask.sourceSlot + 1} already subscribe job task.");
             }
+            else if (_runingWaferTask.Key == Guid.Empty || _runingWaferTask.Value.Count == 0)
+            {
+                _runingWaferTask = new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(waferTask.waferId, waferRecipes);
+            }
+            else
+            {
+                _pendingWaferTasks.Enqueue(new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(waferTask.waferId, waferRecipes));
+            }
+        }
 
-            if(_runingWaferTask.Key == venusWaferTask.waferId || _pendingWaferTasks.ToList().Exists(kv => kv.Key == venusWaferTask.waferId))
+        public void SubscribeLotCleanTask(ControlJobInfo cj, RecipeJobType cleanType)
+        {
+            var lotCleanRecipes = new Queue<KeyValuePair<RecipeJobType, string>>();
+
+            if(cleanType == RecipeJobType.PreClean && !string.IsNullOrWhiteSpace(cj.PreJobClean))
             {
-                LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, $"wafer {venusWaferTask.sourceMod}.{venusWaferTask.sourceSlot + 1} already subscribe job task.");
+                lotCleanRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(cleanType, cj.PreJobClean));
+            }
+            else if(cleanType == RecipeJobType.PostClean && !string.IsNullOrWhiteSpace (cj.PostJobClean))
+            {
+                lotCleanRecipes.Enqueue(new KeyValuePair<RecipeJobType, string>(cleanType, cj.PostJobClean));
+            }
+            else
+            {
+                return;
+            }
+
+            if ((_runingWaferTask.Key == cj.InnerId && _runingWaferTask.Value.ToList().Exists(pv => pv.Key == cleanType)) || _pendingWaferTasks.ToList().Exists(task => task.Key == cj.InnerId && task.Value.ToList().Exists(pv => pv.Key == cleanType)))
+            {
+                LOG.Write(eEvent.WARN_ROUTER, Module, $"Control job {cj.Name} already subscribe {cleanType} task.");
             }
             else if (_runingWaferTask.Key == Guid.Empty || _runingWaferTask.Value.Count == 0)
             {
-                _runingWaferTask = new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(venusWaferTask.waferId, waferRecipes);
+                _runingWaferTask = new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(cj.InnerId, lotCleanRecipes);
             }
             else
             {
-                _pendingWaferTasks.Enqueue(new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(venusWaferTask.waferId, waferRecipes));
+                _pendingWaferTasks.Enqueue(new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(cj.InnerId, lotCleanRecipes));
             }
         }
+
         public bool ReadyMoveIn(WaferTask wafer)
         {
             return _runingWaferTask.Key == wafer.waferId && _runingWaferTask.Value.Count > 0 && _runingWaferTask.Value.First().Key == RecipeJobType.Process;
@@ -331,8 +381,6 @@ namespace Venus_RT.Modules
             _pendingWaferTasks.Clear();
             _runingWaferTask = new KeyValuePair<Guid, Queue<KeyValuePair<RecipeJobType, string>>>(Guid.Empty, new Queue<KeyValuePair<RecipeJobType, string>>());
         }
-
-
     }
 
     class PreAlignTask : ModuleTask
@@ -380,31 +428,6 @@ namespace Venus_RT.Modules
         }
     }
 
-    public class VenusWaferTask : WaferTask
-    {
-        public string preCleanRecipe { get; }
-        public string postCleanRecipe { get; }
-        public VenusWaferTask(ModuleName source, 
-                                int srcSlot, 
-                                ModuleName dest, 
-                                int dstSlot, 
-                                float temp, 
-                                Guid waferID, 
-                                string recipeName, 
-                                string wtwClean, 
-                                SequenceLLInOutPath inOutPath,
-                                int LLDelay, 
-                                bool needAlign
-                                //string preClean, 
-                                //string postClean
-                                ) 
-                                : base(source, srcSlot, dest, dstSlot, temp, waferID, recipeName, wtwClean, inOutPath, LLDelay, needAlign)
-        {
-            //preCleanRecipe = preClean;
-            //postCleanRecipe = postClean;
-        }
-    }
-
     class VenusTMRobotTask : ModuleTask
     {
         public VenusTMRobotTask(ModuleName mod) : base(mod) { }
@@ -422,7 +445,7 @@ namespace Venus_RT.Modules
         private List<ControlJobInfo> _lstControlJobs = new List<ControlJobInfo>();
         private List<ProcessJobInfo> _lstProcessJobs = new List<ProcessJobInfo>();
 
-        private List<VenusWaferTask> _lstWaferTasks = new List<VenusWaferTask>();
+        private List<WaferTask> _lstWaferTasks = new List<WaferTask>();
         private Dictionary<ModuleName, ModuleTask> _dictModuleTask = new Dictionary<ModuleName, ModuleTask>();
         private Queue<WaferInfo> _qeReturnWafers = new Queue<WaferInfo>();
 
@@ -1623,6 +1646,17 @@ namespace Venus_RT.Modules
 
                 if (IsAllProcessJobComplete(runingjob))
                 {
+                    // subscribe clean task
+                    var PMs = GetWaitPreCleanPMsByCtrlJob(runingjob);
+                    foreach (var pm in PMs)
+                    {
+                        var pmTask = _dictModuleTask[pm] as VenusPMTask;
+                        if (pmTask != null && pmTask.Scheduler.IsOnline)
+                        {
+                            pmTask.SubscribeLotCleanTask(runingjob, VenusPMTask.RecipeJobType.PostClean);
+                        }
+                    }
+
                     runingjob.SetState(EnumControlJobState.Completed);
                     runingjob.EndTime = DateTime.Now;
 
@@ -1642,6 +1676,17 @@ namespace Venus_RT.Modules
                 if (runingJobs.Count == 0 || (runingJobs.Count == 1 && IsAllJobWaferProcessedOrProcessing(runingJobs.First())))
                 {
                     ActiveControlJob(pendingJobs.First());
+
+                    // subscribe clean task
+                    var PMs = GetWaitPreCleanPMsByCtrlJob(pendingJobs.First());
+                    foreach (var pm in PMs)
+                    {
+                        var pmTask = _dictModuleTask[pm] as VenusPMTask;
+                        if (pmTask != null && pmTask.Scheduler.IsOnline)
+                        {
+                            pmTask.SubscribeLotCleanTask(pendingJobs.First(), VenusPMTask.RecipeJobType.PreClean);
+                        }
+                    }
                 }
             }
 
@@ -1882,20 +1927,17 @@ namespace Venus_RT.Modules
                 temperature = temp;
             }
 
-            var waferTask = new VenusWaferTask((ModuleName)wafer.OriginStation,
+            var waferTask = new WaferTask((ModuleName)wafer.OriginStation,
                                             wafer.OriginSlot,
                                             pm,
                                             0,
                                             temperature,
                                             wafer.InnerId,
                                             recipeName,
-                                            String.Empty,
+                                            wafer.ProcessJob.Sequence.WTWCleanRecipe,
                                             wafer.ProcessJob.Sequence.LLInOutPath,
                                             wafer.ProcessJob.Sequence.LLDelayTime,
-                                            IsSequenceNeedAlign(wafer.ProcessJob.Sequence)
-                                            //wafer.ProcessJob.Sequence.PreWaferCleanRecipe,  // pre clean
-                                            //wafer.ProcessJob.Sequence.PostWaferCleanRecipe
-                                            );  // post clean
+                                            IsSequenceNeedAlign(wafer.ProcessJob.Sequence));  // post clean
 
             waferTask.OnWaferArrived += WaferArrived;
             waferTask.OnWaferLeaved += WaferLeaved;
@@ -1997,6 +2039,25 @@ namespace Venus_RT.Modules
             reason = "";
             return true;
         }
+
+        private List<ModuleName> GetWaitPreCleanPMsByCtrlJob(ControlJobInfo cj)
+        {
+            var pmlist = new List<ModuleName>();
+            foreach (var pj in _lstProcessJobs)
+            {
+                if (pj.ControlJobName == cj.Name)
+                {
+                    foreach (var pm in pj.Sequence.PMs)
+                    {
+                        if (!pmlist.Contains(pm))
+                            pmlist.Add(pm);
+                    }
+                }
+            }
+
+            return pmlist;
+        }
+
         #endregion
     }
 }