using System; using System.Collections.Generic; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.RecipeCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using JetVirgoPM.Devices; using JetVirgoPM.PMs.Routines; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs; using MECF.Framework.RT.ModuleLibrary.PMModules; namespace JetVirgoPM.PMs.RecipeExecutors { class PreProcessRoutine : PMRoutineBase { public enum Routine { DelayForTest, SetLiftPin, SetSlitDoor, CheckCoolant1Temp1, CheckCoolant1Temp2, CheckTemp1, CheckTemp2, CheckLETemp, CheckDryPump, PumpDown, SetRfMatchMode, SetElectrodeTemp, SetHeaterTemp, PinDownAndPump, End, } //---------------------------------Fields---------------------------------------- // private readonly PumpDownRoutine _pumpRoutine; private readonly TemperatureControlRoutine _TempRoutine; private int _checkChamberTempTimeout = 60; private double _tolerance; private double _Chiller1OffsetTemp = 0.0f; private double _Chiller2OffsetTemp = 0.0f; private bool _bPinDownExecuted = false; private readonly int _PumpingAndPinDownTimeout = 60 * 1000; //---------------------------------Properties------------------------------------ // public string CurrentRecipeBaseName { get; private set; } public string CurrentRecipeRunningName { get; private set; } public string CurrentRecipeContent { get; private set; } public string CurrentLotName { get; set; } public List CurrentRecipeStepList { get; set; } public RecipeHead CurrentRecipeHead { get; set; } private bool _withWafer; public bool _Chamber1Disabled; public bool _Chamber2Disabled; private bool _enableChiller1; private bool _enableChiller2; private bool _enableLE1; private bool _enableLE2; private int _pumpBasePressure; private double _pumpTimeLimit; private double BasePressure { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.BasePressure)) { double setpoint = Convert.ToDouble(CurrentRecipeHead.BasePressure); if (setpoint > 0 && setpoint < 750000) return setpoint; } } return _pumpBasePressure; } } private double PumpDownLimit { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.PumpDownLimit)) { double setpoint = Convert.ToDouble(CurrentRecipeHead.PumpDownLimit); if (setpoint > 0 && setpoint < 600) return setpoint; } } return _pumpTimeLimit; } } public bool PumpingPinIsUp { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.PumpingPinState)) { return CurrentRecipeHead.PumpingPinState == "Up" ? true : false; } } return false; } } public double Chamber1Temp { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.Chamber1Temperature)) { double setpoint = Convert.ToDouble(CurrentRecipeHead.Chamber1Temperature); if (setpoint > 0 && setpoint < 600) return setpoint; } } return 0; } } public double Chamber2Temp { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.Chamber2Temperature)) { double setpoint = Convert.ToDouble(CurrentRecipeHead.Chamber2Temperature); if (setpoint > 0 && setpoint < 600) return setpoint; } } return 0; } } private int PinDownPressure { get { if (CurrentRecipeHead != null) { if (!string.IsNullOrEmpty(CurrentRecipeHead.PinDownPressure)) { int setpoint = Convert.ToInt32(CurrentRecipeHead.PinDownPressure); if (setpoint > 0) return setpoint; } } return 1000; } } //--------------------------------Constructor------------------------------------ // public PreProcessRoutine(JetDualPM chamber, PumpDownRoutine pdr) : base(chamber) { Name = "Pre Process"; _pumpRoutine = pdr; } public void Terminate() { } public RState LoadRecipe(params object[] param) { CurrentRecipeBaseName = (string)param[0]; if (param.Length > 1) WaferID = (string)param[1]; else WaferID = null; if (param.Length > 2) _withWafer = (bool)param[2]; else _withWafer = true; if (_withWafer && WaferManager.Instance.CheckNoWafer(Module, 0) && WaferManager.Instance.CheckNoWafer(Module, 1)) { EV.PostWarningLog(Module.ToString(), $"can not load recipe, no wafer at {Module}"); return RState.Failed; } CurrentRecipeContent = RecipeFileManager.Instance.LoadRecipe("", CurrentRecipeBaseName, true); if (string.IsNullOrEmpty(CurrentRecipeContent)) { EV.PostInfoLog(ModuleName.System.ToString(), $"error during read recipe file {CurrentRecipeBaseName}"); return RState.Failed; } if (!RecipeFileManager.Instance.CheckRecipe(Module, CurrentRecipeContent, out var reasons)) { EV.PostAlarmLog(Module, $"recipe file content not valid {CurrentRecipeBaseName}"); string info = ""; foreach (var item in reasons) info += item; EV.PostPopDialogMessage(EventLevel.Alarm, "recipe file not valid", info); } CurrentRecipeRunningName = $"{CurrentRecipeBaseName}"; if (!Recipe.Parse(Module, CurrentRecipeContent, out RecipeHead recipeHead, out var recipeSteps)) { return RState.Failed; } CurrentRecipeStepList = recipeSteps; CurrentRecipeHead = recipeHead; return RState.End; } public RState Start(params object[] param) { if (_withWafer && WaferManager.Instance.CheckNoWafer(Module, 0) && WaferManager.Instance.CheckNoWafer(Module, 1)) { EV.PostWarningLog(Module.ToString(), $"can not run process, no wafer at {Module}"); return RState.Failed; } //if (CheckSlitDoor1() != Result.RUN||CheckSlitDoor2() != Result.RUN || CheckDryPump() != Result.RUN) //{ // return Result.FAIL; //} if (CheckDryPump() != RState.Running) { return RState.Failed; } _chamber.SetGenerator1CommunicationMode(1); // RS232 mode _chamber.SetGenerator2CommunicationMode(1); // RS232 mode _Chamber1Disabled = _chamber.Chamber1Disable; _Chamber2Disabled = _chamber.Chamber2Disable; _enableChiller1 = _chamber.Chiller1Enable; _enableChiller2 = _chamber.Chiller2Enable; _pumpBasePressure = SC.GetValue($"{Module}.Pump.PumpBasePressure"); _pumpTimeLimit = SC.GetValue($"{Module}.Pump.PumpTimeLimit"); _tolerance = SC.GetValue($"System.MaxTemperatureToleranceToTarget"); _Chiller1OffsetTemp = SC.GetValue($"{Module}.Chiller1.ChillerTemperatureOffset"); _Chiller2OffsetTemp = SC.GetValue($"{Module}.Chiller2.ChillerTemperatureOffset"); try { if (BasePressure <= 0 || BasePressure >= 760000) { return RState.Failed; } if (PumpDownLimit <= 0.01 || PumpDownLimit >= 600) { return RState.Failed; } _checkChamberTempTimeout = SC.GetValue($"{Module}.CheckChamberTempTimeout"); Reset(); //RecipeRunGuid = Guid.NewGuid(); //ProcessDataRecorder.Start(RecipeRunGuid.ToString(), CurrentRecipeRunningName.Split('\\')[1], WaferID, CurrentRecipeRunningName.Split('\\')[0]); //RecipeFileManager.Instance.SaveRecipeHistory(ModuleName.System.ToString(), CurrentRecipeRunningName, CurrentRecipeContent); } catch (Exception ex) { LOG.Write(ex, "Preprocess Start has exception"); throw ex; } _bPinDownExecuted = false; _enableLE1 = true; _enableLE2 = true; return Runner.Start(_chamber.Module.ToString(), Name); } public RState Monitor() { Runner.Run(Routine.SetSlitDoor, HOFs.Apply(SetSlitDoor, EnumDualPM.Both, false), HOFs.Apply(CheckSlitDoor, EnumDualPM.Both, false), 5000) .Run(Routine.PinDownAndPump, PumpStart, CheckPumpAndPinDown, _delay_60s) .Run(Routine.CheckCoolant1Temp1, SetCoolant1Temp, CheckCoolant1Temp, _checkChamberTempTimeout * 1000) .Run(Routine.CheckCoolant1Temp2, SetCoolant2Temp, CheckCoolant2Temp, _checkChamberTempTimeout * 1000) .Run(Routine.CheckLETemp, SetLETemp, CheckLETemp, _checkChamberTempTimeout * 1000) .Run(Routine.CheckTemp1, SetLETemp1, CheckLETemp1, _checkChamberTempTimeout * 1000) .Run(Routine.CheckTemp2, SetLETemp2, CheckLETemp2, _checkChamberTempTimeout * 1000) .End(Routine.End, EndFunc, _delay_50ms); return Runner.Status; } public void Exit() { } bool PumpStart() { return _pumpRoutine.Start(BasePressure) == RState.Running; } bool CheckPumpAndPinDown() { if (!_bPinDownExecuted && !PumpingPinIsUp && ((_chamber.ChamberPressure <= PinDownPressure) || (PinDownPressure <= BasePressure))) { _bPinDownExecuted = true; Notify($"设置 lift pin {_chamber.Name} " + "降" + $"抽气时降顶针:PinDownPressure{PinDownPressure.ToString()},ChamberPressurePressure{_chamber.ChamberPressurePressure.ToString()}" + $",BasePressure{BasePressure.ToString()}"); if (!_Chamber1Disabled && !_chamber.SetLiftPin1(MovementPosition.Down, out string reasonPin1)) { Stop(reasonPin1); return false; } if (!_Chamber2Disabled && !_chamber.SetLiftPin2(MovementPosition.Down, out string reasonPin2)) { Stop(reasonPin2); return false; } } bool res1 = _Chamber1Disabled || _chamber.CheckLift1Down(); bool res2 = _Chamber2Disabled || _chamber.CheckLift2Down(); var result = _pumpRoutine.Monitor(); if(result == RState.Failed || result == RState.Timeout) { Runner.Stop($"设置 Pump {_chamber.Name} failed " + $"抽气时降顶针:PinDownPressure{PinDownPressure.ToString()},ChamberPressurePressure{_chamber.ChamberPressurePressure.ToString()}" + $",BasePressure{BasePressure.ToString()}"); return true; } return (PumpingPinIsUp || (res1 && res2)) && (result == RState.End); } bool SetCoolant1Temp() { if (!SC.IsATMMode && _enableChiller1 && !_Chamber1Disabled && Chamber1Temp > 0) { _enableLE1 = false; return SetCoolant1Temp(Chamber1Temp, _Chiller1OffsetTemp, _tolerance); } return true; } bool CheckCoolant1Temp() { if (!SC.IsATMMode && _enableChiller1 && !_Chamber1Disabled && Chamber1Temp > 0) { return CheckCoolant1Temp(Chamber1Temp, _Chiller1OffsetTemp, _tolerance); } return true; } bool SetCoolant2Temp() { if (!SC.IsATMMode && _enableChiller2 && !_Chamber2Disabled && Chamber2Temp > 0) { _enableLE2 = false; return SetCoolant2Temp(Chamber2Temp, _Chiller2OffsetTemp, _tolerance); } return true; } bool CheckCoolant2Temp() { if (!SC.IsATMMode && _enableChiller2 && !_Chamber2Disabled && Chamber2Temp > 0) { return CheckCoolant2Temp(Chamber2Temp, _Chiller2OffsetTemp, _tolerance); } return true; } bool SetLETemp() { if (!SC.IsATMMode && (_enableLE1 && !_Chamber1Disabled && Chamber1Temp > 0) && (_enableLE2 && !_Chamber2Disabled && Chamber2Temp > 0)) { return SetLETemp(Chamber1Temp, Chamber2Temp, _tolerance, _enableLE1, _enableLE2); } return true; } bool CheckLETemp() { if (!SC.IsATMMode && (_enableLE1 && !_Chamber1Disabled && Chamber1Temp > 0) && (_enableLE2 && !_Chamber2Disabled && Chamber2Temp > 0)) { return CheckLETemp(Chamber1Temp, Chamber2Temp, _tolerance, _enableLE1, _enableLE2); } return true; } bool SetLETemp1() { if (!SC.IsATMMode && _enableLE1 && !_Chamber1Disabled && Chamber1Temp > 0) { return SetLETemp(Chamber1Temp, 0, _tolerance, _enableLE1, false); } return true; } bool CheckLETemp1() { if (!SC.IsATMMode && _enableLE1 && !_Chamber1Disabled && Chamber1Temp > 0) { return CheckLETemp(Chamber1Temp, 0, _tolerance, _enableLE1, false); } return true; } bool SetLETemp2() { if (!SC.IsATMMode && _enableLE2 && !_Chamber2Disabled && Chamber2Temp > 0) { return SetLETemp(0, Chamber2Temp, _tolerance, false, _enableLE2); } return true; } bool CheckLETemp2() { if (!SC.IsATMMode && _enableLE2 && !_Chamber2Disabled && Chamber2Temp > 0) { return CheckLETemp(0, Chamber2Temp, _tolerance, false, _enableLE2); } return true; } } }