using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Devices; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.MFCs; using SicModules.PMs.Routines.Base; namespace SicModules.PMs.Routines { class PMPostTransferRoutine : PMBaseRoutine { enum RoutineStep { SetUpLimit, SetBlockOn, Delay, WaitStatusCorrect, SetBlockOff, EnableRotation, EnableHeater, SetRotation1, WaitRotation1, SetTC1Mode, SetTC1Ratio, SetTC1Ref, SetTC2Mode, SetTC2Ratio, SetTC2Ref, SetChamberPressure, EnableTC1, EnableTC2, SetServoUp, SetScrReset, TimeDelay1, TimeDelay2, TimeDelay3, TimeDelay4, TimeDelay5, TimeDelay6, TimeDelay7, TimeDelay8, TimeDelay9, TimeDelay10, TimeDelay11, TimeDelay12, TimeDelay13, TimeDelay14, TimeDelay15, SetV31, SetV32, SetV35V36, SetGroupB, SetGroupC, SetGroupE, SetGroupF, SetGroupH, SetGroupK, SetGroupD, SetGroupG, SetM1toM17, SetPC, SetM18toM40, SetEPV2, SetGroupJ, SetV72, SetV25, SetPressureDown, SetTVto300 } bool hasWafer; private IoThrottleValve2 _IoThrottle; private double _throttleFinalPressure = 300;//蝶阀最终调整对的压力 private double _pmPressureMaxDiff; //蝶阀与目标压力的差值范围(认为调整到位了) private int _throttleTimeout; //蝶阀调整到指定压力的超时时间 //private int _timeout; private int _rotationSpeed = 60; private bool _psuHeatEnable = false; //是否启用PSU 加热 private int _psuHeatMode = 0; //private float _psuPowerRef = 0; private float _psuL1Ratio = 0; private float _psuL2Ratio = 0; private float _psuL3Ratio = 0; private bool _scrHeatEnable = false; //是否启用SCR 加热 private int _scrHeatMode = 0; //private float _scrPowerRef = 0; private float _scrL1Ratio = 0; private float _scrL2Ratio = 0; private float _scrL3Ratio = 0; private int _IoValueOpenCloseTimeout = 10; //开关超时时间 private double _targetPressure; private PMServoToPressure _pmServoToPressure; private bool _needEnableHeat = true; private int _servoUpDelay; //private NAISServo servo; public PMPostTransferRoutine(ModuleName module, PMModule pm1) : base(module, pm1) { Module = module.ToString(); Name = "Post Transfer Routine"; _pmServoToPressure = new PMServoToPressure(module, pm1); } public void Init(bool needEnableHeat) { _needEnableHeat = needEnableHeat; } public void Init(float basePressure, int ventDelayTime) { } public override Result Start(params object[] objs) { _IoThrottle = DEVICE.GetDevice($"{Module}.TV"); _rotationSpeed = SC.GetValue($"PM.{Module}.ProcessIdle.RotationSpeed"); _pmPressureMaxDiff = SC.GetValue($"PM.{Module}.ThrottlePressureMaxDiff"); _throttleFinalPressure = SC.GetValue($"PM.{Module}.ProcessIdle.FinalPressure"); _throttleTimeout = SC.GetValue($"PM.{Module}.ThrottlePressureTimeout"); _psuHeatEnable = SC.GetValue($"PM.{Module}.ProcessIdle.PSUHeaterEnable"); _psuHeatMode = SC.GetValue($"PM.{Module}.ProcessIdle.PSUHeaterMode"); //_psuPowerRef = (float)SC.GetValue($"PM.{Module}.ProcessIdle.PSUPowerRef"); _psuL1Ratio = (float)SC.GetValue($"PM.{Module}.ProcessIdle.PSUInnerRatio"); _psuL2Ratio = (float)SC.GetValue($"PM.{Module}.ProcessIdle.PSUMiddleRatio"); _psuL3Ratio = (float)SC.GetValue($"PM.{Module}.ProcessIdle.PSUOuterRatio"); _scrHeatEnable = SC.GetValue($"PM.{Module}.ProcessIdle.SCRHeaterEnable"); _scrHeatMode = SC.GetValue($"PM.{Module}.ProcessIdle.SCRHeaterMode"); //_scrPowerRef = (float)SC.GetValue($"PM.{Module}.ProcessIdle.SCRPowerRef"); _scrL1Ratio = (float)SC.GetValue($"PM.{Module}.ProcessIdle.SCRUpperRatio"); _scrL2Ratio = (float)SC.GetValue($"PM.{Module}.ProcessIdle.SCRMiddleRatio"); _scrL3Ratio = (float)SC.GetValue($"PM.{Module}.ProcessIdle.SCRLowerRatio"); _targetPressure = SC.GetValue($"PM.{Module}.ProcessIdle.FinalPressure"); _servoUpDelay = SC.GetValue($"PM.{Module}.PreProcess.ServoBeforeUpDelay"); _pmServoToPressure.Init(_targetPressure); hasWafer = WaferManager.Instance.CheckHasWafer(Module, 0); Reset(); Notify("Start"); return Result.RUN; } public override Result Monitor() { try { //1、 打开 V31(H2.Supply)、 V32(Ar.Supply)。 SetIoValueByGroup((int)RoutineStep.SetV31, IoGroupName.V31, true, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetV32, IoGroupName.V32, true, _IoValueOpenCloseTimeout); //2、 打开 V35(H2N2.Line1)、 V36(H2N2.Line2),关闭 B/ C / E / F / H / KValves,打开 D/ G Valves。 SetIoValueByGroup((int)RoutineStep.SetV35V36, IoGroupName.V35V36, true, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupB, IoGroupName.B, false, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupC, IoGroupName.C, false, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupE, IoGroupName.E, false, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupF, IoGroupName.F, false, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupH, IoGroupName.H, false, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupK, IoGroupName.K, false, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupD, IoGroupName.D, true, _IoValueOpenCloseTimeout); SetIoValueByGroup((int)RoutineStep.SetGroupG, IoGroupName.G, true, _IoValueOpenCloseTimeout); //3、 M1 - M17 设定为 default 值,所有 PC 设定为 default 值(PC1 - PC9)。 SetMfcToDefaultByGroup((int)RoutineStep.SetM1toM17, MfcGroupName.M1toM17, 0); SetPcToDefault((int)RoutineStep.SetPC, _lstPcList); //4、 M18 - M40(除 M30\M34\M39)) MFC 3s ramp 到 default 值。 SetMfcToDefaultByGroup((int)RoutineStep.SetM18toM40, MfcGroupName.M18toM40No303439, 3); //5、 打开 EPV2。 SetIoValueByGroup((int)RoutineStep.SetEPV2, IoGroupName.EPV2, true, _IoValueOpenCloseTimeout); //6、打开 J Valves SetIoValueByGroup((int)RoutineStep.SetGroupJ, IoGroupName.J, true, _IoValueOpenCloseTimeout); //7、打开 V72(GasBox.Vent.Pump) 关闭 V25(GasBox.Vent.Bypass), 反应腔压力伺服到300mbar(可配置) SetIoValueByGroup((int)RoutineStep.SetV72, IoGroupName.VentPump, true, _IoValueOpenCloseTimeout); TimeDelay((int)RoutineStep.TimeDelay5, 1); SetIoValueByGroup((int)RoutineStep.SetV25, IoGroupName.V25, false, _IoValueOpenCloseTimeout); SetThrottleToTargetAndNoWait((int)RoutineStep.SetPressureDown, _IoThrottle, _throttleFinalPressure); WaitThrottleToPressureAndSetMfcSpecial((int)RoutineStep.SetTVto300, _IoThrottle, _throttleFinalPressure, _pmPressureMaxDiff, _throttleTimeout); //8、设定转速(可配置) EnableRotation((int)RoutineStep.EnableRotation, 5); SetRotationValveAndNoWait((int)RoutineStep.SetRotation1, _rotationSpeed); //9、加热使能(PSU 和 SCR)(可配置) if (_psuHeatEnable && _needEnableHeat) { SetPSUEnable((int)RoutineStep.EnableTC1, true, 5); SetPSUHeatMode((int)RoutineStep.SetTC1Mode, _psuHeatMode); TimeDelay((int)RoutineStep.TimeDelay9, 1); SetPSUHeatRatio((int)RoutineStep.SetTC1Ratio, _psuL1Ratio, _psuL2Ratio, _psuL3Ratio); } if (_scrHeatEnable && _needEnableHeat) { SetSCRReset((int)RoutineStep.SetScrReset); TimeDelay((int)RoutineStep.TimeDelay10, 1); SetSCREnable((int)RoutineStep.EnableTC2, true, 5); SetSCRHeatMode((int)RoutineStep.SetTC2Mode, _scrHeatMode); TimeDelay((int)RoutineStep.TimeDelay11, 1); SetSCRHeatRatio((int)RoutineStep.SetTC2Ratio, _scrL1Ratio, _scrL2Ratio, _scrL3Ratio); } TimeDelay((int)RoutineStep.TimeDelay8, 1); WaitRotationValve((int)RoutineStep.WaitRotation1, _rotationSpeed, true, _rotationSpeed / 2); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } Notify("Finished"); return Result.DONE; } //private void ServoUpLimit(int id, PMModuleBase pm, int timeout) //{ // Tuple ret = ExecuteAndWait(id, () => // { // Notify($"Run {pm.Name} set Block No High."); // //if (!servo.SetBlockNoHigh()) // //{ // // Stop(reason); // // return false; // //} // servo.SetBlockNoHigh(); // return true; // }, () => // { // if (servo.AlarmStatus) // { // Stop($"{pm.Name} Servo in error State."); // return null; // } // if (!servo.IsBusy) // return true; // return false; // }, timeout * 1000); // if (ret.Item1) // { // if (ret.Item2 == Result.FAIL) // { // throw (new RoutineFaildException()); // } // else if (ret.Item2 == Result.TIMEOUT) //timeout // { // Stop($"{pm.Name} prepare vent timeout, over {timeout} seconds"); // throw (new RoutineFaildException()); // } // else // throw (new RoutineBreakException()); // } //} //private void ServoBlockOn(int id, PMModuleBase pm, int timeout) //{ // Tuple ret = ExecuteAndWait(id, () => // { // Notify($"Run {pm.Name} set Stb On."); // //if (!servo.SetBlockNoHigh()) // //{ // // Stop(reason); // // return false; // //} // servo.SetStbOn(); // return true; // }, () => // { // if (servo.AlarmStatus) // { // Stop($"{pm.Name} Servo in error State."); // return null; // } // if (!servo.IsBusy) // { // PMDevice.ServoStatus = ServoStatus.Uping; // return true; // } // return false; // }, timeout * 1000); // if (ret.Item1) // { // if (ret.Item2 == Result.FAIL) // { // throw (new RoutineFaildException()); // } // else if (ret.Item2 == Result.TIMEOUT) //timeout // { // Stop($"{pm.Name} prepare vent timeout, over {timeout} seconds"); // throw (new RoutineFaildException()); // } // else // throw (new RoutineBreakException()); // } //} //private void ServoBlockOff(int id, PMModuleBase pm, int timeout) //{ // Tuple ret = ExecuteAndWait(id, () => // { // Notify($"Run {pm.Name} set Stb Off."); // //if (!servo.SetBlockNoHigh()) // //{ // // Stop(reason); // // return false; // //} // servo.SetStbOff(); // return true; // }, () => // { // if (servo.AlarmStatus) // { // Stop($"{pm.Name} Servo in error State."); // return null; // } // if (!servo.IsBusy) // return true; // return false; // }, timeout * 1000); // if (ret.Item1) // { // if (ret.Item2 == Result.FAIL) // { // throw (new RoutineFaildException()); // } // else if (ret.Item2 == Result.TIMEOUT) //timeout // { // Stop($"{pm.Name} prepare vent timeout, over {timeout} seconds"); // throw (new RoutineFaildException()); // } // else // throw (new RoutineBreakException()); // } //} //private void WaitStatusCorrect(int id, PMModule pm, int timeout) //{ // Tuple ret = ExecuteAndWait(id, () => // { // Notify($"Run {pm.Name} Wait, Wait Status Correct"); // return true; // }, () => // { // if (servo.AlarmStatus) // { // Stop($"{pm.Name} Servo in error State error"); // return null; // } // if ((!servo.MotorBusy && servo.PositionComplete) && pm.ConfinementRing.IsUp) // { // PMDevice.ServoStatus = ServoStatus.Up; // return true; // } // return false; // }, timeout * 1000); // if (ret.Item1) // { // if (ret.Item2 == Result.FAIL) // { // throw (new RoutineFaildException()); // } // else if (ret.Item2 == Result.TIMEOUT) //timeout // { // Stop($"{pm.Name} vent timeout, over {timeout} seconds"); // throw (new RoutineFaildException()); // } // else // throw (new RoutineBreakException()); // } //} public override void Abort() { if (!PmDevice.StopVent(out string reason)) { EV.PostWarningLog(Module, reason); } Stop("aborted"); } } }