using System.Collections.Generic;
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到另外一个FOUP,可选Align,Read Wafer ID
///
class RecipeParserTransfer1To1 : IRecipeParser
{
public SorterRecipeXml XmlRecipe { get; set; }
public bool Init(SorterRecipeXml xmlRecipe, out string reason)
{
reason = string.Empty;
if (xmlRecipe.RecipeType != SorterRecipeType.Transfer1To1)
{
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;
List wafersInSourceList = new List();
List wafersInDestinationList = new List();
List destinationModules = 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);
}
}
if (!isLoad)
{
reason = "Source is not valid for transfer..";
return result;
}
isLoad = false;
for (int i = 0; i < XmlRecipe.Destination.Count; i++)
{
LoadPort lp = DEVICE.GetDevice(XmlRecipe.Destination[i].ToString());
if (lp.IsEnableTransferWafer(out reason))
{
isLoad = true;
if (!lp.IsEnableTransferWafer())
continue;
destinationModules.Add(XmlRecipe.Destination[i]);
WaferInfo[] wafersInDestination = WaferManager.Instance.GetWafers(XmlRecipe.Destination[i]);
wafersInDestinationList.Add(wafersInDestination);
}
}
if (!isLoad)
{
reason = "Destination is not valid for transfer..";
return result;
}
if (wafersInSourceList.Count == 0 || wafersInDestinationList.Count == 0)
{
reason = "Recipe has no vaild transfer task.";
return result;
}
switch (XmlRecipe.PlaceModeTransfer1To1)
{
case SorterRecipePlaceModeTransfer1To1.FromBottom:
FromBottom(wafersInSourceList, wafersInDestinationList, destinationModules, ref result, out reason);
break;
case SorterRecipePlaceModeTransfer1To1.FromTop:
FromTop(wafersInSourceList, wafersInDestinationList, destinationModules, ref result, out reason);
break;
case SorterRecipePlaceModeTransfer1To1.SameSlot:
SameSlot(wafersInSourceList, wafersInDestinationList, destinationModules, ref result, out reason);
break;
default:
reason = string.Format("recipe PlaceModeTransfer1To1 {0} not valid", XmlRecipe.PlaceModeTransfer1To1);
return result;
}
//if (result.Count == 0)
// reason = "Recipe has no vaild transfer task.";
return result;
}
///
/// 从source最下面开始取wafer,顺序放在destination的最下面
///
///
///
///
bool FromBottom(List sourceList, List destinationList, List destinationModules, ref List lst, out string reason)
{
reason = string.Empty;
SCConfigItem _scLP2Pitch = SC.GetConfigItem("LoadPort.LoadPort2Pitch");
if (_scLP2Pitch == null || _scLP2Pitch.IntValue == 10)
{
int destinationIndex = -1;
for (int i = 0; i < sourceList.Count * sourceList[0].Length; i++)
{
WaferInfo[] source = sourceList[i / sourceList[0].Length];
if (source[i % sourceList[0].Length].IsEmpty)
continue;
int to = destinationIndex;
for (int j = destinationIndex + 1; j < destinationList.Count * destinationList[0].Length; j++)
{
WaferInfo[] destination = destinationList[j / destinationList[0].Length];
if (destination[j % destinationList[0].Length].IsEmpty)
{
to = j;
break;
}
}
if (to == destinationIndex)
break;
destinationIndex = to;
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 % destinationList[0].Length,
Station = destinationModules[to / destinationList[0].Length],
WaferID = source[i % sourceList[0].Length].WaferID,
});
}
}
else
{
if (sourceList.Count > 1 || destinationList.Count > 1)
{
reason = "Multiple Sources and Destinations are not supported in SameSlot mode";
return false;
}
int destinationIndex = -1;
SCConfigItem _scEnable = SC.GetConfigItem("LoadPort.EnableSlot1OnLP2");
bool isContinue = false;
for (int i = 0; i < sourceList[0].Length; i++)
{
WaferInfo[] source = sourceList[0];
if (isContinue && source[i].IsEmpty)
isContinue = false;
if (source[i].IsEmpty)
{
continue;
}
if (!_scEnable.BoolValue && i == 0)
{
isContinue = true;
continue;
}
if (isContinue)
continue;
int to = destinationIndex;
for (int j = destinationIndex + 1; j < destinationList.Count * destinationList[0].Length; j++)
{
WaferInfo[] destination = destinationList[j / destinationList[0].Length];
if (destination[j % destinationList[0].Length].IsEmpty)
{
to = j;
break;
}
}
if (to == destinationIndex)
break;
destinationIndex = to;
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 % destinationList[0].Length,
Station = destinationModules[to / destinationList[0].Length],
WaferID = source[i % sourceList[0].Length].WaferID,
});
}
}
return true;
}
///
/// 放在同一位置,如果有冲突,直接忽略
///
///
///
///
bool SameSlot(List sourceList, List destinationList, List destinationModules, ref List lst, out string reason)
{
reason = string.Empty;
if (sourceList.Count > 1 || destinationList.Count > 1)
{
reason = "Multiple Sources and Destinations are not supported in SameSlot mode";
return false;
}
WaferInfo[] source = sourceList[0];
WaferInfo[] destination = destinationList[0];
//int destinationIndex = -1;
SCConfigItem _scLP2Pitch = SC.GetConfigItem("LoadPort.LoadPort2Pitch");
if (_scLP2Pitch == null || _scLP2Pitch.IntValue == 10)
{
for (int i = 0; i < source.Length && i < destination.Length; i++)
{
if (source[i].IsEmpty || !destination[i].IsEmpty)
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 = i,
Station = destinationModules[0],
WaferID = source[i].WaferID,
});
}
}
else if (_scLP2Pitch.IntValue == 7 && XmlRecipe.Destination[0] == ModuleName.LP2)
{
SCConfigItem _scEnable = SC.GetConfigItem("LoadPort.EnableSlot1OnLP2");
for (int i = source.Length - 1; i >= 0; i--)
{
if (source[i].IsEmpty || !destination[i].IsEmpty || (!_scEnable.BoolValue && i == 0) || (i > 0 && !destination[i - 1].IsEmpty))
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 = i,
Station = destinationModules[0],
WaferID = source[i].WaferID,
});
}
}
else if ((_scLP2Pitch.IntValue == 7 && XmlRecipe.Source[0] == ModuleName.LP2))
{
SCConfigItem _scEnable = SC.GetConfigItem("LoadPort.EnableSlot1OnLP2");
bool isContinue = false;
for (int i = 0; i < source.Length && i < destination.Length; i++)
{
if (isContinue && source[i].IsEmpty)
isContinue = false;
if (source[i].IsEmpty || !destination[i].IsEmpty)
continue;
if (!_scEnable.BoolValue && i == 0 || (i > 0 && !destination[i - 1].IsEmpty))
{
isContinue = true;
continue;
}
if (isContinue)
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 = i,
Station = destinationModules[0],
WaferID = source[i].WaferID,
});
}
}
return true;
}
///
/// 从source最上面开始取wafer,顺序放在destination的最上面
///
///
///
///
bool FromTop(List sourceList, List destinationList, List destinationModules, ref List lst, out string reason)
{
reason = string.Empty;
SCConfigItem _scLP2Pitch = SC.GetConfigItem("LoadPort.LoadPort2Pitch");
if (_scLP2Pitch == null || _scLP2Pitch.IntValue == 10)
{
int destinationIndex = destinationList.Count * destinationList[0].Length;
for (int i = sourceList.Count * sourceList[0].Length - 1; i >= 0; i--)
{
WaferInfo[] source = sourceList[sourceList.Count - i / sourceList[0].Length - 1];
if (source[i % sourceList[0].Length].IsEmpty)
continue;
int to = destinationIndex;
for (int j = destinationIndex - 1; j >= 0; j--)
{
WaferInfo[] destination = destinationList[destinationList.Count - j / destinationList[0].Length - 1];
if (destination[j % destinationList[0].Length].IsEmpty)
{
to = j;
break;
}
}
if (to == destinationIndex)
break;
destinationIndex = to;
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 % destinationList[0].Length,
Station = destinationModules[destinationList.Count - to / destinationList[0].Length - 1],
WaferID = source[i % sourceList[0].Length].WaferID,
});
}
}
else
{
if (sourceList.Count > 1 || destinationList.Count > 1)
{
reason = "Multiple Sources and Destinations are not supported in SameSlot mode";
return false;
}
SCConfigItem _scEnable = SC.GetConfigItem("LoadPort.EnableSlot1OnLP2");
if (XmlRecipe.Source[0] == ModuleName.LP2) //Source为LP2
{
bool isContinue = false;
int destinationIndex = destinationList[0].Length;
for (int i = 0; i < sourceList[0].Length; i++)
{
WaferInfo[] source = sourceList[0];
if (isContinue && source[i].IsEmpty)
isContinue = false;
if (source[i].IsEmpty)
continue;
if (!_scEnable.BoolValue && i == 0)
{
isContinue = true;
continue;
}
if (isContinue)
continue;
int to = destinationIndex;
for (int j = destinationIndex - 1; j >= 0; j--)
{
WaferInfo[] destination = destinationList[0];
if (destination[j].IsEmpty)
{
to = j;
break;
}
}
if (to == destinationIndex)
break;
destinationIndex = to;
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,
Station = destinationModules[0],
WaferID = source[i].WaferID,
});
}
}
else //Station为LP2
{
int destinationIndex = destinationList[0].Length;
for (int i = sourceList[0].Length - 1; i >= 0; i--)
{
WaferInfo[] source = sourceList[0];
if (source[i].IsEmpty)
continue;
int to = destinationIndex;
for (int j = destinationIndex - 1; j >= 0; j--)
{
WaferInfo[] destination = destinationList[0];
if (j == 0)
{
if (_scEnable.BoolValue)
{
if (destination[j].IsEmpty)
{
to = j;
break;
}
}
}
else
{
if (destination[j - 1].IsEmpty && destination[j].IsEmpty)
{
to = j;
break;
}
}
}
if (to == destinationIndex)
break;
destinationIndex = to;
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,
Station = destinationModules[0],
WaferID = source[i].WaferID,
});
}
}
}
return true;
}
}
}