|
@@ -17,6 +17,9 @@ using MECF.Framework.Common.SubstrateTrackings;
|
|
|
using Venus_Core;
|
|
|
using Venus_RT.Modules.PMs;
|
|
|
using Aitex.Core.RT.Log;
|
|
|
+using Venus_RT.HostWrapper;
|
|
|
+
|
|
|
+
|
|
|
namespace Venus_RT.Modules
|
|
|
{
|
|
|
class RouteManager : Entity, IEntity
|
|
@@ -153,6 +156,7 @@ namespace Venus_RT.Modules
|
|
|
fsm = new StateMachine<RouteManager>(Name, (int)RtState.Init, 200);
|
|
|
|
|
|
SubscribeOperation();
|
|
|
+ SubscribeDataVariable();
|
|
|
}
|
|
|
|
|
|
public bool Check(int msg, out string reason, params object[] args)
|
|
@@ -165,7 +169,7 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
if (msg == (int)MSG.StartCycle)
|
|
|
{
|
|
|
-
|
|
|
+ if (!IsAutoMode)
|
|
|
{
|
|
|
reason = String.Format("can not do {0}, isn't auto mode.", msg.ToString());
|
|
|
return false;
|
|
@@ -186,8 +190,8 @@ namespace Venus_RT.Modules
|
|
|
DATA.Subscribe("System.IsIdle", () => IsIdle || IsInit);
|
|
|
DATA.Subscribe("System.IsAlarm", () => IsAlarm || IsEntityError);
|
|
|
DATA.Subscribe("System.IsBusy", () => IsRunning);
|
|
|
- DATA.Subscribe("System.IsWaitUnload", () => IsAutoMode);
|
|
|
-
|
|
|
+ DATA.Subscribe("System.IsWaitUnload", () => _isWaitUnload && IsAutoMode);
|
|
|
+ DATA.Subscribe("System.IsConnectedWithHost", () => Singleton<FaManager>.Instance.IsConnected);
|
|
|
|
|
|
DATA.Subscribe("EquipmentMode", () => IsAutoMode ? 0 : 1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
|
|
|
|
|
@@ -222,8 +226,159 @@ namespace Venus_RT.Modules
|
|
|
DATA.Subscribe("SYSTEM.FsmState", () => (((RtState)fsm.State).ToString()));
|
|
|
DATA.Subscribe("TMCycle.CycleIndex", () => (_TMCycle.CycleIndex));
|
|
|
|
|
|
+ OP.Subscribe("ReturnWafer", InvokeReturnWafer);
|
|
|
+
|
|
|
+ OP.Subscribe("System.ReturnAllWafer", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.ReturnAllWafer, args[0], args[1], args[2], args[3]);
|
|
|
+ });
|
|
|
+ OP.Subscribe("System.MoveWafer", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ if (!Enum.TryParse((string)args[0], out ModuleName source))
|
|
|
+ {
|
|
|
+ EV.PostWarningLog(Name, $"Parameter source {(string)args[0]} not valid");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!Enum.TryParse((string)args[2], out ModuleName destination))
|
|
|
+ {
|
|
|
+ EV.PostWarningLog(Name, $"Parameter destination {(string)args[1]} not valid");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return CheckToPostMessage((int)MSG.MoveWafer,
|
|
|
+ source, (int)args[1],
|
|
|
+ destination, (int)args[3],
|
|
|
+ (bool)args[4], (int)args[5],
|
|
|
+ (bool)args[6], (int)args[7], (string)args[8]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.HomeAll", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.HOME);
|
|
|
+ });
|
|
|
+ OP.Subscribe("System.Abort", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.ABORT);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.Reset", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.RESET);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.SetAutoMode", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.SetAutoMode);
|
|
|
+ });
|
|
|
+ OP.Subscribe("System.SetManualMode", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.SetManualMode);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.CreateJob", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.CreateJob, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.StartJob", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.StartJob, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.PauseJob", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.PauseJob, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.ResumeJob", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.ResumeJob, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.StopJob", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.StopJob, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.AbortJob", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.AbortJob, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("LP1.Map", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ if (IsAutoMode)
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.Map, ModuleName.LP1.ToString());
|
|
|
+ }
|
|
|
+
|
|
|
+ return EFEM.InvokeMap(ModuleName.LP1.ToString()) != (int)FSM_MSG.NONE;
|
|
|
+ });
|
|
|
+
|
|
|
+
|
|
|
+ OP.Subscribe("LP2.Map", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ if (IsAutoMode)
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.Map, ModuleName.LP2.ToString());
|
|
|
+ }
|
|
|
+
|
|
|
+ return EFEM.InvokeMap(ModuleName.LP2.ToString()) != (int)FSM_MSG.NONE;
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe(RtOperation.SetConfig.ToString(), (name, args) =>
|
|
|
+ {
|
|
|
+ string sc_key = args[0] as string;
|
|
|
+ if (!string.IsNullOrWhiteSpace(sc_key) && args.Length > 1)
|
|
|
+ {
|
|
|
+ SC.SetItemValue(sc_key, args[1]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.ResetIdleCleanTime", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.ResetIdleCleanTime, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.ResetIdlePurgeTime", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.ResetIdlePurgeTime, args[0]);
|
|
|
+ });
|
|
|
+
|
|
|
+ OP.Subscribe("System.SetWaferSize", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ string module = (string)args[0];
|
|
|
+ string size = (string)args[1];
|
|
|
+ switch (size)
|
|
|
+ {
|
|
|
+ case "3":
|
|
|
+ WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS3);
|
|
|
+ break;
|
|
|
+ case "4":
|
|
|
+ WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS4);
|
|
|
+ break;
|
|
|
+ case "6":
|
|
|
+ WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS6);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ EV.PostWarningLog("System", $"wafer size {size} not valid");
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return true;
|
|
|
+ });
|
|
|
|
|
|
+ OP.Subscribe("System.CassetteLeave", (string cmd, object[] args) =>
|
|
|
+ {
|
|
|
+ return CheckToPostMessage((int)MSG.CassetteLeave);
|
|
|
+ });
|
|
|
|
|
|
+ OP.Subscribe("System.IsModuleInstalled", (string cmd, object[] args) => {
|
|
|
+ return ModuleHelper.IsInstalled((ModuleName)args[0]);
|
|
|
+ });
|
|
|
}
|
|
|
public bool CheckToPostMessage(int msg, params object[] args)
|
|
|
{
|
|
@@ -249,17 +404,16 @@ namespace Venus_RT.Modules
|
|
|
{
|
|
|
if (WaferManager.Instance.CheckHasWafer(chamber, slot))
|
|
|
{
|
|
|
- EV.PostInfoLog("System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot));
|
|
|
+ LOG.Write(eEvent.EV_ROUTER, "System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot));
|
|
|
}
|
|
|
else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null)
|
|
|
{
|
|
|
-
|
|
|
LOG.Write(eEvent.EV_WAFER_CREATE, ModuleName.System, chamber.ToString(), (slot + 1).ToString(), state.ToString());
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
|
|
+ LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
@@ -279,18 +433,48 @@ namespace Venus_RT.Modules
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- EV.PostInfoLog("System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1));
|
|
|
+ LOG.Write(eEvent.EV_ROUTER, "System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1));
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
|
|
+ LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ private bool InvokeReturnWafer(string arg1, object[] args)
|
|
|
+ {
|
|
|
+ ModuleName target = ModuleHelper.Converter(args[0].ToString());
|
|
|
+ int slot = (int)args[1];
|
|
|
+
|
|
|
+ if (ModuleHelper.IsLoadPort(target))
|
|
|
+ {
|
|
|
+ LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Wafer already at LoadPort {0} {1}, return operation is not valid", target.ToString(), slot + 1));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!WaferManager.Instance.IsWaferSlotLocationValid(target, slot))
|
|
|
+ {
|
|
|
+ LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("Invalid position,{0},{1}", target.ToString(), slot.ToString()));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ WaferInfo wafer = WaferManager.Instance.GetWafer(target, slot);
|
|
|
+ if (wafer.IsEmpty)
|
|
|
+ {
|
|
|
+ LOG.Write(eEvent.WARN_ROUTER, "System", string.Format("No wafer at {0} {1}, return operation is not valid", target.ToString(), slot + 1));
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ return CheckToPostMessage((int)MSG.MoveWafer,
|
|
|
+ target, slot,
|
|
|
+ (ModuleName)wafer.OriginStation, wafer.OriginSlot,
|
|
|
+ false, 0, false, 0, "Blade1");
|
|
|
+ }
|
|
|
+
|
|
|
public PMEntity GetPM(ModuleName mod)
|
|
|
{
|
|
|
if (ModuleHelper.IsInstalled(mod))
|
|
@@ -512,41 +696,49 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private bool FsmAbortAutoTransfer(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.Clear();
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmJobDone(object[] objs)
|
|
|
{
|
|
|
+ _isWaitUnload = true;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmCreateJob(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.CreateJob((Dictionary<string, object>)objs[0]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmStartJob(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.StartJob((string)objs[0]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmPauseJob(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.PauseJob((string)objs[0]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmResumeJob(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.ResumeJob((string)objs[0]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmStopJob(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.StopJob((string)objs[0]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
private bool FsmAbortJob(object[] objs)
|
|
|
{
|
|
|
+ _AutoCycle.AbortJob((string)objs[0]);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
@@ -567,11 +759,27 @@ namespace Venus_RT.Modules
|
|
|
|
|
|
private bool FsmMonitorAutoIdle(object[] objs)
|
|
|
{
|
|
|
- return true;
|
|
|
+ RState ret = _AutoCycle.Monitor();
|
|
|
+
|
|
|
+ if (_AutoCycle.CheckAllJobDone())
|
|
|
+ {
|
|
|
+ if (!CheckToPostMessage((int)MSG.JobDone))
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ _isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone");
|
|
|
+
|
|
|
+ return ret == RState.End;
|
|
|
}
|
|
|
|
|
|
private bool FsmStartSetManualMode(object[] objs)
|
|
|
{
|
|
|
+ if (_AutoCycle.HasJobRunning)
|
|
|
+ {
|
|
|
+ LOG.Write(eEvent.WARN_ROUTER, "System", "Can not change to manual mode, abort running job first");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
return true;
|
|
|
}
|
|
|
private void _debugRoutine()
|