Sic01/SicRT/Equipments/AutoTransfer.cs

2014 lines
71 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 System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Windows.Media.Imaging;
using Aitex.Core.Common;
using Aitex.Core.RT.DataCenter;
using Aitex.Core.RT.Device;
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 Aitex.Core.Util;
using Aitex.Sorter.Common;
using MECF.Framework.Common.DataCenter;
using MECF.Framework.Common.DBCore;
using MECF.Framework.Common.Equipment;
using MECF.Framework.Common.Jobs;
using MECF.Framework.Common.Schedulers;
using MECF.Framework.Common.SubstrateTrackings;
using SicRT.Modules.Schedulers;
using SicRT.Scheduler;
namespace SicRT.Modules
{
public partial class AutoTransfer : SchedulerModuleFactory
{
/* 几个问题待解决
* 1.参数
* 2.Routine判断是否执行完了
*
*/
private bool _isPmAInstal = true;
private bool _isPmBInstal = false;
private bool _cotrolJobComplete = false;
private List<ControlJobInfo> _lstControlJobs = new List<ControlJobInfo>();
private List<ProcessJobInfo> _lstProcessJobs = new List<ProcessJobInfo>();
//private Object _locker = new Object();
private List<SchedulerPM> _lstPmsCurrentSequence = new List<SchedulerPM>();
private const string LogSource = "Scheduler";
private const string StatsNameTotalRunningWafer = "TotalRunningWafer";
private const string StatsNameTotalWaferProcessedPM1 = "PM1.WaferProcessed";
private const string StatsNameTotalWaferProcessedPM2 = "PM2.WaferProcessed";
private bool _isInited;
private bool _isCycleMode;
private int _cycleSetPoint = 0;
private int _cycledCount = 0;
private int _cycledWafer = 0;
private int _totalWaferWhenStart = 0;
private bool _AllModuleFinised = false; //所有模块工作都已经完成
private string _curRecipeName = "";
private string _curSequenceName = "";
private bool _canSetHeat = false; //需不需要PM开始停止加热(TMRobot从LoadLock开始取盘)
private bool _isModuleErrorPrevious;
private bool[] _isPMErrorPrevious = new bool[4];
private ushort _debugger2 = 0;
private ushort _debugger3 = 0;
private ushort _debugger4 = 0;
private ushort _debugger5 = 0;
private ushort _debugger6 = 0;
private ushort _debugger7 = 0;
private ushort _debugger8 = 0;
private R_TRIG _trigJobComplete = new R_TRIG();
private R_TRIG _loadLockFinishedTrig = new R_TRIG(); //LoadLock完成后充气需要发出蜂鸣
private R_TRIG _loadLockStartTrig = new R_TRIG(); //LoadLock放入Wafer后需要Purge
private R_TRIG _updateAutoJobLocation = new R_TRIG(); //需要向数据库更新Wafer位置
private string _pm1WaferStaus = "";
public AutoTransfer()
{
DATA.Subscribe("Scheduler.IsCycleMode", () => _isCycleMode);
DATA.Subscribe("Scheduler.CycledCount", () => _cycledCount);
DATA.Subscribe("Scheduler.CycleSetPoint", () => _cycleSetPoint);
DATA.Subscribe("Scheduler.RecipeName", () => _curRecipeName);
DATA.Subscribe("Scheduler.SequenceName", () => _curSequenceName);
DATA.Subscribe("LoadLock.LocalJobName", () =>
{
var jb = _lstControlJobs.Find(x => x.Module == "LoadLock");
if (jb != null)
return jb.Name;
return "";
});
DATA.Subscribe("LoadLock.LocalJobStatus", () =>
{
var jb = _lstControlJobs.Find(x => x.Module == "LoadLock");
if (jb != null)
return jb.State.ToString();
return "";
});
}
public bool HasJobRunning
{
get { return _lstControlJobs.Count > 0; }
}
public void Clear()
{
_tmRobot.ResetTask();
foreach (var pm in _lstPms)
{
pm.ResetTask();
}
foreach (var ll in _lstLls)
{
ll.ResetTask();
}
_buffer.ResetTask();
_preHeat.ResetTask();
_lstControlJobs.Clear();
_lstProcessJobs.Clear();
}
public void GetConfig()
{
_cycledCount = 0;
_isPmAInstal = SC.GetValue<bool>("System.SetUp.IsPM1Installed");
_isPmBInstal = SC.GetValue<bool>("System.SetUp.IsPM2Installed");
_isCycleMode = SC.GetValue<bool>("System.IsCycleMode");
_cycleSetPoint = _isCycleMode ? SC.GetValue<int>("System.CycleCount") : 0;
foreach (var pm in _lstPms)
{
pm.GetConfigInfo();
}
}
#region Job Management
public void CreateJob(Dictionary<string, object> param)
{
//_lstControlJobs = new List<ControlJobInfo>();
//_lstProcessJobs = new List<ProcessJobInfo>();
string[] slotSequence = (string[])param["SlotSequence"];
string jobId = (string)param["JobId"] + DateTime.Now.ToString("yyyyMMddHHmmss");
string module = (string)param["Module"];
bool autoStart = (bool)param["AutoStart"];
if (string.IsNullOrEmpty(jobId))
{
jobId = "CJ_Local_" + module;
}
Dictionary<string, bool[]> seqSlot = new Dictionary<string, bool[]>();
Dictionary<string, List<int>> seqSlotWafers = new Dictionary<string, List<int>>();
Dictionary<string, string> indexSequence = new Dictionary<string, string>();
bool enableGroupBySequence = SC.GetValue<bool>("System.Scheduler.GroupWaferBySequence");
for (int i = 0; i < 1; i++)
{
if (string.IsNullOrEmpty(slotSequence[i]) || string.IsNullOrEmpty(slotSequence[i].Trim()))
continue;
string groupName = i.ToString();
indexSequence[groupName] = slotSequence[i];
if (!seqSlot.ContainsKey(groupName))
{
seqSlot[groupName] = new bool[1];
}
if (!seqSlotWafers.ContainsKey(groupName))
{
seqSlotWafers[groupName] = new List<int>();
}
seqSlot[groupName][i] = true;
seqSlotWafers[groupName].Add(i);
}
if (seqSlotWafers.Count == 0)
{
EV.PostWarningLog(LogSource, $"Can not create job, no wafer assigned");
return;
}
List<ProcessJobInfo> pjs = new List<ProcessJobInfo>();
string[] seqs = seqSlot.Keys.ToArray();
List<string> pjIDs = new List<string>();
for (int i = 0; i < seqs.Length; i++)
{
var name = jobId + "_" + (i + 1);
if (!CreateProcessJob(name, indexSequence[seqs[i]], seqSlotWafers[seqs[i]], autoStart)) //ProcessJob创建失败直接返回不再创建ControlJob
return;
pjIDs.Add(name);
}
if (!CreateControlJob(jobId, module, pjIDs, autoStart))
{
foreach (var pjName in pjIDs)
{
var pj = _lstProcessJobs.FirstOrDefault(x => x.Name == pjName);
if (pj != null)
_lstProcessJobs.Remove(pj);
}
}
WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0);
if (wafer != null)
{
string recipeName = _curRecipeName;
if (recipeName.IndexOf(@"\") > 0)
{
recipeName = recipeName.Substring(recipeName.LastIndexOf(@"\") + 1);
}
AutoJobRecorder.Add(wafer.InnerId.ToString(), recipeName, (string)param["JobId"], ModuleName.LoadLock.ToString(), GetWaferStatue(wafer));
}
}
public bool CreateControlJob(string jobId, string module, List<string> pjIDs, bool isAutoStart)
{
if (_lstControlJobs.Exists(x => x.Name == jobId))
{
EV.PostWarningLog(LogSource, $"{jobId} is already created");
return false;
}
if (_lstProcessJobs.Count <= 0) //判断上一步ProcessJob是否创建成功
{
EV.PostWarningLog(LogSource, $"process job is not exist");
return false;
}
ControlJobInfo cj = new ControlJobInfo();
cj.Name = jobId;
cj.Module = module;
cj.SetState(EnumControlJobState.WaitingForStart);
int totalWafer = 0;
foreach (var pjName in pjIDs)
{
var pj = _lstProcessJobs.FirstOrDefault(x => x.Name == pjName);
if (pj == null)
{
LOG.Info($"not find {pjName} while create control job");
continue;
}
var slotWafers = new List<Tuple<ModuleName, int>>();
foreach (var slotWafer in pj.SlotWafers)
{
if (!WaferManager.Instance.CheckHasWafer(module, slotWafer.Item2))
{
EV.PostWarningLog(LogSource, $"job wafer: {module} slot {slotWafer.Item2 + 1} not in the carrier");
return false;
}
if (!WaferManager.Instance.CheckWafer(ModuleHelper.Converter(module), slotWafer.Item2, WaferStatus.Normal))
{
EV.PostWarningLog(LogSource, $"job wafer: {module} slot {slotWafer.Item2 + 1} status is {WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), slotWafer.Item2).Status}");
return false;
}
if (WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), slotWafer.Item2).ProcessState != EnumWaferProcessStatus.Idle)
{
EV.PostWarningLog(LogSource, $"job wafer: {module} slot {slotWafer.Item2 + 1} process status is {WaferManager.Instance.GetWafer(ModuleHelper.Converter(module), slotWafer.Item2).ProcessState}");
return false;
}
slotWafers.Add(Tuple.Create(ModuleHelper.Converter(module), slotWafer.Item2));
totalWafer++;
}
pj.ControlJobName = jobId;
cj.ProcessJobNameList.Add(pj.Name);
pj.SlotWafers = slotWafers;
foreach (var pjSlotWafer in pj.SlotWafers)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
WaferDataRecorder.SetCjInfo(wafer.InnerId.ToString(), cj.InnerId.ToString());
WaferDataRecorder.SetWaferSequence(wafer.InnerId.ToString(), pj.Sequence.Name);
WaferDataRecorder.SetWaferLotId(wafer.InnerId.ToString(), jobId);
}
}
_lstControlJobs.Add(cj);
CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
JobDataRecorder.StartCJ(cj.InnerId.ToString(), null, cj.Name, cj.Module, cj.Module, totalWafer);
return true;
}
public bool CreateProcessJob(string jobId, string sequenceName, List<int> slotNumbers/*0 based*/, bool isAutoStart)
{
var sequenceInfo = SequenceInfoHelper.GetInfo(sequenceName);
#region
if (!CheckSequenceReady(sequenceInfo, out string reason))
{
EV.PostWarningLog(LogSource, reason);
return false;
}
#endregion
var slotWafers = new List<Tuple<ModuleName, int>>();
foreach (var slot in slotNumbers)
{
slotWafers.Add(Tuple.Create(ModuleName.System, slot));
}
ProcessJobInfo pj = new ProcessJobInfo();
pj.Name = jobId;
pj.Sequence = sequenceInfo;
pj.SlotWafers = slotWafers;
pj.SetState(EnumProcessJobState.Queued);
_lstProcessJobs.Add(pj);
return true;
}
internal void StopJob(string jobName)
{
ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
if (cj == null)
{
EV.PostWarningLog(LogSource, $"stop job rejected, not found job with id {jobName}");
return;
}
foreach (var pj in _lstProcessJobs)
{
if (pj.ControlJobName == cj.Name)
{
pj.SetState(EnumProcessJobState.Stopping);
}
}
if (_cycleSetPoint > 0)
{
_cycleSetPoint = _cycledCount;
}
}
internal void AbortJob(string jobName)
{
//ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
//if (cj == null)
//{
// EV.PostWarningLog(LogSource, $"abort job rejected, not found job with id {jobName}");
// return;
//}
if (_lstControlJobs.Count == 0)
{
return;
}
ControlJobInfo cj = _lstControlJobs[_lstControlJobs.Count - 1];
int unprocessed_cj = 0;
int aborted_cj = 0;
List<ProcessJobInfo> pjAbortList = new List<ProcessJobInfo>();
foreach (var pj in _lstProcessJobs)
{
if (pj.ControlJobName == cj.Name)
{
pj.SetState(EnumProcessJobState.Aborting);
pjAbortList.Add(pj);
int unprocessed = 0;
int aborted = 0;
WaferInfo[] wafers = WaferManager.Instance.GetWaferByProcessJob(pj.Name);
foreach (var waferInfo in wafers)
{
waferInfo.ProcessJob = null;
waferInfo.NextSequenceStep = 0;
if (waferInfo.ProcessState != EnumWaferProcessStatus.Completed)
{
unprocessed++;
unprocessed_cj++;
}
}
JobDataRecorder.EndPJ(pj.InnerId.ToString(), aborted, unprocessed);
}
}
foreach (var pj in pjAbortList)
{
_lstProcessJobs.Remove(pj);
}
_lstControlJobs.Remove(cj);
JobDataRecorder.EndCJ(cj.InnerId.ToString(), aborted_cj, unprocessed_cj);
}
public void ResumeJob(string jobName)
{
ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
if (cj == null)
{
EV.PostWarningLog(LogSource, $"resume job rejected, not found job with id {jobName}");
return;
}
if (cj.State == EnumControlJobState.Paused)
{
cj.SetState(EnumControlJobState.Executing);
}
}
internal void PauseJob(string jobName)
{
ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == jobName);
if (cj == null)
{
EV.PostWarningLog(LogSource, $"pause job rejected, not found job with id {jobName}");
return;
}
if (cj.State == EnumControlJobState.Executing)
{
cj.SetState(EnumControlJobState.Paused);
}
}
internal void StartJob(string jobName)
{
GetConfig();
if (_lstControlJobs.Count < 0)
{
return;
}
foreach (ControlJobInfo cj in _lstControlJobs)
{
if (cj == null)
{
EV.PostWarningLog(LogSource, $"start job rejected, not found job with id {jobName}");
return;
}
if (cj.State == EnumControlJobState.WaitingForStart)
{
cj.SetState(EnumControlJobState.Executing);
}
_loadLockStartTrig.RST = true;
_loadLockFinishedTrig.RST = true;
}
}
#endregion
/// <summary>
/// Start Auto Transfer
/// </summary>
/// <param name="objs"></param>
/// <returns></returns>
public Result Start(params object[] objs)
{
GetConfig();
_cycledWafer = 0;
_cycledCount = 0;
_totalWaferWhenStart = StatsDataManager.Instance.GetValue(StatsNameTotalRunningWafer);
bool hasPmOnline = false;
foreach (var schedulerPm in _lstPms)
{
if (schedulerPm.IsOnline && !schedulerPm.IsError)
{
hasPmOnline = true;
break;
}
}
if (!hasPmOnline)
{
EV.PostWarningLog("Scheduler", "can not change to auto mode, at least one process chamber be online and no error");
return Result.FAIL;
}
if (!_tmRobot.IsOnline || _tmRobot.IsError)
{
EV.PostWarningLog("Scheduler", "can not change to auto mode, TM robot should be online and no error");
return Result.FAIL;
}
return Result.RUN;
}
public Result Monitor()
{
ControlJobInfo cjActive = _lstControlJobs.Find(x => x.State == EnumControlJobState.Executing);
if (cjActive != null)
{
MonitorModuleTasks();
MonitorAutoJobStatus();
MonitorPmPreTasks();
}
MonitorJobTasks();
MonitorCleanTasks();
return Result.RUN;
}
#region Job task
public Result MonitorJobTasks()
{
UpdateProcessJobStatus();
UpdateControlJobStatus();
StartNewJob();
//_trigJobComplete.CLK = CheckJobComplete();
//if (_trigJobComplete.Q)
//{
// _loadlock.SetJobStatue();
// return Result.DONE;
//}
return Result.RUN;
}
public Result MonitorCleanTasks()
{
foreach (var pm in _lstPms)
{
pm.MonitorCleanTasks();
}
return Result.RUN;
}
public Result MonitorPmPreTasks()
{
//检查
if (CheckWaferNeedProcess(_loadlock.Module, 0))
{
string pmModule = GetProcessModule(_loadlock.Module, 0);
if (pmModule != "" && WaferManager.Instance.CheckNoWafer(ModuleHelper.Converter(pmModule), 0))
{
foreach (var pm in _lstPms)
{
if (pm.Module.ToString() == pmModule && pm.CurrentWaferID == "")
{
//设置需要运行Pre和Complete Recipe的内容及相关的ProcessID
string waferID = WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0).WaferID;
bool enbalePre = false;
bool enbaleComplete = false;
string preRecipe = "";
string completeRecipe = "";
if (GetPreCompleteRecipeInfo(_loadlock.Module, 0, out enbalePre, out enbaleComplete, out preRecipe, out completeRecipe))
{
pm.SetCleanInfo(waferID, enbalePre, enbaleComplete, preRecipe, completeRecipe);
}
}
}
}
}
foreach (var pm in _lstPms)
{
pm.MonitorClean();
}
return Result.RUN;
}
protected bool CheckAllWaferReturned(ProcessJobInfo pj, bool checkAllProcessed)
{
for (int i = 0; i < pj.SlotWafers.Count; ++i)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2);
if (wafer.IsEmpty)
return false;
if (checkAllProcessed && CheckWaferNeedProcess(pj.SlotWafers[i].Item1, pj.SlotWafers[i].Item2))
return false;
if (wafer.ProcessJob == null || wafer.ProcessJob.InnerId != pj.InnerId)
{
return false;
}
}
return true;
}
protected bool CheckAllDummyWaferReturned()
{
foreach (var schedulerPm in _lstPms)
{
if (WaferManager.Instance.CheckWaferIsDummy(schedulerPm.Module, 0))
return false;
}
if (WaferManager.Instance.CheckWaferIsDummy(_tmRobot.Module, 0))
return false;
if (WaferManager.Instance.CheckWaferIsDummy(_tmRobot.Module, 1))
return false;
return true;
}
protected bool CheckAllPmCleaned(ProcessJobInfo pj)
{
foreach (var schedulerPm in _lstPms)
{
if (CheckNeedRunClean(schedulerPm.Module, out _, out _))
{
foreach (var sequenceStepInfo in pj.Sequence.Steps)
{
if (sequenceStepInfo.StepModules.Contains(schedulerPm.Module))
return false;
}
}
}
return true;
}
private void UpdateProcessJobStatus()
{
foreach (var pj in _lstProcessJobs)
{
if (pj.State == EnumProcessJobState.Processing)
{
if (CheckAllWaferReturned(pj, true) && CheckAllPmCleaned(pj) && CheckAllDummyWaferReturned() && _tmRobot.IsAvailable && _loadlock.IsAvailable)
{
if (CheckWaferSequenceStepDone(ModuleName.LoadLock, 0))
{
pj.SetState(EnumProcessJobState.ProcessingComplete);
JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0);
}
}
}
else if (pj.State == EnumProcessJobState.Stopping)
{
if (CheckAllWaferReturned(pj, false) && CheckAllPmCleaned(pj) && CheckAllDummyWaferReturned() && _tmRobot.IsAvailable && _loadlock.IsAvailable)
{
if (CheckWaferSequenceStepDone(ModuleName.LoadLock, 0))
{
pj.SetState(EnumProcessJobState.ProcessingComplete);
JobDataRecorder.EndPJ(pj.InnerId.ToString(), 0, 0);
}
}
}
}
}
private void UpdateControlJobStatus()
{
if (_lstControlJobs.Count == 0)
return;
List<ControlJobInfo> cjRemoveList = new List<ControlJobInfo>();
foreach (var cj in _lstControlJobs)
{
if (cj.State == EnumControlJobState.Completed)
{
_lstControlJobs.Remove(cj);
break;
}
else if (cj.State == EnumControlJobState.Executing)
{
bool allPjCompleted = true;
foreach (var pjName in cj.ProcessJobNameList)
{
var pj = _lstProcessJobs.Find(x => x.Name == pjName);
if (pj == null)
{
LOG.Error($"Not find pj named {pjName} in {cj.Name}");
continue;
}
if (pj.State != EnumProcessJobState.Complete && pj.State != EnumProcessJobState.ProcessingComplete)
{
allPjCompleted = false;
break;
}
}
if (allPjCompleted)
{
//Cycle模式下执行+1操作
if (_isCycleMode && _cycledCount < _cycleSetPoint)
{
_cycledCount++;
if (_cycledCount < _cycleSetPoint)
{
foreach (var pjName in cj.ProcessJobNameList)
{
var pj = _lstProcessJobs.Find(x => x.Name == pjName);
if (pj == null)
{
LOG.Error($"Not find pj named {pjName} in {cj.Name}");
continue;
}
pj.SetState(EnumProcessJobState.Queued);
pj.InnerId = Guid.NewGuid();
foreach (var pjSlotWafer in pj.SlotWafers)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
wafer.ProcessJob = null;
wafer.NextSequenceStep = 0;
wafer.ProcessState = EnumWaferProcessStatus.Idle;
}
}
}
}
else
{
cj.SetState(EnumControlJobState.Completed);
}
}
}
}
}
private void StartNewJob()
{
foreach (var cj in _lstControlJobs)
{
if (cj.State == EnumControlJobState.Executing)
{
foreach (var pjName in cj.ProcessJobNameList)
{
var pj = _lstProcessJobs.Find(x => x.Name == pjName);
if (pj == null)
{
LOG.Error($"Not find pj named {pjName} in {cj.Name}");
continue;
}
if (pj.State == EnumProcessJobState.Queued)
{
ActiveProcessJob(pj);
}
}
}
}
}
public bool CheckAllJobDone()
{
//_trigLp1JobComplete.CLK = _isUnloadFoup && CheckJobComplete(ModuleName.LP1.ToString()) && !IsRemoteConnected;
//if (_trigLp1JobComplete.Q)
//{
// CheckLp1AutoGaslinePurge(); //qiming 20210429
//}
//_trigLp2JobComplete.CLK = _isUnloadFoup && CheckJobComplete(ModuleName.LP2.ToString()) && !IsRemoteConnected;
//if (_trigLp2JobComplete.Q)
//{
// CheckLp2AutoGaslinePurge(); //qiming 20210429
//}
foreach (var cj in _lstControlJobs)
{
if (cj.State == EnumControlJobState.Executing || cj.State == EnumControlJobState.Paused)
return false;
}
if (WaferManager.Instance.CheckHasWafer(ModuleName.LoadLock, 0) && _lstControlJobs.Count == 0)
{
if (WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0).ProcessState == EnumWaferProcessStatus.Completed)
{
AutoJobRecorder.EndJob(WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0).InnerId.ToString());
_loadlock.SetJobStatue();
EV.PostWarningLog("Scheduler", "ControlJob Finished!");
return true;
}
}
return false;
}
public void MonitorAutoJobStatus()
{
_updateAutoJobLocation.CLK = _tmRobot.IsAvailable;
if (_updateAutoJobLocation.Q)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleName.PM1, 0);
if (wafer != null)
{
AutoJobRecorder.UpdatePosition(wafer.InnerId.ToString(), ModuleName.PM1.ToString(), GetWaferStatue(wafer));
}
WaferInfo wafer1 = WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0);
if (wafer1 != null)
{
AutoJobRecorder.UpdatePosition(wafer1.InnerId.ToString(), ModuleName.TM.ToString(), GetWaferStatue(wafer1));
}
WaferInfo wafer2 = WaferManager.Instance.GetWafer(ModuleName.Buffer, 0);
if (wafer2 != null)
{
AutoJobRecorder.UpdatePosition(wafer2.InnerId.ToString(), ModuleName.Buffer.ToString(), GetWaferStatue(wafer2));
}
WaferInfo wafer3 = WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0);
if (wafer3 != null)
{
AutoJobRecorder.UpdatePosition(wafer3.InnerId.ToString(), ModuleName.LoadLock.ToString(), GetWaferStatue(wafer3));
}
}
}
#region
private bool CheckSequenceReady(SequenceInfo seq, out string reason)
{
reason = "";
bool pmIsReady = false;
bool bufferIsReady = false;
for (int i = 0; i < seq.Steps.Count; i++)
{
SequenceStepInfo stepInfo = seq.Steps[i];
foreach (var module in stepInfo.StepModules)
{
if ((module == ModuleName.PM1 || module == ModuleName.PMA))
{
if (!_isPmAInstal)
{
reason = "Sequence stepinfo contains a no installed PM";
return false;
}
_curSequenceName = seq.Name;
_curRecipeName = seq.Steps[i].RecipeName; //顺便获取最新的Recipe名字
pmIsReady = true;
if (!SicPM.RecipeExecutions.RecipeParser.CheckDataAvalible(_curRecipeName, module.ToString(), out string reason1))
{
EV.PostWarningLog(LogSource, reason1);
//return false;
}
}
else if ((module == ModuleName.PM2 || module == ModuleName.PMB))
{
if (!_isPmBInstal)
{
reason = "Sequence stepinfo contains a no installed PM";
return false;
}
_curSequenceName = seq.Name;
_curRecipeName = seq.Steps[i].RecipeName; //顺便获取最新的Recipe名字
pmIsReady = true;
if (!SicPM.RecipeExecutions.RecipeParser.CheckDataAvalible(_curRecipeName, module.ToString(), out string reason1))
{
reason = "Recipe data is error!";
return false;
}
}
if (module == ModuleName.Buffer)
{
if (!pmIsReady)
{
reason = "Sequence stepinfo error,The buffer step must after the PM step";
return false;
}
bufferIsReady = true;
}
}
}
if (!pmIsReady)
{
reason = "Sequence stepinfo must contain a PM step";
return false;
}
if (!bufferIsReady)
{
reason = "Sequence stepinfo must contain a Buffer step";
return false;
}
return true;
}
#endregion
private bool ActiveProcessJob(ProcessJobInfo pj)
{
_lstPmsCurrentSequence.Clear();
for (int i = 0; i < pj.Sequence.Steps.Count; i++)
{
SequenceStepInfo stepInfo = pj.Sequence.Steps[i];
foreach (var module in stepInfo.StepModules)
{
if (ModuleHelper.IsPm(module) && _lstPms.Exists(x => x.Module == module))
{
_lstPmsCurrentSequence.Add(_lstPms.Find(x => x.Module == module));
}
}
}
foreach (var pjSlotWafer in pj.SlotWafers)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(pjSlotWafer.Item1, pjSlotWafer.Item2);
wafer.ProcessJob = pj;
wafer.NextSequenceStep = 0;
WaferDataRecorder.SetPjInfo(wafer.InnerId.ToString(), pj.InnerId.ToString());
}
ControlJobInfo cj = _lstControlJobs.Find(x => x.Name == pj.ControlJobName);
CarrierInfo carrier = CarrierManager.Instance.GetCarrier(cj.Module);
JobDataRecorder.StartPJ(pj.InnerId.ToString(), null, cj.InnerId.ToString(), pj.Name, cj.Module, cj.Module, pj.SlotWafers.Count);
pj.SetState(EnumProcessJobState.Processing);
return true;
}
private bool CheckJobComplete(string lp = null)
{
if (_lstProcessJobs.Count == 0)
return false;
if (_lstControlJobs.Count == 0)
return false;
if (_isCycleMode && _cycledCount < _cycleSetPoint)
return false;
if (lp != null)
{
var cj = _lstControlJobs.Find(x => x.Module == lp);
if (cj == null)
return false;
}
foreach (var pj in _lstProcessJobs)
{
if (lp == null)
{
if (pj.State != EnumProcessJobState.ProcessingComplete)
{
return false;
}
}
}
foreach (var cj in _lstControlJobs)
{
if (lp == null)
{
if (cj.State != EnumControlJobState.Completed)
{
return false;
}
}
else
{
if (cj.Module == lp && cj.State != EnumControlJobState.Completed)
{
return false;
}
}
}
return true;
}
#endregion
#region Module task
public Result MonitorModuleTasks()
{
MonitorPMTask();
MonitorTmRobotTask();
MonitorLoadLockTask();
MonitorBufferTask();
return Result.RUN;
}
private void MonitorBufferTask()
{
if (WaferManager.Instance.CheckHasWafer(_buffer.Module, 0) && CheckWaferNextStepIsBuffer(_buffer.Module, 0) && _tmRobot.IsAvailable && _buffer.IsAvailable)
{
//判断冷却方式是温度还是时间
bool coolingTypeIsTime = CheckCoolingTypeIsTime(_buffer.Module, 0);
int coolingValue = GetWaferSequenceBufferCoolingValue(_buffer.Module, 0);
_buffer.Cooling(coolingTypeIsTime, coolingValue);
WaferManager.Instance.GetWafer(_buffer.Module, 0).NextSequenceStep++;
}
}
private bool _loadLockFinishedPurgeOver = false;
private bool _loadLockFinishedVent = false;
private void MonitorLoadLockTask()
{
if (!_tmRobot.IsAvailable || !_loadlock.IsAvailable)
{
return;
}
if (CheckWaferSequenceStepDone(ModuleName.LoadLock, 0) && WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0).ProcessState == EnumWaferProcessStatus.Completed)
{
if (!_loadlock.CheckAtAtm())
{
if (_isCycleMode && _cycledCount < _cycleSetPoint)
{
return;
}
else
{
if (!_loadLockFinishedPurgeOver)
{
_loadlock.Purge();
_loadLockFinishedPurgeOver = true;
return;
}
}
}
if (_loadLockFinishedPurgeOver)
{
if (!_loadLockFinishedVent)
{
_loadlock.Vent();
_loadLockFinishedVent = true;
return;
}
_trigJobComplete.CLK = _loadLockFinishedVent;
if (_trigJobComplete.Q)
{
AutoJobRecorder.EndJob(WaferManager.Instance.GetWafer(ModuleName.LoadLock, 0).InnerId.ToString());
_loadlock.SetJobStatue();
}
}
}
else
{
if (WaferManager.Instance.CheckHasWafer(_loadlock.Module, 0))
{
//第一次Start,LoadLock需要执行Purge
_loadLockStartTrig.CLK = true;
if (_loadLockStartTrig.Q)
{
//_loadLockFinishedPurgeOver = false;
_loadlock.Purge();
return;
}
if (!_loadlock.IsReadyForPick(ModuleName.TMRobot, 0))
{
_loadlock.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, 0);
}
}
else
{
if (!_loadlock.IsReadyForPlace(ModuleName.TMRobot, 0))
{
_loadlock.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
}
}
}
}
private void MonitorPMTask()
{
foreach (var pm in _lstPms)
{
WaferInfo wafer1 = WaferManager.Instance.GetWafer(pm.Module, 0);
if (wafer1 == null)
{
_pm1WaferStaus = "";
}
else if (wafer1.ProcessState.ToString() != _pm1WaferStaus)
{
_pm1WaferStaus = wafer1.ProcessState.ToString();
AutoJobRecorder.UpdatePosition(wafer1.InnerId.ToString(), ModuleName.PM1.ToString(), GetWaferStatue(wafer1));
}
if (!pm.IsAvailable)
continue;
if (WaferManager.Instance.CheckHasWafer(pm.Module, 0))
{
if (CheckNeedRunClean(pm.Module, out bool withWafer, out string recipe) && withWafer
&& WaferManager.Instance.GetWafer(pm.Module, 0).Status == WaferStatus.Dummy
&& WaferManager.Instance.GetWafer(pm.Module, 0).ProcessState == EnumWaferProcessStatus.Wait)
{
pm.Process(recipe, true, withWafer);
continue;
}
if (CheckWaferNeedProcess(pm.Module, 0, pm.Module))
{
WaferInfo wafer = WaferManager.Instance.GetWafer(pm.Module, 0);
if (pm.Process(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].RecipeName, false, true))
{
pm.SetCurrentRunCount();
WaferManager.Instance.GetWafer(pm.Module, 0).NextSequenceStep++;
continue;
}
}
else
{
if (!pm.IsReadyForPick(ModuleName.TMRobot, 0))
{
pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Pick, 0);
}
}
}
else
{
if (CheckNeedRunClean(pm.Module, out bool withWafer, out string recipe) && !withWafer)
{
pm.Process(recipe, true, withWafer);
continue;
}
if (!pm.IsReadyForPlace(ModuleName.TMRobot, 0))
{
pm.PrepareTransfer(ModuleName.TMRobot, EnumTransferType.Place, 0);
return;
}
//if (!pm.CheckHeatIsDisbale() && _canSetHeat)
//{
// pm.SetHeatDisable();
// _canSetHeat = false;
//}
}
}
}
private void MonitorTmRobotTask()
{
if (!_tmRobot.IsAvailable)
return;
//TM robot is idle, release all the target
foreach (var ll in _lstLls)
{
if (ll.IsWaitTransfer(ModuleName.TMRobot))
ll.StopWaitTransfer(ModuleName.TMRobot);
}
foreach (var pm in _lstPms)
{
if (pm.IsWaitTransfer(ModuleName.TMRobot))
pm.StopWaitTransfer(ModuleName.TMRobot);
}
if (_buffer.IsWaitTransfer(ModuleName.TMRobot))
_buffer.StopWaitTransfer(ModuleName.TMRobot);
MonitorTmRobotLoadLockTask();
MonitorTmRobotBufferTask();
MonitorTmRobotPMTask();
//MonitorTmRobotPreHeatTask();
}
private void MonitorTmRobotLoadLockTask()
{
if (!_tmRobot.IsAvailable)
return;
//place to ll
bool blade0HasWaferAndProcessed = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) &&
!CheckWaferNeedProcess(ModuleName.TMRobot, 0) &&
!(WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).Status == WaferStatus.Dummy)
&& CheckWaferSequenceStepDone(ModuleName.TMRobot, 0);
if (blade0HasWaferAndProcessed && WaferManager.Instance.CheckNoWafer(_loadlock.Module, 0))
{
Hand placeBlade = Hand.Blade1;
SchedulerLoadLock placeLL = null;
int placeSlot = Int32.MinValue;
if (_loadlock.IsAvailable && _loadlock.IsReadyForPlace(ModuleName.TMRobot, 0))
{
int slot = WaferManager.Instance.GetWafer(_loadlock.Module, 0).OriginSlot;
if (slot > placeSlot)
{
placeLL = _loadlock;
placeSlot = slot;
}
}
if (placeLL != null)
{
if (placeLL.IsReadyForPlace(ModuleName.TMRobot, 0))
{
if (_tmRobot.Place(placeLL.Module, 0, placeBlade))
{
_loadLockFinishedPurgeOver = false;
_loadLockFinishedVent = false;
placeLL.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
if (!_tmRobot.IsAvailable)
return;
//pick from ll
if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0))
{
Hand pickBlade = Hand.Blade1;
SchedulerLoadLock pickLL = null;
int pickSlot = Int32.MaxValue;
if (!_loadlock.IsAvailable
|| !_loadlock.IsReadyForPick(ModuleName.TM, 0)
|| !WaferManager.Instance.CheckHasWafer(_loadlock.Module, 0)
|| !CheckWaferNeedProcess(_loadlock.Module, 0)
|| !CheckWaferProcessModuleIsAvailable(_loadlock.Module, 0))
return;
bool findChamberToProcess = false;
foreach (var pm in _lstPms)
{
if (!pm.IsAvailable || WaferManager.Instance.CheckHasWafer(pm.Module, 0) || CheckNeedRunClean(pm.Module, out _, out _))
continue;
bool llWaferProcessIn = CheckWaferNextProcessIn(_loadlock.Module, 0, pm.Module);
bool robotWaferProcessIn = CheckWaferNextProcessIn(ModuleName.TMRobot, (int)pickBlade, pm.Module);
if (!llWaferProcessIn)
continue;
if (robotWaferProcessIn)
continue;
findChamberToProcess = true;
}
string chamberToProcess = GetProcessModule(_loadlock.Module, 0);
foreach (var pm in _lstPms)
{
if (pm.Module.ToString() == chamberToProcess)
{
if (pm.CurrentWaferID != "" && pm.CurrentWaferID != WaferManager.Instance.GetWafer(_loadlock.Module, 0).WaferID)
{
//return;
}
}
}
if (!findChamberToProcess)
return;
int slot = WaferManager.Instance.GetWafer(_loadlock.Module, 0).OriginSlot;
if (slot < pickSlot)
{
pickLL = _loadlock;
pickSlot = slot;
}
if (pickLL != null)
{
if (pickLL.IsReadyForPick(ModuleName.TMRobot, 0))
{
if (_tmRobot.Pick(pickLL.Module, 0, pickBlade))
{
pickLL.WaitTransfer(ModuleName.TMRobot);
_canSetHeat = true;
return;
}
}
}
}
}
private void MonitorTmRobotBufferTask()
{
if (!_tmRobot.IsAvailable || !_buffer.IsAvailable)
return;
//place to Buffer (工艺做完Sequence下一步是Buffer)
bool blade0HasWaferAndProcessed = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) &&
!CheckWaferNeedProcess(ModuleName.TMRobot, 0, _pm1.Module) &&
(CheckWaferNextStepIsBuffer(ModuleName.TMRobot, 0) || (!CheckWaferNextStepIsBuffer(ModuleName.Buffer, 0) && !CheckWaferNextStepIsBuffer(ModuleName.LoadLock, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.LoadLock, 0)));
//place to buffer
if (blade0HasWaferAndProcessed && WaferManager.Instance.CheckNoWafer(ModuleName.Buffer, 0))
{
Hand placeBlade = Hand.Blade1;
if (_buffer.IsReadyForPlace(ModuleName.TMRobot, 0))
{
if (_tmRobot.Place(_buffer.Module, 0, placeBlade))
{
_buffer.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
//pick from buffer
if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0) && WaferManager.Instance.CheckNoWafer(ModuleName.LoadLock, 0) && WaferManager.Instance.CheckHasWafer(ModuleName.Buffer, 0))
{
if (_loadlock.HasWafer(0))
{
return;
}
Hand pickBlade = Hand.Blade1;
if (!_buffer.CheckTaskDone() || !CheckWaferSequenceStepDone(_buffer.Module, 0))
{
return;
}
bool waferHasJob = CheckBufferWaferHasJob();
if (!waferHasJob && !_buffer.IsReadyForPick(ModuleName.TMRobot, 0))
{
return;
}
else
{
if (_tmRobot.Pick(_buffer.Module, 0, pickBlade))
{
_buffer.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
private void MonitorTmRobotPMTask()
{
if (!_tmRobot.IsAvailable)
return;
//place to pm
bool blade0HasWaferAndNeedProcess = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) &&
CheckWaferNeedProcess(ModuleName.TMRobot, 0);
if (blade0HasWaferAndNeedProcess)
{
_debugger2++;
foreach (var pm in _lstPms)
{
if (!pm.IsAvailable
|| !WaferManager.Instance.CheckNoWafer(pm.Module, 0)
|| !pm.IsReadyForPlace(ModuleName.TMRobot, 0))
//|| !pm.CheckTempBelow900())
continue;
bool cleanRequired = CheckNeedRunClean(pm.Module, out bool withWafer, out _);
if (cleanRequired)
{
if (!withWafer)
continue;
bool blade0DummyPlace = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) &&
CheckWaferNeedProcess(ModuleName.TMRobot, 0, pm.Module) && WaferManager.Instance.CheckWaferIsDummy(ModuleName.TMRobot, 0);
bool blade1DummyPlace = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 1) &&
CheckWaferNeedProcess(ModuleName.TMRobot, 1, pm.Module) && WaferManager.Instance.CheckWaferIsDummy(ModuleName.TMRobot, 1);
if (blade0DummyPlace || blade1DummyPlace)
{
Hand placeBlade = blade0DummyPlace ? Hand.Blade1 : Hand.Blade2;
if (blade0DummyPlace && blade1DummyPlace)
{
if (WaferManager.Instance.GetWafer(ModuleName.TMRobot, 1).OriginSlot <
WaferManager.Instance.GetWafer(ModuleName.TMRobot, 0).OriginSlot)
{
placeBlade = Hand.Blade2;
}
}
if (_tmRobot.Place(pm.Module, 0, placeBlade))
{
pm.WaitTransfer(ModuleName.TMRobot);
return;
}
}
continue;
}
bool blade0Place = WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, 0) &&
CheckWaferNeedProcess(ModuleName.TMRobot, 0, pm.Module);
if (blade0Place)
{
Hand placeBlade = Hand.Blade1;
if (_tmRobot.Place(pm.Module, 0, placeBlade))
{
pm.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
if (!_tmRobot.IsAvailable)
return;
//pick from pm
if (WaferManager.Instance.CheckNoWafer(ModuleName.TMRobot, 0))
{
_debugger3++;
Hand pickBlade = Hand.Blade1;
ModuleName pickPm = ModuleName.System;
int waferOriginSlot = int.MaxValue;
foreach (var schedulerPm in _lstPms)
{
//增加温度低于900才能Pick的限制
if (!schedulerPm.IsAvailable
|| WaferManager.Instance.CheckNoWafer(schedulerPm.Module, 0)
|| CheckWaferNeedProcess(schedulerPm.Module, 0, schedulerPm.Module)
|| WaferManager.Instance.CheckHasWafer(ModuleName.TMRobot, (int)pickBlade))
//|| !schedulerPm.CheckTempBelow900())
continue;
_debugger4++;
WaferInfo wafer = WaferManager.Instance.GetWafer(schedulerPm.Module, 0);
bool pickAllowed = CheckVacuumWaferHasAvailableTarget(schedulerPm.Module, 0, schedulerPm.Module);
if (pickAllowed)
{
_debugger5++;
int slot = wafer.OriginSlot;
if (slot < waferOriginSlot)
{
waferOriginSlot = slot;
pickPm = schedulerPm.Module;
}
}
}
if (pickPm != ModuleName.System)
{
_debugger6++;
SchedulerModule pm = GetModule(pickPm.ToString());
if (pm.IsReadyForPick(ModuleName.TMRobot, 0))
{
_debugger7++;
bool hasWaferNeedRun = CheckWaferNeedProcess(ModuleName.LoadLock, 0) || CheckWaferNeedProcess(ModuleName.TMRobot, 0) || CheckWaferNeedProcess(ModuleName.Buffer, 0);
if (_tmRobot.Pick(pm.Module, 0, pickBlade))
{
_debugger8++;
pm.WaitTransfer(ModuleName.TMRobot);
return;
}
}
}
}
}
#endregion
#region Logic Check
private bool CheckNeedRunClean(ModuleName module, out bool withWafer, out string recipeName)
{
recipeName = string.Empty;
withWafer = false;
return false;
}
private bool CheckVacuumWaferHasAvailableTarget(ModuleName waferModule, int waferSlot, ModuleName chamberSwappable)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
if (CheckWaferNeedProcess(waferModule, waferSlot))
{
// Check for an empty PM
foreach (var pm in _lstPms)
{
if (WaferManager.Instance.CheckNoWafer(pm.Module, 0) || pm.Module == chamberSwappable)
{
if (pm.IsAvailable == false)
continue;
if (!CheckWaferNextProcessIn(waferModule, waferSlot, pm.Module))
continue;
return true;
}
}
}
else
{
if (WaferManager.Instance.CheckNoWafer(_buffer.Module, 0) && _buffer.IsAvailable)
{
return true;
}
}
return false;
}
private bool CheckWaferNextProcessIn(ModuleName waferModule, int waferSlot, ModuleName chamber)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
if (wafer.ProcessJob == null ||
wafer.ProcessJob.Sequence == null ||
wafer.ProcessJob.Sequence.Steps == null ||
wafer.ProcessJob.Sequence.Steps.Count <= wafer.NextSequenceStep ||
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep] == null ||
wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules == null)
{
return false;
}
//return wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(chamber);
for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
{
if (wafer.ProcessJob.Sequence.Steps[i].StepModules.Contains(chamber))
{
return true;
}
}
return false;
}
private SequenceInfo GetCurrentSequenceInfo()
{
foreach (var pj in _lstProcessJobs)
{
if (pj.State == EnumProcessJobState.Processing)
{
return pj.Sequence;
}
}
return null;
}
/// <summary>
/// 判断Buffer的冷却方式是时间还是温度
/// </summary>
/// <param name="module"></param>
/// <param name="slot"></param>
/// <returns></returns>
private bool CheckCoolingTypeIsTime(ModuleName module, int slot)
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(module))
return false;
if (wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["CoolingType"].ToString().ToLower() == "time")
{
return true;
}
return false;
}
private int GetWaferSequenceBufferCoolingValue(ModuleName module, int slot)
{
int coolingValue = 0;
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return coolingValue;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return coolingValue;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return coolingValue;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(module))
return coolingValue;
int.TryParse(wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepParameter["CoolingValue"].ToString(),
out coolingValue);
return coolingValue;
}
private bool CheckWaferNextStepIsBuffer(ModuleName module, int slot)
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.Buffer))
return false;
return true;
}
private bool CheckWaferNextStepIsLoadLock(ModuleName module, int slot)
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Any(m => ModuleHelper.IsLoadLock(m)))
return false;
return true;
}
private bool CheckWaferNextStepIsTMRobot(ModuleName module, int slot)
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Contains(ModuleName.TMRobot))
return false;
return true;
}
private bool CheckWaferNextStepIsPM(ModuleName module, int slot)
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
if (!wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules.Any(m => ModuleHelper.IsPm(m)))
return false;
return true;
}
/// <summary>
/// 获取前处理和后处理的Recipe信息
/// </summary>
/// <param name="module"></param>
/// <param name="slot"></param>
/// <returns></returns>
private bool GetPreCompleteRecipeInfo(ModuleName module, int slot, out bool enablePre, out bool enableComplete, out string preRecipe, out string completeRecipe)
{
enablePre = false;
enableComplete = false;
preRecipe = "";
completeRecipe = "";
try
{
if (!WaferManager.Instance.CheckHasWafer(module, slot))
return false;
WaferInfo wafer = WaferManager.Instance.GetWafer(module, slot);
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
for (int i = 0; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
{
if (wafer.ProcessJob.Sequence.Steps[i].StepModules.Any(m => ModuleHelper.IsPm(m)))
{
if (wafer.ProcessJob.Sequence.Steps[i].StepParameter["EnablePre"].ToString().Trim() != "")
{
enablePre = true;
}
if (wafer.ProcessJob.Sequence.Steps[i].StepParameter["EnableComplete"].ToString().Trim() != "")
{
enableComplete = true;
}
preRecipe = wafer.ProcessJob.Sequence.Steps[i].StepParameter["PretreatmentRecipe"].ToString();
completeRecipe = wafer.ProcessJob.Sequence.Steps[i].StepParameter["CompleteRecipe"].ToString();
}
}
return true;
}
catch (Exception ex)
{
enablePre = false;
enableComplete = false;
preRecipe = "";
completeRecipe = "";
return true;
}
}
public bool CheckWaferNeedProcess(ModuleName waferModule, int waferSlot, ModuleName processIn = ModuleName.System)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
if (wafer.IsEmpty)
return false;
if (wafer.Status == WaferStatus.Dummy && wafer.ProcessState == EnumWaferProcessStatus.Wait)
{
if (ModuleHelper.IsPm(processIn))
{
return (CheckNeedRunClean(processIn, out bool withWafer, out _) && withWafer);
}
return true;
}
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
if (processIn != ModuleName.System && !wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules
.Contains(processIn))
return false;
bool hasPm = false;
for (int i = wafer.NextSequenceStep; i < wafer.ProcessJob.Sequence.Steps.Count; i++)
{
foreach (var stepModule in wafer.ProcessJob.Sequence.Steps[i].StepModules)
{
if (ModuleHelper.IsPm(stepModule))
{
hasPm = true;
break;
}
}
if (hasPm)
break;
}
if (processIn == ModuleName.System && !hasPm)
return false;
return true;
}
public bool CheckWaferSequenceStepDone(ModuleName waferModule, int waferSlot)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
if (wafer.IsEmpty)
{
return false;
}
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
{
return true;
}
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count && wafer.ProcessJob.Sequence.Steps.Count > 0)
{
return true;
}
return false;
}
public bool CheckBufferWaferHasJob()
{
WaferInfo wafer = WaferManager.Instance.GetWafer(ModuleName.Buffer, 0);
if (wafer.IsEmpty)
{
return false;
}
if (wafer.ProcessJob == null)
{
return false;
}
ProcessJobInfo pj = _lstProcessJobs.Find(x => x.InnerId == wafer.ProcessJob.InnerId);
if (pj == null)
{
return false;
}
return true;
}
public bool CheckWaferProcessModuleIsAvailable(ModuleName waferModule, int waferSlot)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
if (wafer.IsEmpty)
return false;
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return false;
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return false;
//foreach (var module in wafer.ProcessJob.Sequence.Steps[wafer.NextSequenceStep].StepModules)
//{
// if (WaferManager.Instance.CheckNoWafer(module, 0)
// && _lstPms.Find(x => x.Module == module).IsAvailable
// && !CheckNeedRunClean(module, out bool _, out string _))
// return true;
//}
foreach (var step in wafer.ProcessJob.Sequence.Steps)
{
foreach (var module in step.StepModules)
{
if (module.ToString().StartsWith("PM")
&& WaferManager.Instance.CheckNoWafer(module, 0)
&& _lstPms.Find(x => x.Module == module).IsAvailable
&& !CheckNeedRunClean(module, out bool _, out string _))
return true;
}
}
return false;
}
//获取
public string GetProcessModule(ModuleName waferModule, int waferSlot)
{
WaferInfo wafer = WaferManager.Instance.GetWafer(waferModule, waferSlot);
if (wafer.IsEmpty)
return "";
if (wafer.ProcessJob == null || wafer.ProcessJob.Sequence == null)
return "";
if (wafer.NextSequenceStep >= wafer.ProcessJob.Sequence.Steps.Count)
return "";
foreach (var step in wafer.ProcessJob.Sequence.Steps)
{
foreach (var module in step.StepModules)
{
if (module.ToString().StartsWith("PM")
&& WaferManager.Instance.CheckNoWafer(module, 0)
&& _lstPms.Find(x => x.Module == module).IsAvailable
&& !CheckNeedRunClean(module, out bool _, out string _))
return module.ToString();
}
}
return "";
}
#endregion
#region Module error
public Result MonitorModuleError()
{
bool isModuleError = false;
bool[] isPMError = new bool[4];
for (int i = 0; i < isPMError.Length; i++)
{
isPMError[i] = false;
}
if (_tmRobot.IsError)
isModuleError = true;
for (int i = 0; i < _lstPms.Count; i++) // PM出错不影响其他腔体的传片
{
if (_lstPms[i].IsError)
isPMError[i] = true;
}
foreach (var ll in _lstLls)
{
if (ll.IsError)
isModuleError = true;
}
if (isModuleError && !_isModuleErrorPrevious)
{
//var jb1 = _lstControlJobs.Find(x => x.Module == "LP1");
//if (jb1 != null)
// PauseJob(jb1.Name);
//var jb2 = _lstControlJobs.Find(x => x.Module == "LP2");
//if (jb2 != null)
// PauseJob(jb2.Name);
}
else if (!isModuleError && _isModuleErrorPrevious)
{
Reset();
//CloseDoor();
}
for (int i = 0; i < _lstPms.Count; i++)
{
if (!isPMError[i] && _isPMErrorPrevious[i])
{
_lstPms[i].ResetTask();
}
_isPMErrorPrevious[i] = isPMError[i];
}
_isModuleErrorPrevious = isModuleError;
return Result.RUN;
}
private string GetWaferStatue(WaferInfo wafer)
{
if (wafer.ProcessState == EnumWaferProcessStatus.InProcess)
{
return "InProcess";
}
else if (wafer.ProcessState == EnumWaferProcessStatus.Completed)
{
return "Completed";
}
else
{
return "Idle";
}
}
#endregion
}
}