using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.SCCore; using Aitex.Sorter.Common; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; namespace Aitex.Sorter.RT.Module.Recipe { /// /// /// 把同一个Foup内分散的wafer集中起来;可选align或者read wafer id /// /// class RecipeParserPack : IRecipeParser { public SorterRecipeXml XmlRecipe { get; set; } public bool Init(SorterRecipeXml xmlRecipe, out string reason) { reason = string.Empty; if (xmlRecipe.RecipeType != SorterRecipeType.Pack) { LOG.Write("xml recipe type not valid, " + xmlRecipe.RecipeType); reason = "Recipe xml file not valid"; return false; } XmlRecipe = xmlRecipe; return true; } public List Parse(out string reason) { List result = new List(); reason = string.Empty; //string paramName = string.Empty; //switch (XmlRecipe.Source[0]) //{ // case ModuleName.LP1: // paramName = ParamName.WaferInfoFoupA; // break; // case ModuleName.LP2: // paramName = ParamName.WaferInfoFoupB; // break; // case ModuleName.LP3: // paramName = ParamName.WaferInfoFoupC; // break; // case ModuleName.LP4: // paramName = ParamName.WaferInfoFoupD; // break; // default: // reason = string.Format("recipe source {0} not valid", XmlRecipe.Source); // return result; //} //WaferInfo[] foupInfos = (WaferInfo[])DATA.Poll(ChamberSetString.System, paramName); //Array.Reverse(foupInfos); List wafersInSourceList = new List(); List SourceModules = new List(); bool isLoad = false; for (int i = 0; i < XmlRecipe.Source.Count; i++) { LoadPort lp = DEVICE.GetDevice(XmlRecipe.Source[i].ToString()); if (lp.IsEnableTransferWafer(out reason)) { isLoad = true; WaferInfo[] wafersInSource = WaferManager.Instance.GetWafers(XmlRecipe.Source[i]); wafersInSourceList.Add(wafersInSource); SourceModules.Add(XmlRecipe.Source[i]); } } if (!isLoad) { reason = "Source is not valid for transfer."; return result; } if (wafersInSourceList.Count == 0) { reason = "Please choose Sources"; return result; } switch (XmlRecipe.PlaceModePack) { case SorterRecipePlaceModePack.FromBottomInsert: FromBottomInsert(wafersInSourceList, SourceModules, ref result, out reason); break; case SorterRecipePlaceModePack.FromBottomShift: FromBottomShift(wafersInSourceList, SourceModules, ref result, out reason); break; case SorterRecipePlaceModePack.FromTopInsert: FromTopInsert(wafersInSourceList, SourceModules, ref result, out reason); break; case SorterRecipePlaceModePack.FromTopShift: FromTopShift(wafersInSourceList, SourceModules, ref result, out reason); break; default: reason = string.Format("recipe PlaceModePack {0} not valid", XmlRecipe.PlaceModePack); return result; } //if (result.Count == 0) // reason = "Recipe has no vaild transfer task."; return result; } /// /// 从最上面开始取wafer,从最下面开始找空 /// /// /// /// bool FromBottomInsert(List sourceList, List sourceModules, ref List lst, out string reason) { reason = string.Empty; for (int s = 0; s < sourceList.Count; s++) { WaferInfo[] foupInfos = WaferManager.Instance.GetWafers(XmlRecipe.Source[s]); int to = -1; for (int i = foupInfos.Length - 1; i >= 0; i--) { if (foupInfos[i].IsEmpty) continue; bool findEmpty = false; for (int j = to + 1; j < i; j++) { if (foupInfos[j].IsEmpty) { to = j; findEmpty = true; break; } } if (!findEmpty) break; lst.Add(new TransferInfo() { Source = sourceModules[s], Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 1 ? MoveOption.Reader1 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 2 ? MoveOption.Reader2 : MoveOption.None) | (XmlRecipe.IsTurnOver ? MoveOption.Turnover : MoveOption.None), Slot = to, Station = sourceModules[s], WaferID = foupInfos[i].WaferID, }); } } return true; } /// /// 从最下面开始找空,顺序朝上找wafer /// /// /// /// bool FromBottomShift(List sourceList, List sourceModules, ref List lst, out string reason) { reason = string.Empty; for (int s = 0; s < sourceList.Count; s++) { WaferInfo[] foupInfos = WaferManager.Instance.GetWafers(XmlRecipe.Source[s]); int to = -1; for (int i = 0; i < foupInfos.Length; i++) { if (foupInfos[i].IsEmpty) continue; to++; if (i == to) continue; lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 1 ? MoveOption.Reader1 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 2 ? MoveOption.Reader2 : MoveOption.None) | (XmlRecipe.IsTurnOver ? MoveOption.Turnover : MoveOption.None), Slot = to, Source = sourceModules[s], Station = sourceModules[s], WaferID = foupInfos[i].WaferID, }); } } return true; } /// /// 从最下面开始找wafer,从最上面找空 /// /// /// /// bool FromTopInsert(List sourceList, List sourceModules, ref List lst, out string reason) { reason = string.Empty; for (int s = 0; s < sourceList.Count; s++) { WaferInfo[] foupInfos = sourceList[s]; int to = foupInfos.Length; for (int i = 0; i < foupInfos.Length; i++) { if (foupInfos[i].IsEmpty) continue; bool findEmpty = false; for (int j = to - 1; j > i; j--) { if (foupInfos[j].IsEmpty) { to = j; findEmpty = true; break; } } if (!findEmpty) break; lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 1 ? MoveOption.Reader1 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 2 ? MoveOption.Reader2 : MoveOption.None) | (XmlRecipe.IsTurnOver ? MoveOption.Turnover : MoveOption.None), Slot = to, Source = sourceModules[s], Station = sourceModules[s], WaferID = foupInfos[i].WaferID, }); } } return true; } /// /// 集中,平移到最上面 /// /// /// /// bool FromTopShift(List sourceList, List sourceModules, ref List lst, out string reason) { reason = string.Empty; for (int s = 0; s < sourceList.Count; s++) { WaferInfo[] foupInfos = WaferManager.Instance.GetWafers(XmlRecipe.Source[s]); int to = foupInfos.Length; for (int i = foupInfos.Length - 1; i >= 0; i--) { if (foupInfos[i].IsEmpty) continue; to--; if (to == i) continue; lst.Add(new TransferInfo() { Angle = XmlRecipe.AlignAngle, Option = (XmlRecipe.IsAlign ? MoveOption.Align : MoveOption.None) | (XmlRecipe.IsReadLaserMarker ? MoveOption.ReadID : MoveOption.None) | (XmlRecipe.IsReadT7Code ? MoveOption.ReadID2 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 1 ? MoveOption.Reader1 : MoveOption.None) | (XmlRecipe.WaferReaderIndex == 2 ? MoveOption.Reader2 : MoveOption.None) | (XmlRecipe.IsTurnOver ? MoveOption.Turnover : MoveOption.None), Slot = to, Source = sourceModules[s], Station = sourceModules[s], WaferID = foupInfos[i].WaferID, }); } } return true; } } }