浏览代码

Develop transfer cycle.

sangwq 1 年之前
父节点
当前提交
8f9b95ae8f

+ 6 - 6
Venus/Framework/Common/Device/Unit/IoGasValve.cs

@@ -170,11 +170,11 @@ namespace Aitex.Core.RT.Device.Unit
 
             if (!TurnValve(op, out string reason))
             {
-                EV.PostWarningLog(Module, $"Can not {name} valve {Module}.{Name}, {reason}");
+                LOG.Write(eEvent.WARN_IO_VALVE, Module, $"Can not {name} valve {Module}.{Name}, {reason}");
                 return false;
             }
 
-            //EV.PostInfoLog(Module, $"{name} valve {Module}.{Name}");
+            LOG.Write(eEvent.INFO_IO_VALVE, Module, $"{name} valve {Module}.{Name}");
 
             return true;
         }
@@ -193,13 +193,13 @@ namespace Aitex.Core.RT.Device.Unit
                         {
                             if (_operation)
                             {
-                                EV.PostAlarmLog(Module,eEvent.ERR_IoGasValve, _doOpen.Check(_isNc ? true : false, out string reason) ?
+                                LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
                                         $"{Display} open: valve keep closed" :
                                         $"{Display} Fail to open due to interlock {reason}");
                             }
                             else
                             {
-                                EV.PostAlarmLog(Module, eEvent.ERR_IoGasValve, _doOpen.Check(_isNc ? true : false, out string reason) ?
+                                LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
                                     $"{Display} Close : Valve keep open" :
                                     $"{Display} Close : Failed for interlock {reason}");
                             }
@@ -213,13 +213,13 @@ namespace Aitex.Core.RT.Device.Unit
                         {
                             if (_operation)
                             {
-                                EV.PostAlarmLog(Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
+                                LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
                                     $"Valve {Display} was Close,Reason PLC kept" :
                                     $"Valve {Display} was Close,Reason {reason}");
                             }
                             else
                             {
-                                EV.PostAlarmLog(Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
+                                LOG.Write(eEvent.ERR_IO_VALVE, Module, _doOpen.Check(_isNc ? true : false, out string reason) ?
                                     $"Valve {Display} was Open,Reason PLC Kept" :
                                     $"Valve {Display} was Open,Reason:{reason}");
                             }

+ 2 - 2
Venus/Framework/Common/Log/LOG.cs

@@ -83,8 +83,8 @@ namespace Aitex.Core.RT.Log
                 var item3 = module.ToString();
 
                 StringBuilder text = new StringBuilder();
-                text.Append(((int)item1).ToString().PadLeft(6));
-                text.Append(item3.PadLeft(8));
+                text.Append(((int)item1).ToString().PadLeft(8));
+                text.Append(item3.PadLeft(12));
                 text.Append("    ");
                 text.Append(string.Format(logItem.GlobalDescription_zh, values));              
                 string message = text.ToString();

+ 3 - 0
Venus/Venus_Core/EventDefine.cs

@@ -64,6 +64,9 @@ namespace Aitex.Core.RT.Log{
 		ERR_Sensor = 1028,
 		INFO_FA = 1029,
 		INFO_IOCYLINDER = 1030,
+		INFO_IO_VALVE = 1031,
+		WARN_IO_VALVE = 1032,
+		ERR_IO_VALVE = 1033,
 		ERR_TM = 2000,
 		INFO_TM = 2001,
 		WARN_TM = 2002,

+ 27 - 0
Venus/Venus_RT/Config/LogDefine.json

@@ -568,6 +568,33 @@
     "Note": "Cylinder INFO"
   },
   {
+    "Id": 1031,
+    "Level": "Info",
+    "LogEnum": "INFO_IO_VALVE",
+    "GlobalDescription_zh": "IO Valve: {0}",
+    "GlobalDescription_en": "IO Valve: {0}",
+    "Module": "PM",
+    "Note": "IO Valve:  Info"
+  },
+  {
+    "Id": 1032,
+    "Level": "Warning",
+    "LogEnum": "WARN_IO_VALVE",
+    "GlobalDescription_zh": "IO Valve: {0}",
+    "GlobalDescription_en": "IO Valve: {0}",
+    "Module": "PM",
+    "Note": "IO Valve:  Warning"
+  },
+  {
+    "Id": 1033,
+    "Level": "Error",
+    "LogEnum": "ERR_IO_VALVE",
+    "GlobalDescription_zh": "IO Valve: {0}",
+    "GlobalDescription_en": "IO Valve: {0}",
+    "Module": "PM",
+    "Note": "IO Valve:  Alarm"
+  },
+  {
     "Id": 2000,
     "Level": "Error",
     "LogEnum": "ERR_TM",

+ 180 - 66
Venus/Venus_RT/Modules/AutoCycle.cs

@@ -87,6 +87,9 @@ namespace Venus_RT.Modules
         Dictionary<SlotItem, Guid> _vacWaferTargets = new Dictionary<SlotItem, Guid>();
         Dictionary<SlotItem, Guid> _atmWaferTargets = new Dictionary<SlotItem, Guid>();
 
+        R_TRIG _vacMoveFinishTrig = new R_TRIG();
+        R_TRIG _atmMoveFinishTrig = new R_TRIG();
+
         private SchedulerFACallback _faCallback;
         private SchedulerDBCallback _dbCallback;
 
@@ -453,6 +456,8 @@ namespace Venus_RT.Modules
 
                 //ResetTraceFlag();
             }
+
+            _cycleState = RState.Running;
         }
 
         public void Clear()
@@ -530,50 +535,7 @@ namespace Venus_RT.Modules
 
         private void epilogue()
         {
-            foreach(var mod in _vacSchedulers)
-            {
-                if(mod.Value.IsAvailable)
-                {
-                    var tars = _vacWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
-                    foreach(var tar in tars)
-                    {
-                        var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
-                        if (wafer.IsEmpty)
-                            continue;
-
-                        if(wafer.InnerId == tar.Value)
-                        {
-                            // wafer arrive
-                            _vacWaferTargets.Remove(tar.Key);
-                            wafer.NextSequenceStep++;
-                        }
-                    }
-                }
-            }
-
-            foreach(var mod in _atmSchedulers)
-            {
-                if (mod.Value.IsAvailable)
-                {
-                    var tars = _atmWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
-                    foreach (var tar in tars)
-                    {
-                        var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
-                        if (wafer.IsEmpty)
-                            continue;
-
-                        if (wafer.InnerId == tar.Value)
-                        {
-                            // wafer arrive
-                            _atmWaferTargets.Remove(tar.Key);
-
-                            if (!ModuleHelper.IsLoadPort(tar.Key.Module))
-                                wafer.NextSequenceStep++;
-                        }
-                    }
-                }
-            }
-
+            CheckWaferArrived();
             StartNewJob();
         }
 
@@ -587,6 +549,9 @@ namespace Venus_RT.Modules
         #region Vacuum System
         private void PumpingTMRobotTask()
         {
+            if (!_tmRobot.IsAvailable)
+                return;
+
             foreach(var mod in _vacSchedulers)
             {
                 if (mod.Value.IsAvailable && _vacModules[mod.Key].MovingStatus == MovingStatus.Staying)
@@ -599,7 +564,6 @@ namespace Venus_RT.Modules
                             if(WaferManager.Instance.CheckHasWafer(mod.Key, slot) && IsVacWaferReadyOut(mod.Key, slot))
                             {
                                 _vacReadyOutSlots.Add(new SlotItem(mod.Key, slot));
-                                _vacModules[mod.Key].MovingStatus = MovingStatus.Waiting;
                             }
                         }
 
@@ -609,7 +573,6 @@ namespace Venus_RT.Modules
                             if(WaferManager.Instance.CheckNoWafer(mod.Key, slot))
                             {
                                 _vacReadyInSlots.Add(new SlotItem(mod.Key, slot));
-                                _vacModules[mod.Key].MovingStatus = MovingStatus.Waiting;
                             }
                         }
                     }
@@ -618,12 +581,10 @@ namespace Venus_RT.Modules
                         if(WaferManager.Instance.CheckHasWafer(mod.Key, 0) && IsVacWaferReadyOut(mod.Key, 0))  // processed?
                         {
                             _vacReadyOutSlots.Add(new SlotItem(mod.Key, 0));
-                            _vacModules[mod.Key].MovingStatus = MovingStatus.Waiting;
                         }
-                        else
+                        else if(WaferManager.Instance.CheckNoWafer(mod.Key, 0))
                         {
                             _vacReadyInSlots.Add(new SlotItem(mod.Key, 0));
-                            _vacModules[mod.Key].MovingStatus = MovingStatus.Waiting;
                         }
                     }
                 }
@@ -634,6 +595,9 @@ namespace Venus_RT.Modules
         {
             destSlot = new SlotItem(ModuleName.System, -1);
             var wafer = WaferManager.Instance.GetWafer(outSlot.Module, outSlot.Slot);
+            if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
+                return false;
+
             foreach (var next_module in wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules)
             {
                 var validSlots = GetModuleValidSlots(next_module);
@@ -643,7 +607,7 @@ namespace Venus_RT.Modules
                         continue;
 
                     var ready_in = _vacReadyInSlots.Find(item => item.Module == next_module && item.Slot == nSlot);
-                    if (ready_in != null)
+                    if (ready_in != null && _vacModules[ready_in.Module].MovingStatus != MovingStatus.Moving)
                     {
                         destSlot.Module = ready_in.Module;
                         destSlot.Slot = nSlot;
@@ -689,24 +653,52 @@ namespace Venus_RT.Modules
             var validSlots = GetModuleValidSlots(inModule);
             foreach(var slot in _vacReadyOutSlots)
             {
-                if (slot.Module == inModule)
+                if (slot.Module == inModule && _vacModules[slot.Module].MovingStatus == MovingStatus.Moving)
                     continue;
 
                 var wafer = WaferManager.Instance.GetWafer(slot.Module, slot.Slot);
+
+                if (wafer.IsEmpty || wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null || wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
+                    continue;
+
                 foreach (var next_module in wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules)
                 {
-                    if(next_module == inModule && validSlots.Count > 0)
+                    if(next_module == inModule && validSlots.Count > 0 && !_movingItems.Exists(item => item.SourceModule == slot.Module && item.SourceSlot == slot.Slot))
                     {
-                        inSlots.Add(new MoveItem(slot.Module, slot.Slot, inModule, validSlots.First(), Hand.None) );
+                        if(!inSlots.Exists(item => item.SourceModule == slot.Module && item.SourceSlot == slot.Slot))
+                        {
+                            inSlots.Add(new MoveItem(slot.Module, slot.Slot, inModule, validSlots.First(), Hand.None));
+                        }
+                        
                         validSlots.RemoveAt(0);
                     }
                 }
-
             }
 
             return inSlots;
         }
 
+        private void UpdateItemMovingStatus(MoveItem moveItem, MovingStatus status = MovingStatus.Moving)
+        {
+            if(!ModuleHelper.IsTMRobot(moveItem.DestinationModule))
+            {
+                _vacModules[moveItem.DestinationModule].MovingStatus = status;
+            }
+
+            if(!ModuleHelper.IsTMRobot(moveItem.SourceModule))
+            {
+                _vacModules[moveItem.SourceModule].MovingStatus = status;
+            }
+        }
+
+        private void UpdateModuleMovingStatus(ModuleName module, MovingStatus status = MovingStatus.Moving)
+        {
+            if (!ModuleHelper.IsTMRobot(module))
+            {
+                _vacModules[module].MovingStatus = status;
+            }
+        }
+
         private void ProcessTMRobotTask()
         {
             if(_tmRobot.IsAvailable)
@@ -718,11 +710,16 @@ namespace Venus_RT.Modules
 
                 foreach(var slot in _vacReadyOutSlots)
                 {
-                    if(ModuleHelper.IsLoadLock(slot.Module))
+                    if (_vacModules[slot.Module].MovingStatus == MovingStatus.Moving)
+                        continue;
+
+                    if (ModuleHelper.IsLoadLock(slot.Module))
                     {
                         if(SearchWaferDestination(slot, out SlotItem destSlot))
                         {
                             _movingItems.Add(new MoveItem(slot.Module, slot.Slot, destSlot.Module, destSlot.Slot, Hand.None));
+                            UpdateModuleMovingStatus(slot.Module);
+                            UpdateModuleMovingStatus(destSlot.Module);
 
                             // check whether match double pick pattern
                             var out_slot_2 = _vacReadyOutSlots.Find(item => item.Module == slot.Module && item.Slot != slot.Slot);
@@ -731,6 +728,8 @@ namespace Venus_RT.Modules
                                 if(SearchWaferDestination(out_slot_2, out SlotItem destSlot_2))
                                 {
                                     _movingItems.Add(new MoveItem(out_slot_2.Module, out_slot_2.Slot, destSlot_2.Module, destSlot_2.Slot, Hand.None));
+                                    UpdateModuleMovingStatus(out_slot_2.Module);
+                                    UpdateModuleMovingStatus(destSlot_2.Module);
                                 }
                             }
 
@@ -739,6 +738,7 @@ namespace Venus_RT.Modules
                             foreach(var in_slot in in_slots)
                             {
                                 _movingItems.Add(in_slot);
+                                UpdateItemMovingStatus(in_slot);
                             }
 
                             return;
@@ -749,12 +749,15 @@ namespace Venus_RT.Modules
                         if(SearchWaferDestination(slot, out SlotItem destSlot))
                         {
                             _movingItems.Add(new MoveItem(slot.Module, slot.Slot, destSlot.Module, destSlot.Slot, Hand.None));
+                            UpdateModuleMovingStatus(slot.Module);
+                            UpdateModuleMovingStatus(destSlot.Module);
 
                             // check whether match swap pattern
                             var in_slots = SearchWaitInSlots(slot.Module);
                             if(in_slots.Count >= 1)
                             {
                                 _movingItems.Add(in_slots.First());
+                                UpdateItemMovingStatus(in_slots.First());
                             }
                             else
                             {
@@ -763,6 +766,7 @@ namespace Venus_RT.Modules
                                 foreach (var item in same_dest)
                                 {
                                     _movingItems.Add(item);
+                                    UpdateItemMovingStatus(item);
                                 }
                             }
 
@@ -770,6 +774,9 @@ namespace Venus_RT.Modules
                         }
                     }
                 }
+
+                _vacReadyOutSlots.Clear();
+                _vacReadyInSlots.Clear();
             }
         }
 
@@ -786,6 +793,7 @@ namespace Venus_RT.Modules
                         if (wafer.IsEmpty)
                         {
                             // 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");
                             return;
                         }
@@ -793,7 +801,6 @@ namespace Venus_RT.Modules
                         var slot = new SlotItem(item.DestinationModule, item.DestinationSlot);
                         _vacWaferTargets[slot] = wafer.InnerId;
                     }
-                    _movingItems.Clear();
                 }
             }
         }
@@ -825,7 +832,7 @@ namespace Venus_RT.Modules
             if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
             {
                 // should not go here
-                LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Wafer:{wafer.WaferOrigin} NextSequenceStep {wafer.NextSequenceStep} exceeds {wafer.ProcessJob.Sequence.Name} max steps number");
+                //LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Wafer:{wafer.WaferOrigin} NextSequenceStep {wafer.NextSequenceStep} exceeds {wafer.ProcessJob.Sequence.Name} max steps number");
                 return false;
             }
 
@@ -926,7 +933,12 @@ namespace Venus_RT.Modules
             if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
                 return false;
 
-            if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
+            if (wafer.NextSequenceStep == wafer.ProcessJob.Sequence.Steps.Count)
+            {
+                // need return
+                return true; 
+            }
+            else if(wafer.NextSequenceStep > wafer.ProcessJob.Sequence.Steps.Count)
             {
                 // should not go here
                 LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Wafer:{wafer.WaferOrigin} NextSequenceStep {wafer.NextSequenceStep} exceeds {wafer.ProcessJob.Sequence.Name} max steps number");
@@ -949,6 +961,9 @@ namespace Venus_RT.Modules
         }
         private bool ProcessLLEFEMRobotTask(ModuleName ll)
         {
+            if (_vacModules[ll].MovingStatus != MovingStatus.Staying)
+                return false;
+
             var robotSlots = GetEfemRobotWaferReadyInHands(ll);
             var inSlots = ll == ModuleName.LLA ? _LLAInSlot : _LLBInSlot;
             foreach(var slot in inSlots)
@@ -984,11 +999,11 @@ namespace Venus_RT.Modules
         {
             int exist = 0;
             int empty = 0;
-            foreach (var atmModule in _atmModules)
+            foreach (var module in _vacModules)
             {
-                if (ModuleHelper.IsPm(atmModule.Key))
+                if (ModuleHelper.IsPm(module.Key))
                 {
-                    if (WaferManager.Instance.CheckHasWafer(atmModule.Key, 0))
+                    if (WaferManager.Instance.CheckHasWafer(module.Key, 0))
                         exist++;
                     else
                         empty++;
@@ -1048,7 +1063,11 @@ namespace Venus_RT.Modules
             var llaWaferStatus = GetLLProcessStatusCount(ModuleName.LLA);
             var llbWaferStatus = GetLLProcessStatusCount(ModuleName.LLB);
             var pmWaferStatus = GetPMWaferExistence();
-            if (pmWaferStatus.Item2 <= (llaWaferStatus.Item2 + llbWaferStatus.Item2))
+
+            if (llaWaferStatus.Item1 + llbWaferStatus.Item1 > 0)
+                return false;
+
+            if (_LLAInSlot.Count + _LLBInSlot.Count + pmWaferStatus.Item2 - llaWaferStatus.Item2 - llbWaferStatus.Item2 <= 2)
                 return false;
 
             if (GetEfemRoborWaferCount() >= 1 && GetAtmInerWaferCount() > 0)
@@ -1190,14 +1209,19 @@ namespace Venus_RT.Modules
                         if (wafer.IsEmpty)
                         {
                             // post alarm
+                            _cycleState = RState.Failed;
                             LOG.Write(eEvent.ERR_ROUTER, ModuleName.System, $"Cannot run EFEM moving task as Get {item.SourceModule}{item.SourceModule} Wafer Info failed");
                             return;
                         }
 
                         var slot = new SlotItem(item.DestinationModule, item.DestinationSlot);
                         _atmWaferTargets[slot] = wafer.InnerId;
+
+                        if(ModuleHelper.IsLoadLock(item.Module))
+                        {
+                            _vacModules[item.Module].MovingStatus = MovingStatus.Moving;
+                        }
                     }
-                    _efemMovingItems.Clear();
                 }
             }
         }
@@ -1206,8 +1230,11 @@ namespace Venus_RT.Modules
         {
             for(int i = 0; i < 2; i++)
             {
-                if ((WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, i) && !_efemMovingItems.Exists(item => item.DestinationModule == ModuleName.EfemRobot && item.DestinationSlot == i)) ||
-                (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, i) && _efemMovingItems.Exists(item => item.SourceModule == ModuleName.EfemRobot && item.SourceSlot == i)))
+                if ((WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, i) && 
+                    !_efemMovingItems.Exists(item => item.DestinationModule == ModuleName.EfemRobot && item.DestinationSlot == i)) ||
+                (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, i) && 
+                _efemMovingItems.Exists(item => item.SourceModule == ModuleName.EfemRobot && item.SourceSlot == i) && 
+                !_efemMovingItems.Exists(item => item.DestinationModule == ModuleName.EfemRobot && item.DestinationSlot == i)))
                 return (Hand)i;
             }
 
@@ -1308,6 +1335,9 @@ namespace Venus_RT.Modules
                     if (!ModuleHelper.IsPm(stepModule))
                         break;
 
+                    if (!_vacSchedulers.Keys.Contains(stepModule))
+                        continue;
+
                     var pm = _vacSchedulers[stepModule] as SchedulerPM;
                     if (pm != null)
                     {
@@ -1376,7 +1406,7 @@ namespace Venus_RT.Modules
                     SequenceStepInfo stepInfo = seq.Steps[i];
                     foreach (var module in stepInfo.StepModules)
                     {
-                        if (ModuleHelper.IsPm(module))
+                        if (ModuleHelper.IsPm(module) && _vacSchedulers.ContainsKey(module))
                         {
                             var pm = _vacSchedulers[module] as SchedulerPM;
 
@@ -1392,6 +1422,90 @@ namespace Venus_RT.Modules
 
             return result;
         }
+
+        private void CheckWaferArrived()
+        {
+            if (_cycleState != RState.Running)
+                return;
+
+            foreach (var mod in _vacSchedulers.Append(new KeyValuePair<ModuleName, SchedulerModule>( ModuleName.TMRobot, _tmRobot)))
+            {
+                //if (mod.Value.IsAvailable)
+                {
+                    var tars = _vacWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
+                    foreach (var tar in tars)
+                    {
+                        var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
+                        if (wafer.IsEmpty)
+                            continue;
+
+                        if (wafer.InnerId == tar.Value)
+                        {
+                            // wafer arrive
+                            _vacWaferTargets.Remove(tar.Key);
+                            if(!ModuleHelper.IsTMRobot(tar.Key.Module))
+                                wafer.NextSequenceStep++;
+                        }
+                    }
+                }
+            }
+
+            _vacMoveFinishTrig.CLK = _vacWaferTargets.Count == 0;
+            if (_vacMoveFinishTrig.Q)
+            {
+                foreach(var item in _movingItems)
+                {
+                    if(!ModuleHelper.IsTMRobot(item.DestinationModule))
+                    {
+                        _vacModules[item.DestinationModule].MovingStatus = MovingStatus.Staying;
+                    }
+
+                    if(!ModuleHelper.IsTMRobot(item.SourceModule))
+                    {
+                        _vacModules[item.SourceModule].MovingStatus = MovingStatus.Staying;
+                    }
+                }
+
+                _movingItems.Clear();
+            }
+
+            foreach (var mod in _atmSchedulers.Append(new KeyValuePair<ModuleName, SchedulerModule>(ModuleName.EfemRobot, _efemRobot)))
+            {
+                //if (mod.Value.IsAvailable)
+                {
+                    var tars = _atmWaferTargets.Where(item => item.Key.Module == mod.Key).ToArray();
+                    foreach (var tar in tars)
+                    {
+                        var wafer = WaferManager.Instance.GetWafer(tar.Key.Module, tar.Key.Slot);
+                        if (wafer.IsEmpty)
+                            continue;
+
+                        if (wafer.InnerId == tar.Value)
+                        {
+                            // wafer arrive
+                            _atmWaferTargets.Remove(tar.Key);
+
+                            if (!ModuleHelper.IsEFEMRobot(tar.Key.Module))
+                                wafer.NextSequenceStep++;
+                        }
+                    }
+                }
+            }
+
+            _atmMoveFinishTrig.CLK = _atmWaferTargets.Count == 0;
+            if(_atmMoveFinishTrig.Q)
+            {
+                foreach(var item in _efemMovingItems)
+                {
+                    if(ModuleHelper.IsLoadLock(item.Module))
+                    {
+                        _vacModules[item.Module].MovingStatus = MovingStatus.Staying;
+                    }
+                }
+
+                _efemMovingItems.Clear();
+            }
+        }
         private void PreJobClean(ControlJobInfo cj)
         {
             if (cj.IsPreJobCleanDone)

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

@@ -60,21 +60,21 @@ namespace Venus_RT.Modules.EFEM
                 _targetModule = firtItem.DestinationModule;
             else
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Invalid move parameter: {firtItem.SourceModule},{firtItem.SourceSlot} => {firtItem.DestinationModule},{firtItem.DestinationSlot} ");
+                LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"Invalid move parameter: {firtItem.SourceModule},{firtItem.SourceSlot + 1} => {firtItem.DestinationModule},{firtItem.DestinationSlot + 1} ");
                 return RState.Failed;
             }
 
             _llModule = Singleton<RouteManager>.Instance.GetLL(_targetModule);
             if (_llModule == null)
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Invalid Loadlock: {_targetModule}, maybe not installed");
+                LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"Invalid Loadlock: {_targetModule}, maybe not installed");
                 return RState.Failed;
             }
 
             _tmModule = Singleton<RouteManager>.Instance.GetTM();
             if(_tmModule == null)
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Get TM Entity failed.");
+                LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $"Get TM Entity failed.");
                 return RState.Failed;
             }
                 

+ 11 - 4
Venus/Venus_RT/Modules/RouteManager.cs

@@ -110,8 +110,7 @@ namespace Venus_RT.Modules
                        || (PMA?.IsError ?? false)
                        || (PMB?.IsError ?? false)
                        || (PMC?.IsError ?? false)
-                       || (PMD?.IsError ?? false)
-                       ;
+                       || (PMD?.IsError ?? false);
             }
         }
 
@@ -387,7 +386,7 @@ namespace Venus_RT.Modules
         {
             if (!fsm.FindTransition(fsm.State, msg))
             {
-                LOG.Write(eEvent.WARN_FSM_WARN, ModuleName.TM, $"TM is in {(RtState)fsm.State} state,can not do {(MSG)msg}");
+                LOG.Write(eEvent.WARN_ROUTER, ModuleName.System, $"System is in {(RtState)fsm.State} state,can not do {(MSG)msg}");
                 return false;
             }
 
@@ -526,7 +525,6 @@ namespace Venus_RT.Modules
             PMB?.Initialize();
             PMC?.Initialize();
             PMD?.Initialize();
-
             TM?.Initialize();
             LLA?.Initialize();
             LLB?.Initialize();
@@ -550,6 +548,9 @@ namespace Venus_RT.Modules
 
             ////  EnterExitTransition<RtState, FSM_MSG>(RtState.Initializing, fStartInit, FSM_MSG.NONE, null);
             ///
+
+            AnyStateTransition(MSG.ERROR,       FsmError,               RtState.Error);
+
             Transition(RtState.Idle,            FSM_MSG.TIMER,          FsmMonitor,                 RtState.Idle);
             Transition(RtState.Init,            FSM_MSG.TIMER,          FsmMonitor,                 RtState.Init);
 
@@ -686,6 +687,12 @@ namespace Venus_RT.Modules
         {
             RState ret = _AutoCycle.Monitor();
 
+            if(ret == RState.Failed)
+            {
+                if (!CheckToPostMessage((int)MSG.ERROR))
+                    return false;
+            }
+
             if (_AutoCycle.CheckJobJustDone(out string jobInfo))
             {
                 EV.PostPopDialogMessage(EventLevel.InformationNoDelay, "Job complete", jobInfo);

+ 6 - 1
Venus/Venus_RT/Modules/Schedulers/SchedulerEfemRobot.cs

@@ -113,7 +113,12 @@ namespace Venus_RT.Scheduler
 
         public bool PostMoveItems(MoveItem[] items)
         {
-            if(ModuleHelper.IsLoadLock(items.First().Module))
+            foreach (var item in items)
+            {
+                LOG.Write(eEvent.EV_ROUTER, ModuleName.EfemRobot, $"Post Moving Item: {item.SourceModule} Slot {item.SourceSlot + 1} => {item.DestinationModule} Slot {item.DestinationSlot + 1}");
+            }
+
+            if (ModuleHelper.IsLoadLock(items.First().Module))
             {
                 _currentScheduler = new SchedulerItem();
                 _currentScheduler.MoveType = EfemEntity.MSG.Swap;

+ 42 - 5
Venus/Venus_RT/Modules/Schedulers/SchedulerTMRobot.cs

@@ -89,6 +89,43 @@ namespace Venus_RT.Modules.Schedulers
 
         public bool PostMoveItems(MoveItem[] items)
         {
+            foreach(var item in items)
+            {
+                LOG.Write(eEvent.EV_ROUTER, ModuleName.TMRobot, $"Post Moving Item: {item.SourceModule} Slot {item.SourceSlot + 1} => {item.DestinationModule} Slot {item.DestinationSlot + 1}");
+            }
+
+            void PackPMSwapCmds(MoveItem[] swapItems)
+            {
+                // must swap the item order for PM swap
+                if (!ModuleHelper.IsTMRobot(swapItems[1].SourceModule))
+                {
+                    SchedulerItem item = new SchedulerItem();
+                    item.MoveType = TMEntity.MSG.Pick;
+                    item.target = swapItems[1].SourceModule;
+                    item.moveList = new Queue<MoveItem>();
+                    item.moveList.Enqueue(new MoveItem(swapItems[1].SourceModule, swapItems[1].SourceSlot, ModuleName.TMRobot, 0, (Hand)0));
+                    _schedulerList.Enqueue(item);
+                }
+                
+                SchedulerItem swap = new SchedulerItem();
+                swap.MoveType = TMEntity.MSG.PMSwap;
+                swap.target = swapItems[0].SourceModule;
+                swap.moveList = new Queue<MoveItem>();
+                swap.moveList.Enqueue(new MoveItem(swapItems[0].SourceModule, swapItems[0].SourceSlot, ModuleName.TMRobot, 1, (Hand)1));
+                swap.moveList.Enqueue(new MoveItem(ModuleName.TMRobot, 0, swapItems[1].DestinationModule, swapItems[1].DestinationSlot, (Hand)0));
+                _schedulerList.Enqueue(swap);
+
+                if (!ModuleHelper.IsTMRobot(swapItems[0].DestinationModule))
+                {
+                    SchedulerItem last = new SchedulerItem();
+                    last.MoveType = TMEntity.MSG.Place;
+                    last.target = swapItems[0].DestinationModule;
+                    last.moveList = new Queue<MoveItem>();
+                    last.moveList.Enqueue(new MoveItem(ModuleName.TMRobot, 1, swapItems[0].DestinationModule, swapItems[0].DestinationSlot, (Hand)1));
+                    _schedulerList.Enqueue(last);
+                }
+            }
+
             void PackSwapCmds(MoveItem[] swapItems, TMEntity.MSG swapType, int swapIndex)
             {
                 SchedulerItem swap = new SchedulerItem();
@@ -104,16 +141,16 @@ namespace Venus_RT.Modules.Schedulers
                         item.MoveType = ModuleHelper.IsLoadLock(swapItems[i].SourceModule) ? TMEntity.MSG.Pick : TMEntity.MSG.PMPick;
                         item.target = swapItems[i].SourceModule;
                         item.moveList = new Queue<MoveItem>();
-                        item.moveList.Enqueue(new MoveItem(swapItems[i].SourceModule, swapItems[i].SourceSlot, ModuleName.TM, i, (Hand)i));
+                        item.moveList.Enqueue(new MoveItem(swapItems[i].SourceModule, swapItems[i].SourceSlot, ModuleName.TMRobot, i, (Hand)i));
                         _schedulerList.Enqueue(item);
 
-                        swap.moveList.Enqueue(new MoveItem(ModuleName.TM, i, swapItems[i].DestinationModule, swapItems[i].DestinationSlot, (Hand)i));
+                        swap.moveList.Enqueue(new MoveItem(ModuleName.TMRobot, i, swapItems[i].DestinationModule, swapItems[i].DestinationSlot, (Hand)i));
                     }
                 }
 
                 for (int j = swapIndex; j < swapItems.Length; j++)
                 {
-                    swap.moveList.Enqueue(new MoveItem(swapItems[j].SourceModule, swapItems[j].SourceSlot, ModuleName.TM, j - swapIndex, (Hand)(j - swapIndex)));
+                    swap.moveList.Enqueue(new MoveItem(swapItems[j].SourceModule, swapItems[j].SourceSlot, ModuleName.TMRobot, j - swapIndex, (Hand)(j - swapIndex)));
                 }
                 _schedulerList.Enqueue(swap);
 
@@ -173,7 +210,7 @@ namespace Venus_RT.Modules.Schedulers
                     else if (ModuleHelper.IsPm(items[0].SourceModule) &&
                         items[0].SourceModule == items[1].DestinationModule)
                     {
-                        PackSwapCmds(items,  TMEntity.MSG.PMSwap, 1);
+                        PackPMSwapCmds(items);
                     }
                 }
             }
@@ -182,7 +219,7 @@ namespace Venus_RT.Modules.Schedulers
             Hand freeHand = SelectFreeHand();
             if(freeHand == Hand.None)
             {
-                LOG.Write(eEvent.WARN_ROUTER, ModuleName.TM, "No Free Arm to transfer wafer");
+                LOG.Write(eEvent.WARN_ROUTER, ModuleName.TMRobot, "No Free Arm to transfer wafer");
                 return false;
             }
             if(_schedulerList.Count == 0)

+ 1 - 1
Venus/Venus_RT/Modules/TM/MFPMPickRoutine.cs

@@ -74,7 +74,7 @@ namespace Venus_RT.Modules.TM
 
             if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as {_targetModule} Slot {_targetSlot} has no wafer");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as {_targetModule} Slot {_targetSlot + 1} has no wafer");
                 return RState.Failed;
             }
 

+ 1 - 1
Venus/Venus_RT/Modules/TM/MFPMPlaceRoutine.cs

@@ -74,7 +74,7 @@ namespace Venus_RT.Modules.TM
 
             if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot Place as {_targetModule} Slot {_targetSlot} already has a wafer");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot Place as {_targetModule} Slot {_targetSlot + 1} already has a wafer");
                 return RState.Failed;
             }
 

+ 1 - 1
Venus/Venus_RT/Modules/TM/MFPMSwapRoutine.cs

@@ -88,7 +88,7 @@ namespace Venus_RT.Modules.TM
 
             if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot Swap Wafer as {_targetModule} Slot {_targetSlot} has no wafer");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot Swap Wafer as {_targetModule} Slot {_targetSlot + 1} has no wafer");
                 return RState.Failed;
             }
 

+ 1 - 1
Venus/Venus_RT/Modules/TM/MFPickRoutine.cs

@@ -72,7 +72,7 @@ namespace Venus_RT.Modules.TM
             
             if (WaferManager.Instance.CheckNoWafer(_targetModule, _targetSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as {_targetModule} Slot {_targetSlot} has no wafer");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot pick as {_targetModule} Slot {_targetSlot + 1} has no wafer");
                 return RState.Failed;
             }
 

+ 1 - 1
Venus/Venus_RT/Modules/TM/MFPlaceRoutine.cs

@@ -72,7 +72,7 @@ namespace Venus_RT.Modules.TM
 
             if (WaferManager.Instance.CheckHasWafer(_targetModule, _targetSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot place as {_targetModule} Slot {_targetSlot} already has a wafer");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot place as {_targetModule} Slot {_targetSlot + 1} already has a wafer");
                 return RState.Failed;
             }
 

+ 3 - 3
Venus/Venus_RT/Modules/TM/MFSwapRoutine.cs

@@ -62,7 +62,7 @@ namespace Venus_RT.Modules.TM
                 _targetModule = firtItem.DestinationModule;
             else
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Invalid move parameter: {firtItem.SourceModule},{firtItem.SourceSlot} => {firtItem.DestinationModule},{firtItem.DestinationSlot} ");
+                LOG.Write(eEvent.ERR_TM, Module, $"Invalid move parameter: {firtItem.SourceModule},{firtItem.SourceSlot + 1} => {firtItem.DestinationModule},{firtItem.DestinationSlot + 1} ");
                 return RState.Failed;
             }
 
@@ -138,13 +138,13 @@ namespace Venus_RT.Modules.TM
         {
             if (WaferManager.Instance.CheckHasWafer(item.DestinationModule, item.DestinationSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot move wafer as desitination {_currentAction.DestinationModule},{_currentAction.DestinationSlot} already a wafer: ");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot move wafer as desitination {_currentAction.DestinationModule},{_currentAction.DestinationSlot + 1} already a wafer: ");
                 return false;
             }
 
             if (WaferManager.Instance.CheckNoWafer(_currentAction.SourceModule, _currentAction.SourceSlot))
             {
-                LOG.Write(eEvent.ERR_TM, Module, $"Cannot move wafer as source {_currentAction.SourceModule}, {_currentAction.SourceSlot} has no wafer");
+                LOG.Write(eEvent.ERR_TM, Module, $"Cannot move wafer as source {_currentAction.SourceModule}, {_currentAction.SourceSlot + 1} has no wafer");
                 return false;
             }