using System; using Aitex.Core.Common; using Aitex.Core.RT.Event; 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 VirgoCommon; using VirgoRT.Devices; namespace VirgoRT.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; private double _OffsetTemp = 0.0f; public PMPrepareTransferRoutine(JetPM chamber, VentRoutine _vRoutine) : base(chamber) { Name = "PrepareTransfer"; _ventRoutine = _vRoutine; } public Result Init(EnumTransferType type, float temp, WaferSize size) { _TransferType = type; _ws = size; _temp = temp; if (type == EnumTransferType.Place) { Name = $"Prepare Place {_ws}"; } else if (type == EnumTransferType.Pick) { size = WaferManager.Instance.GetWafer(_chamber.Module, 0).Size; Name = $"Prepare Pick {_ws}"; } return Result.DONE; } public Result Init(EnumTransferType type, float temp) { WaferSize ws = WaferSize.WS0; if (type == EnumTransferType.Place) { ws = WaferManager.Instance.GetWafer(ModuleName.EfemRobot, 0).Size; } else if (type == EnumTransferType.Pick) { ws = WaferManager.Instance.GetWafer(_chamber.Module, 0).Size; } return Init(type, temp, ws); } public Result Start(params object[] objs) { Reset(); _timeout = SC.GetValue($"{Module}.PrepareTransferTimeout"); _tolerance = SC.GetValue($"System.MaxTemperatureToleranceToTarget"); _OffsetTemp = SC.GetValue($"{Module}.Chiller.ChillerTemperatureOffset"); Notify($"开始, 准备 {(_TransferType == EnumTransferType.Place ? "放" : _TransferType == EnumTransferType.Pick ? "取" : "动作未知")}{_ws} 寸片, "); if (SC.GetValue("System.IsATMMode") && !_chamber.CheckAtm()) { EV.PostWarningLog(ModuleName.System.ToString(), $"Running in ATMmode,{_chamber.DeviceID} not in ATM now!"); } return Result.RUN; } public Result Monitor() { try { // vent if (!SC.GetValue("System.IsATMMode") && _chamber.IsSlitDoorClosed) { ExecuteRoutine((int)RoutineStep.Vent, _ventRoutine); } if (_TransferType == EnumTransferType.Place) { if (!SC.GetValue("System.IsATMMode") && _temp > 10) { if (SC.GetValue($"{Module}.Chiller.EnableChiller")) { CheckCoolantTemp((int)RoutineStep.CheckTemp, _temp, _OffsetTemp, _timeout, _tolerance); } else { CheckSubstrateTemp((int)RoutineStep.CheckTemp, _temp, _timeout, _tolerance); } } PMPreparePlace((int)RoutineStep.PrepareTransferPlace, false, _ws, true, _timeout); } else if (_TransferType == EnumTransferType.Pick) { PMPreparePick((int)RoutineStep.PrepareTransferPick, _TransferType == EnumTransferType.Pick, _ws, 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; } _chamber.PrepareGuidePinForPlace(ws); //_chamber.SetSlitDoor(isOpen, out string reason1); return true; } bool? Check1() { bool res1 = isUp ? _chamber.CheckLiftUp() : _chamber.CheckLiftDown(); bool res2 = _chamber.CheckGuidePinIsReadyForTransfer(ws); //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, WaferSize ws, 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.PrepareGuidePinForPlace(ws); //_chamber.SetSlitDoor(isOpen, out string reason1); return true; } bool? Check1() { bool res1 = isUp ? _chamber.CheckLiftUp() : _chamber.CheckLiftDown(); //bool res2 = isOpen ? _chamber.CheckSlitDoorOpen() : _chamber.CheckSlitDoorClose(); bool res3 = _chamber.CheckGuidePinIsReadyForTransfer(ws); 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 SetGuidePinUp(int id, WaferSize ws, int timeout) { Tuple ret = ExecuteAndWait(id, () => { Notify($"set Guide pin {_chamber.Name} " + "升"); _chamber.PrepareGuidePinForPlace(ws); return true; }, () => { return _chamber.CheckGuidePinIsReadyForTransfer(ws); }, 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(); } } } }