|
@@ -1,427 +0,0 @@
|
|
|
-using Aitex.Common.Util;
|
|
|
-using Aitex.Core.RT.Event;
|
|
|
-using Aitex.Core.RT.Log;
|
|
|
-using Aitex.Core.RT.SCCore;
|
|
|
-
|
|
|
-using System;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.Xml;
|
|
|
-
|
|
|
-namespace Venus_RT.Modules
|
|
|
-{
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- public class RecipeHead
|
|
|
- {
|
|
|
- public string RecipeVariation { get; set; }
|
|
|
- public string CreationTime { get; set; }
|
|
|
- public string LastRevisionTime { get; set; }
|
|
|
- public string CreatedBy { get; set; }
|
|
|
- public string LastModifiedBy { get; set; }
|
|
|
- public string PressureMode { get; set; }
|
|
|
- public string Description { get; set; }
|
|
|
- public string Barcode { get; set; }
|
|
|
- public string BasePressure { get; set; }
|
|
|
- public string PumpDownLimit { get; set; }
|
|
|
-
|
|
|
-
|
|
|
- public string PurgeActive { get; set; }
|
|
|
- public string MatchPositionC1 { get; set; }
|
|
|
- public string MatchPositionC2 { get; set; }
|
|
|
- public string SubstrateTemp { get; set; }
|
|
|
- public string PumpingPinState { get; set; }
|
|
|
- public string NotToPurgeOrVent { get; set; }
|
|
|
- public string VentingPinState { get; set; }
|
|
|
- public string PinDownPressure { get; set; }
|
|
|
- }
|
|
|
-
|
|
|
- public class RecipeStep
|
|
|
- {
|
|
|
- public string StepName;
|
|
|
- public double StepTime;
|
|
|
- public bool IsJumpStep;
|
|
|
- public bool IsLoopStartStep;
|
|
|
- public bool IsLoopEndStep;
|
|
|
- public int LoopCount;
|
|
|
- public string EndBy;
|
|
|
- public string EndPointConfig;
|
|
|
- public bool FaultIfNoEPDTrigger;
|
|
|
-
|
|
|
-
|
|
|
- public Dictionary<string, string> RecipeCommands = new Dictionary<string, string>();
|
|
|
- public Dictionary<string, object[]> ToleranceCommands = new Dictionary<string, object[]>();
|
|
|
- }
|
|
|
-
|
|
|
- public class Recipe
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- public static Guid CurrentRecipeRunGuid;
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- public static bool Parse(string chamberId, string recipe, out RecipeHead recipeHead, out List<RecipeStep> recipeData)
|
|
|
- {
|
|
|
- recipeHead = new RecipeHead();
|
|
|
- recipeData = new List<RecipeStep>();
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
- HashSet<string> recipeAllowedCommands = new HashSet<string>();
|
|
|
- XmlDocument rcpFormatDoc = new XmlDocument();
|
|
|
-
|
|
|
- string recipeSchema = PathManager.GetCfgDir() + "RecipeFormat.xml";
|
|
|
- rcpFormatDoc.Load(recipeSchema);
|
|
|
-
|
|
|
- XmlNodeList rcpItemNodeList = rcpFormatDoc.SelectNodes("/Aitex/TableRecipeFormat/Catalog/Group/Step");
|
|
|
- foreach (XmlElement item in rcpItemNodeList)
|
|
|
- recipeAllowedCommands.Add(item.Attributes["ControlName"].Value);
|
|
|
-
|
|
|
-
|
|
|
- XmlDocument rcpDataDoc = new XmlDocument();
|
|
|
- rcpDataDoc.LoadXml(recipe);
|
|
|
-
|
|
|
- recipeHead.PressureMode = rcpDataDoc.DocumentElement.HasAttribute("PressureMode") ? rcpDataDoc.DocumentElement.Attributes["PressureMode"].Value : "";
|
|
|
-
|
|
|
- recipeHead.BasePressure = rcpDataDoc.DocumentElement.HasAttribute("BasePressure") ? rcpDataDoc.DocumentElement.Attributes["BasePressure"].Value : "";
|
|
|
-
|
|
|
- recipeHead.PumpDownLimit = rcpDataDoc.DocumentElement.HasAttribute("PumpDownLimit") ? rcpDataDoc.DocumentElement.Attributes["PumpDownLimit"].Value : "";
|
|
|
-
|
|
|
- recipeHead.PurgeActive = rcpDataDoc.DocumentElement.HasAttribute("PurgeActive") ? rcpDataDoc.DocumentElement.Attributes["PurgeActive"].Value : "";
|
|
|
-
|
|
|
- recipeHead.MatchPositionC1 = rcpDataDoc.DocumentElement.HasAttribute("MatchPositionC1") ? rcpDataDoc.DocumentElement.Attributes["MatchPositionC1"].Value : "";
|
|
|
-
|
|
|
- recipeHead.MatchPositionC2 = rcpDataDoc.DocumentElement.HasAttribute("MatchPositionC2") ? rcpDataDoc.DocumentElement.Attributes["MatchPositionC2"].Value : "";
|
|
|
-
|
|
|
- recipeHead.Barcode = rcpDataDoc.DocumentElement.HasAttribute("Barcode") ? rcpDataDoc.DocumentElement.Attributes["Barcode"].Value : "";
|
|
|
-
|
|
|
- recipeHead.SubstrateTemp = rcpDataDoc.DocumentElement.HasAttribute("SubstrateTemp") ? rcpDataDoc.DocumentElement.Attributes["SubstrateTemp"].Value : "";
|
|
|
-
|
|
|
- recipeHead.PumpingPinState = rcpDataDoc.DocumentElement.HasAttribute("PumpingPinState") ? rcpDataDoc.DocumentElement.Attributes["PumpingPinState"].Value : "Down";
|
|
|
-
|
|
|
-
|
|
|
- recipeHead.NotToPurgeOrVent = rcpDataDoc.DocumentElement.HasAttribute("NotToPurgeOrVent") ? rcpDataDoc.DocumentElement.Attributes["NotToPurgeOrVent"].Value : "";
|
|
|
-
|
|
|
- recipeHead.VentingPinState = rcpDataDoc.DocumentElement.HasAttribute("VentingPinState") ? rcpDataDoc.DocumentElement.Attributes["VentingPinState"].Value : "Down";
|
|
|
-
|
|
|
- recipeHead.PinDownPressure = rcpDataDoc.DocumentElement.HasAttribute("PinDownPressure") ? rcpDataDoc.DocumentElement.Attributes["PinDownPressure"].Value : "1000";
|
|
|
-
|
|
|
- XmlNodeList stepNodeList = rcpDataDoc.SelectNodes("/TableRecipeData/Step");
|
|
|
- for (int i = 0; i < stepNodeList.Count; i++)
|
|
|
- {
|
|
|
- var recipeStep = new RecipeStep();
|
|
|
- recipeData.Add(recipeStep);
|
|
|
-
|
|
|
- XmlElement stepNode = stepNodeList[i] as XmlElement;
|
|
|
- Dictionary<string, string> dic = new Dictionary<string, string>();
|
|
|
-
|
|
|
-
|
|
|
- foreach (XmlAttribute att in stepNode.Attributes)
|
|
|
- {
|
|
|
- if (recipeAllowedCommands.Contains(att.Name))
|
|
|
- {
|
|
|
- dic.Add(att.Name, att.Value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- foreach (XmlElement subStepNode in stepNode.ChildNodes)
|
|
|
- {
|
|
|
- foreach (XmlAttribute att in subStepNode.Attributes)
|
|
|
- {
|
|
|
- if (recipeAllowedCommands.Contains(att.Name))
|
|
|
- {
|
|
|
- dic.Add(att.Name, att.Value);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- foreach (XmlElement subsubStepNode in subStepNode.ChildNodes)
|
|
|
- {
|
|
|
- foreach (XmlAttribute att in subsubStepNode.Attributes)
|
|
|
- {
|
|
|
- if (recipeAllowedCommands.Contains(att.Name))
|
|
|
- {
|
|
|
- dic.Add(att.Name, att.Value);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- recipeStep.IsJumpStep = true;
|
|
|
- recipeStep.StepName = dic["Name"];
|
|
|
- recipeStep.StepTime = double.Parse(dic["Time"]);
|
|
|
- string loopStr = dic["Loop"];
|
|
|
- recipeStep.IsLoopStartStep = System.Text.RegularExpressions.Regex.Match(loopStr, @"Loop\x20\d+\s*$").Success;
|
|
|
- recipeStep.IsLoopEndStep = System.Text.RegularExpressions.Regex.Match(loopStr, @"Loop End$").Success;
|
|
|
- if (recipeStep.IsLoopStartStep)
|
|
|
- recipeStep.LoopCount = Convert.ToInt32(loopStr.Replace("Loop", string.Empty));
|
|
|
- else
|
|
|
- recipeStep.LoopCount = 0;
|
|
|
-
|
|
|
- recipeStep.EndBy = dic["EndBy"];
|
|
|
-
|
|
|
- if (recipeStep.EndBy == "EndByRfTime")
|
|
|
- {
|
|
|
- recipeStep.StepTime = double.Parse(dic["Rf.SetPowerOnTime"]);
|
|
|
-
|
|
|
- if (recipeStep.StepTime <= 0)
|
|
|
- {
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- int rfPower = (int)Convert.ToDouble(dic["Rf.SetPower"]);
|
|
|
- dic.Add("Rf.SetPowerOnOff", rfPower > 0 ? "true" : "false");
|
|
|
- if (SC.GetValue<bool>($"{chamberId}.BiasRf.EnableBiasRF"))
|
|
|
- {
|
|
|
- int rfPowerBias = (int)Convert.ToDouble(dic["BiasRf.SetPower"]);
|
|
|
- dic.Add("BiasRf.SetPowerOnOff", rfPowerBias > 0 ? "true" : "false");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- dic.Remove("BiasRf.SetPower");
|
|
|
- dic.Remove("BiasRf.SetMatchProcessMode");
|
|
|
- dic.Remove("BiasRf.SetMatchPositionC1");
|
|
|
- dic.Remove("BiasRf.SetMatchPositionC2");
|
|
|
- }
|
|
|
-
|
|
|
- bool epdInstalled = SC.ContainsItem("System.SetUp.EPDInstalled") && SC.GetValue<bool>($"System.SetUp.EPDInstalled");
|
|
|
-
|
|
|
- if (!epdInstalled)
|
|
|
- {
|
|
|
- if (dic.ContainsKey("EPD.SetConfig"))
|
|
|
- dic.Remove("EPD.SetConfig");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- recipeStep.EndPointConfig = dic.ContainsKey("EPD.SetConfig") ? dic["EPD.SetConfig"] : null;
|
|
|
-
|
|
|
- if (string.IsNullOrEmpty(recipeStep.EndPointConfig))
|
|
|
- {
|
|
|
- if (recipeStep.EndBy == "EndByEndPoint")
|
|
|
- {
|
|
|
- EV.PostWarningLog("System", "EndPoint is empty");
|
|
|
- return false;
|
|
|
- }
|
|
|
- recipeStep.EndPointConfig = SC.GetStringValue("System.EndPoint.EndPointDefaultValue");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- List<string> items = new List<string>() { "MfcGas1", "MfcGas2", "MfcGas3", "MfcGas4", "MfcGas5", "PressureControl", "Rf", "BiasRf" };
|
|
|
- Dictionary<string, object[]> tolerance = new Dictionary<string, object[]>();
|
|
|
- foreach (var item in items)
|
|
|
- {
|
|
|
- if (item == "BiasRf" && !SC.GetValue<bool>($"{chamberId}.BiasRf.EnableBiasRF"))
|
|
|
- {
|
|
|
- dic.Remove(($"{item}.SoftTolerance"));
|
|
|
- dic.Remove(($"{item}.HardTolerance"));
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- var time = SC.GetValue<int>($"{chamberId}.RecipeToleranceIgnoreTime");
|
|
|
- var warning = dic.ContainsKey($"{item}.SoftTolerance") ? dic[$"{item}.SoftTolerance"] : "0";
|
|
|
- var alarm = dic.ContainsKey($"{item}.HardTolerance") ? dic[$"{item}.HardTolerance"] : "0";
|
|
|
- tolerance[$"{item}.SetRecipeTolerance"] = new object[]
|
|
|
- {
|
|
|
- time, warning, alarm
|
|
|
- };
|
|
|
-
|
|
|
- dic.Remove(($"{item}.SoftTolerance"));
|
|
|
- dic.Remove(($"{item}.HardTolerance"));
|
|
|
- }
|
|
|
-
|
|
|
- recipeStep.ToleranceCommands = tolerance;
|
|
|
-
|
|
|
-
|
|
|
- dic.Remove("StepNo");
|
|
|
- dic.Remove("Name");
|
|
|
- dic.Remove("Loop");
|
|
|
- dic.Remove("Time");
|
|
|
- dic.Remove("EndBy");
|
|
|
-
|
|
|
- dic.Remove("Rf.SetPowerOnTime");
|
|
|
-
|
|
|
- foreach (string key in dic.Keys)
|
|
|
- recipeStep.RecipeCommands.Add(key, dic[key]);
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
-
|
|
|
- return false;
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-}
|