MoS2/App/Modules/SicModules/PMs/Routines/PMPostTransferRoutine.cs
SIC1016\caipeilun 1a9f180e2b PMroutine修改
2026-08-04 18:19:29 +08:00

422 lines
16 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<IoThrottleValve2>($"{Module}.TV");
_rotationSpeed = SC.GetValue<int>($"PM.{Module}.ProcessIdle.RotationSpeed");
_pmPressureMaxDiff = SC.GetValue<double>($"PM.{Module}.ThrottlePressureMaxDiff");
_throttleFinalPressure = SC.GetValue<double>($"PM.{Module}.ProcessIdle.FinalPressure");
_throttleTimeout = SC.GetValue<int>($"PM.{Module}.ThrottlePressureTimeout");
_psuHeatEnable = SC.GetValue<bool>($"PM.{Module}.ProcessIdle.PSUHeaterEnable");
_psuHeatMode = SC.GetValue<int>($"PM.{Module}.ProcessIdle.PSUHeaterMode");
//_psuPowerRef = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUPowerRef");
_psuL1Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUInnerRatio");
_psuL2Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUMiddleRatio");
_psuL3Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.PSUOuterRatio");
_scrHeatEnable = SC.GetValue<bool>($"PM.{Module}.ProcessIdle.SCRHeaterEnable");
_scrHeatMode = SC.GetValue<int>($"PM.{Module}.ProcessIdle.SCRHeaterMode");
//_scrPowerRef = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRPowerRef");
_scrL1Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRUpperRatio");
_scrL2Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRMiddleRatio");
_scrL3Ratio = (float)SC.GetValue<double>($"PM.{Module}.ProcessIdle.SCRLowerRatio");
_targetPressure = SC.GetValue<double>($"PM.{Module}.ProcessIdle.FinalPressure");
_servoUpDelay = SC.GetValue<int>($"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<bool, Result> 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<bool, Result> 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<bool, Result> 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<bool, Result> 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");
}
}
}