using System; using Aitex.Core.Common; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Schedulers; using MECF.Framework.Common.SubstrateTrackings; using Virgo_DCommon; using Virgo_DRT.Devices; namespace Virgo_DRT.Modules.PMs { class PMPrepareTransferRoutine : PMRoutineBase, IRoutine { enum RoutineStep { LiftUpDown, Vent, VentDelay, SetGuidePin, CheckTemp, SetSlitDoor, SlitDoorDelay, PrepareTransferPlace, PrepareTransferPick, kEnd } private EnumTransferType _TransferType; private int _timeout; private readonly VentRoutine _ventRoutine; private WaferSize _ws; private float _temp; private double _tolerance; public PMPrepareTransferRoutine(JetPM chamber, VentRoutine _vRoutine) : base(chamber) { Name = "PrepareTransfer"; _ventRoutine = _vRoutine; } public Result Init(EnumTransferType type, float temp) { _TransferType = type; if (_TransferType == EnumTransferType.Place) { _ws = WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).Size; Name = $"Prepare Place {_ws}"; } else if (_TransferType == EnumTransferType.Pick) { _ws = WaferManager.Instance.GetWafer(_chamber.Module, 0).Size; Name = $"Prepare Pick {_ws}"; } _temp = temp; return Result.DONE; } public Result Start(params object[] objs) { Reset(); _timeout = SC.GetValue($"{Module}.PrepareTransferTimeout"); _tolerance = SC.GetValue($"System.MaxTemperatureToleranceToTarget"); Notify($"开始, 准备 {(_TransferType == EnumTransferType.Place ? "放" : _TransferType == EnumTransferType.Pick ? "取" : "动作未知")}{_ws} 寸片, "); return Result.RUN; } public Result Monitor() { try { // vent if (!SC.GetValue("System.IsATMMode")) { ExecuteRoutine((int)RoutineStep.Vent, _ventRoutine); } if (_TransferType == EnumTransferType.Place) { if (_temp > 10) { CheckSubstrateTemp((int)RoutineStep.CheckTemp, _temp, _timeout, _tolerance); } PMPreparePlace((int)RoutineStep.PrepareTransferPlace, _TransferType == EnumTransferType.Pick, _ws, true, _timeout); } else if (_TransferType == EnumTransferType.Pick) { PMPreparePick((int)RoutineStep.PrepareTransferPick, _TransferType == EnumTransferType.Pick, true, _timeout); } End((int)RoutineStep.kEnd); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { Notify("出错"); return Result.FAIL; } catch (Exception ex) { Stop(ex.Message); return Result.FAIL; } Notify("结束"); return Result.DONE; } public override void Abort() { } public void PMPreparePlace(int id, bool isUp, WaferSize ws, bool isOpen, int timeout) { bool Func() { Notify($"设置 liftPin {(isUp ? "升" : "降")}, 设置 {ws} Pin 升, 设置 SlitDoor {(isOpen ? "开" : "关")}"); if (!_chamber.SetLiftPin(isUp ? MovementPosition.Up : MovementPosition.Down, out string reason)) { Stop(reason); return false; } if (ws == WaferSize.WS3) { _chamber.SetGuidePin3Inch(MovementPosition.Up); _chamber.SetGuidePin4Inch(MovementPosition.Down); } else if (ws == WaferSize.WS4) { _chamber.SetGuidePin4Inch(MovementPosition.Up); _chamber.SetGuidePin3Inch(MovementPosition.Down); } else if (ws == WaferSize.WS6) { _chamber.SetGuidePin3Inch(MovementPosition.Down); _chamber.SetGuidePin4Inch(MovementPosition.Down); } _chamber.SetSlitDoor(isOpen, out string reason1); return true; } bool? Check1() { bool res1 = isUp ? _chamber.CheckLiftUp() : _chamber.CheckLiftDown(); bool res2 = false; switch (ws) { case WaferSize.WS3: res2 = _chamber.Inch3Position == MovementPosition.Up && _chamber.Inch4Position == MovementPosition.Down; break; case WaferSize.WS4: res2 = _chamber.Inch4Position == MovementPosition.Up && _chamber.Inch3Position == MovementPosition.Down; break; case WaferSize.WS6: res2 = _chamber.Inch3Position == MovementPosition.Down && _chamber.Inch4Position == MovementPosition.Down; break; } bool res3 = isOpen ? _chamber.CheckSlitDoorOpen() : _chamber.CheckSlitDoorClose(); return res1 && res2 && res3; } Tuple ret = ExecuteAndWait(id, Func, Check1, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } if (ret.Item2 == Result.TIMEOUT) { Stop($"无法 放片准备 in {timeout} seconds"); throw new RoutineFaildException(); } throw new RoutineBreakException(); } } public void PMPreparePick(int id, bool isUp, bool isOpen, int timeout) { bool Func() { Notify($"设置 LiftPin {(isUp ? "升" : "降")}, 设置 SlitDoor {(isOpen ? "开" : "关")}"); if (!_chamber.SetLiftPin(isUp ? MovementPosition.Up : MovementPosition.Down, out string reason)) { Stop(reason); return false; } _chamber.SetSlitDoor(isOpen, out string reason1); return true; } bool? Check1() { bool res1 = isUp ? _chamber.CheckLiftUp() : _chamber.CheckLiftDown(); bool res2 = isOpen ? _chamber.CheckSlitDoorOpen() : _chamber.CheckSlitDoorClose(); return res1 && res2; } Tuple ret = ExecuteAndWait(id, Func, Check1, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } if (ret.Item2 == Result.TIMEOUT) { Stop($"无法 取片准备 in {timeout} seconds"); throw new RoutineFaildException(); } throw new RoutineBreakException(); } } public void SetLiftPinUpDown(int id, bool isUp, int timeout) { Tuple ret = ExecuteAndWait(id, () => { Notify($"设置 lift pin {_chamber.Name} " + (isUp ? "升" : "降")); if (!_chamber.SetLiftPin(isUp ? MovementPosition.Up : MovementPosition.Down, out string reason)) { Stop(reason); return false; } return true; }, () => isUp ? _chamber.CheckLiftUp() : _chamber.CheckLiftDown(), timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } else if (ret.Item2 == Result.TIMEOUT) //timeout { Stop($"无法 {(isUp ? "Up" : "Down")} lift pin in {timeout} seconds"); throw new RoutineFaildException(); } else throw new RoutineBreakException(); } } public void SetGuidePinUp(int id, WaferSize ws, int timeout) { Tuple ret = ExecuteAndWait(id, () => { Notify($"set Guide pin {_chamber.Name} " + "升"); if (ws == WaferSize.WS3) { _chamber.SetGuidePin3Inch(MovementPosition.Up); _chamber.SetGuidePin4Inch(MovementPosition.Down); } else if (ws == WaferSize.WS4) { _chamber.SetGuidePin4Inch(MovementPosition.Up); _chamber.SetGuidePin3Inch(MovementPosition.Down); } else if (ws == WaferSize.WS6) { _chamber.SetGuidePin3Inch(MovementPosition.Down); _chamber.SetGuidePin4Inch(MovementPosition.Down); } return true; }, () => { bool res = false; switch (ws) { case WaferSize.WS3: res = _chamber.Inch3Position == MovementPosition.Up && _chamber.Inch4Position == MovementPosition.Down; break; case WaferSize.WS4: res = _chamber.Inch4Position == MovementPosition.Up && _chamber.Inch3Position == MovementPosition.Down; break; case WaferSize.WS6: res = _chamber.Inch3Position == MovementPosition.Down && _chamber.Inch4Position == MovementPosition.Down; break; } return res; }, timeout * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } else if (ret.Item2 == Result.TIMEOUT) //timeout { Stop($"can not complete in {timeout} seconds"); throw new RoutineFaildException(); } else throw new RoutineBreakException(); } } } }