using System; using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using EFEM.RT.Modules; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; using System.Security.Cryptography; namespace EFEM.RT.Routines { public class SwapRoutine : CommonRoutine, IRoutine { enum Swap { QueryState, CheckBeforeSwap, SwapWafer, WaitSwap, PickWafer, WaitPick, PlaceWafer, WaitPlace, CheckAfterSwap, CoolBufferMoveUP, WaitCoolBufferMoveUP, CoolBufferMoveDown, PostMessage, RobotBusytoSimifOn, RobotBusytoSimifOff, CheckBlade1WaferPrecense, CheckBlade2WaferPrecense, CheckBlade1WaferPrecenseAfterSwap, CheckBlade2WaferPrecenseAfterSwap, QuerySignalStatus, WaitCoolBufferMoveDown, PinDown, NotifyFlipperPrepare, NotifyFlipperOver } private SCConfigItem _scSwapTimeout = null; private int _timeout = 0; public SwapRoutine(string module, string name) { Module = module; Name = name; _scSwapTimeout = SC.GetConfigItem(SorterCommon.ScPathName.Robot_TimeLimitForPlaceWafer); } public bool Initalize() { IsStopped = true; return true; } public ModuleName Source { get; set; } public int Slot { get; set; } public Hand PlaceBlade { get; set; } public LoadPort _lpDevice; private int _offsetXPick; private int _offsetYPick; private int _offsetZPick; private int _offsetXPlace; private int _offsetYPlace; private int _offsetZPLace; private Hand _pickHand; private int _alignerdelay = 0; private int _coolingdelay = 0; private int delaytime = 0; public Result Start(params object[] objs) { IsStopped = false; Reset(); _timeout = robot.RobotCommandTimeout; ; Reset(); EV.PostMessage(ModuleName.System.ToString(), EventEnum.GeneralInfo, string.Format("swap wafer {0}{1:D2} place blade {2} start", Source.ToString(), Slot + 1, PlaceBlade.ToString())); if (ModuleHelper.IsCoolingBuffer(Source)) delaytime = _coolingdelay * 1000; else delaytime = _alignerdelay * 1000; _pickHand = Hand.Blade1; if (PlaceBlade == Hand.Blade1) _pickHand = Hand.Blade2; return Result.RUN; } public Result Monitor() { try { if (IsStopped) return Result.DONE; if (ModuleHelper.IsCoolingBuffer(Source) || ModuleHelper.IsAligner(Source)) { var dev = GetCoolBuffer(Source); if (dev != null) { //QueryCoolBufferState((int)Pick.QueryState, GetCoolBuffer(Source)); CoolBufferMoveUP((int)Swap.CoolBufferMoveUP, GetCoolBuffer(Source), WaferManager.Instance.GetWaferSize(Source, Slot), _timeout, Notify, Stop); WaitCoolBufferMoveUp((int)Swap.WaitCoolBufferMoveUP, GetCoolBuffer(Source), "Wait CoolingBuffer Move Up...", _timeout, Notify, Stop); } } else if (ModuleHelper.IsFlipper(Source)) { FlipperPrepare((int)Swap.NotifyFlipperPrepare, GetFlipper(), "Flipper Prepare Transfer...", _timeout, Notify, Stop); } //if (ModuleHelper.IsLoadLock(Source)) //{ // if (Source.Equals("LL1")) ll1.SafeytoPm(true); // else if (Source.Equals("LL2")) ll2.SafeytoPm(true); //} //RobotSignalStatus((int)Swap.QuerySignalStatus, robot, _timeout); CheckBladeWaferIsExist((int)Swap.CheckBlade1WaferPrecense, robot, Hand.Blade1, _timeout); CheckBladeWaferIsExist((int)Swap.CheckBlade2WaferPrecense, robot, Hand.Blade2, _timeout); CheckBeforeSwap((int)Swap.CheckBeforeSwap, "Check wafer information", Source, Slot, _pickHand, Notify, Stop); //if (ModuleHelper.IsLoadPort(Source)) //{ // RobotBusytoSimif((int)Swap.RobotBusytoSimifOn, Source, true, _timeout, Notify, Stop); //} //if (OffsetX == 0 && OffsetY == 0 && OffsetZ == 0) //{ // PickWafer((int)Swap.PickWafer, "Pick wafer", Source, Slot, _pickHand, _offsetXPick, _offsetYPick, _offsetZPick, Notify, Stop); // this.WaitRobotMotion((int)Swap.WaitPick, robot, "Wait picked", _timeout, Notify, Stop); // PlaceWafer((int)Swap.PlaceWafer, "Place wafer", Source, Slot, PlaceBlade, _offsetXPlace, _offsetYPlace, _offsetZPLace, Notify, Stop); // this.WaitRobotMotion((int)Swap.WaitPlace, robot, "Wait Placed", _timeout, Notify, Stop); //} //else //{ if (!ModuleHelper.IsLoadLock(Source)) { if (ModuleHelper.IsCoolingBuffer(Source) || ModuleHelper.IsAligner(Source)) { SwapWafer((int)Swap.SwapWafer, "Swap wafer", Source, Slot, _pickHand, OffsetX, OffsetY, OffsetZ, Notify, Stop); } else { PickWafer((int)Swap.PickWafer, "Pick wafer", Source, Slot, _pickHand, _offsetXPick, _offsetYPick, _offsetZPick, Notify, Stop); this.WaitRobotMotion((int)Swap.WaitPick, robot, "Wait picked", _timeout, Notify, Stop); PlaceWafer((int)Swap.PlaceWafer, "Place wafer", Source, Slot, PlaceBlade, _offsetXPlace, _offsetYPlace, _offsetZPLace, Notify, Stop); this.WaitRobotMotion((int)Swap.WaitPlace, robot, "Wait Placed", _timeout, Notify, Stop); } } //} this.WaitRobotMotion((int)Swap.WaitSwap, robot, "Wait swap finish", _timeout, Notify, Stop); //if (ModuleHelper.IsLoadPort(Source)) //{ // RobotBusytoSimif((int)Swap.RobotBusytoSimifOn, Source, true, _timeout, Notify, Stop); //} if (ModuleHelper.IsCoolingBuffer(Source) || ModuleHelper.IsAligner(Source)) { var dev = GetCoolBuffer(Source); if (dev != null) { TimeDelay((int)Swap.PinDown, delaytime); CoolBufferMoveDown((int)Swap.CoolBufferMoveDown, GetCoolBuffer(Source), WaferManager.Instance.GetWaferSize(Source, Slot), _timeout, Notify, Stop); WaitCoolBufferMoveDown((int)Swap.WaitCoolBufferMoveDown, GetCoolBuffer(Source), "Wait CoolingBuffer Move Down...", _timeout, Notify, Stop); } } else if(ModuleHelper.IsFlipper(Source)) { FlipperComplete((int)Swap.NotifyFlipperOver, GetFlipper(), "Flipper Complete Transfer...", _timeout, Notify, Stop); } PostMessage((int)Swap.PostMessage, string.Format("Swap wafer {0}{1:D2} place blade {2}", Source.ToString(), Slot + 1, PlaceBlade.ToString())); CheckBladeWaferIsExist((int)Swap.CheckBlade1WaferPrecenseAfterSwap, robot, Hand.Blade1, _timeout); CheckBladeWaferIsExist((int)Swap.CheckBlade2WaferPrecenseAfterSwap, robot, Hand.Blade2, _timeout); CheckAfterSwap((int)Swap.CheckAfterSwap, "Check wafer information after swap", Source, Slot, PlaceBlade, Notify, Stop); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { IsStopped = true; return Result.FAIL; } IsStopped = true; return Result.DONE; } protected override void Notify(string message) { EV.PostMessage(Module, EventEnum.GeneralInfo, String.Format("Swap wafer:{0}", message)); } /// /// prepare process failed /// /// /// protected override void Stop(string failReason) { string reason = String.Empty; EV.PostMessage(ModuleName.System.ToString(), EventEnum.GeneralInfo, string.Format("Swap wafer {0}{1:D2} with arm {2} failed, {3}", Source.ToString(), Slot + 1, PlaceBlade.ToString(), failReason)); } private void SwapWafer(int id, string name, ModuleName chamber, int slot, Hand blade, int x, int y, int z, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("Swap wafer {0}{1:D2}", chamber.ToString(), slot)); string reason = string.Empty; if (x == 0 && y == 0 && z == 0) return robot.Swap((RobotArmEnum)blade,chamber.ToString(), slot); return robot.SwapEx((RobotArmEnum)blade, chamber.ToString(), slot, x, y, z,0); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } public void CheckBeforeSwap(int id, string name, ModuleName chamber, int slot, Hand blade, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("Check target {0}{1:D2} wafer information", chamber.ToString(), slot)); string reason = string.Empty; if (!CheckRobotMotionInterlock(chamber, slot, out reason)) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.TransferPrepareFailed, String.Format("target {0}{1:D2},{2}", chamber.ToString(), slot + 1, reason)); return false; } if (blade == Hand.Blade1) { bool bHasWafer = WaferManager.Instance.CheckWafer(chamber, slot, WaferStatus.Normal); if (!bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, String.Format("target {0}{1:D2}", chamber.ToString(), slot + 1)); return false; } bHasWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)Hand.Blade1, WaferStatus.Normal); if (bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade1); //check sensor if (bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } bool bNoWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)Hand.Blade2, WaferStatus.Normal); if (!bNoWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick); return false; } bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)Hand.Blade2); //check sensor if (bNoWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick); return false; } } else { bool bHasWafer = WaferManager.Instance.CheckWafer(chamber, slot, WaferStatus.Normal); if (!bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferAbsentWithoutRecord, String.Format("target {0}{1:D2}", chamber.ToString(), slot + 1)); return false; } bHasWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)Hand.Blade2, WaferStatus.Normal); if (bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade2); //check sensor if (bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedBeforeSend); return false; } bool bNoWafer = WaferManager.Instance.CheckWafer(ModuleName.Robot, (int)Hand.Blade1, WaferStatus.Normal); if (!bNoWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick); return false; } bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)Hand.Blade1); //check sensor if (bNoWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedBeforePick); return false; } } return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { error(String.Format("Failed to swap, wafer information not correct.")); throw (new RoutineFaildException()); } } } public void CheckAfterSwap(int id, string name, ModuleName chamber, int slot, Hand blade, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(name); if (blade == Hand.Blade1) { bool bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)Hand.Blade1); if (!bNoWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend); return false; } bool bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade2); if (!bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick); return false; } } else { bool bNoWafer = CheckSensorNoWafer(ModuleName.Robot, (int)Hand.Blade2); if (!bNoWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDetectedAfterSend); return false; } bool bHasWafer = CheckSeneorHasWafer(ModuleName.Robot, (int)Hand.Blade1); if (!bHasWafer) { EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferNotDetectedAfterPick); return false; } } return true; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { error(String.Format("Failed to check information after swap.")); throw (new RoutineFaildException()); } } } } }