962 lines
33 KiB
C#
962 lines
33 KiB
C#
using System;
|
||
using Aitex.Core.RT.DataCenter;
|
||
using Aitex.Core.RT.Device;
|
||
using Aitex.Core.RT.Device.Devices;
|
||
using Aitex.Core.RT.Event;
|
||
using Aitex.Core.RT.OperationCenter;
|
||
using Aitex.Core.RT.Routine;
|
||
using Aitex.Core.RT.SCCore;
|
||
using MECF.Framework.Common.Equipment;
|
||
using MECF.Framework.Common.SubstrateTrackings;
|
||
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadLocks;
|
||
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.TMs;
|
||
using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.UnLoad;
|
||
using SicModules.LLs;
|
||
using SicModules.LLs.Routines;
|
||
using SicModules.TMs.Routines.Base;
|
||
using SicModules.UnLoads;
|
||
using SicModules.UnLoads.Routines;
|
||
|
||
namespace SicModules.TMs.Routines
|
||
{
|
||
public class TMSlitValveRoutine : TMBaseRoutine
|
||
{
|
||
enum RoutineStep
|
||
{
|
||
ChamberBalance,
|
||
OpenTMToLLVent,
|
||
OpenTMToPMV70,
|
||
CheckPressureCondition,
|
||
|
||
SetSlitValve,
|
||
|
||
SetSlowVentValve,
|
||
SetM40,
|
||
|
||
LLRoutine,
|
||
|
||
Delay,
|
||
Delay1, Delay2, Delay3, Delay4,
|
||
CloseTMToLLVent,
|
||
CloseTMToPMV70,
|
||
PumpDownToBase,
|
||
CheckConfinementIsDown,
|
||
|
||
SetConfinementRingUp,
|
||
SetConfinementRingDown,
|
||
SetPostTransfer,
|
||
SetPmPreTrasfer,
|
||
WaitSicServoHome,
|
||
SetV77,
|
||
SetV77Close,
|
||
SetTmMfc,
|
||
|
||
WaitTempBelow900,
|
||
WaitPVTempBelowSet,
|
||
WaitPMIdle
|
||
}
|
||
|
||
|
||
private int _timeout;
|
||
|
||
private SicTM _tm;
|
||
private LoadLock _ll;
|
||
private UnLoad _unLoad;
|
||
private IoValve PMToTm_V70;
|
||
private IoPressure _pmPT1;
|
||
private IoConfinementRing _confinementRing;
|
||
|
||
private IoInterLock _pmIoInterLock;
|
||
private IoTC _tc1;
|
||
|
||
private string _paramTarget;
|
||
|
||
/// <summary>
|
||
/// 次参数表示闸板阀开或者关,由上层调用者在初始化这个类时决定
|
||
/// </summary>
|
||
private bool _paramIsOpen;
|
||
private bool _confinementIsDown = false;
|
||
|
||
|
||
//private TMPumpWithTurboRoutine _pumpDownRoutine;
|
||
|
||
private TMPressureBalanceRoutine _balanceRoutine;
|
||
private LoadLockServoToRoutine _llVentTo;
|
||
private UnLoadServoToRoutine _unLoadVentTo;
|
||
private IoMFC _m40;
|
||
|
||
private bool _needPressureBalance;
|
||
|
||
private int _rotationStopTimeout = 120;
|
||
|
||
private double _maxPressureDiffOpenSlitValve;
|
||
private bool _isAtmMode;
|
||
private bool _isLockLock;
|
||
private bool _isUnLoad;
|
||
private bool _isPM;
|
||
private bool _isBuffer;
|
||
private int _tmV77DelayTime = 5;
|
||
private double _tmMfcFlow = 10;
|
||
|
||
|
||
|
||
private bool _pmPostTrasferNeedEnableHeat = true;
|
||
private bool _preTransferPSUEnable = false;
|
||
private bool _preTransferSCREnable = false;
|
||
public IoPSU PSU1 = null;
|
||
public IoPSU PSU2 = null;
|
||
public IoPSU PSU3 = null;
|
||
public IoSCR SCR1 = null;
|
||
public IoSCR SCR2 = null;
|
||
public IoSCR SCR3 = null;
|
||
|
||
private double _pmPVTempLimit = 0;
|
||
|
||
public TMSlitValveRoutine()
|
||
{
|
||
Module = ModuleName.TM.ToString();
|
||
Name = "Slit Valve";
|
||
_tm = DEVICE.GetDevice<SicTM>($"{ ModuleName.System.ToString()}.{ ModuleName.TM.ToString()}");
|
||
_ll = DEVICE.GetDevice<SicLoadLock>($"{ModuleName.LoadLock}.{ModuleName.LoadLock}");
|
||
_unLoad= DEVICE.GetDevice<SicUnLoad>($"{ModuleName.UnLoad}.{ModuleName.UnLoad}");
|
||
}
|
||
|
||
public void Init(string module, bool isOpen, bool needEnableHeat)
|
||
{
|
||
_pmPostTrasferNeedEnableHeat = needEnableHeat;
|
||
Init(module, isOpen);
|
||
}
|
||
|
||
public void Init(string module, bool isOpen)
|
||
{
|
||
_paramTarget = module;
|
||
_paramIsOpen = isOpen;
|
||
Name = isOpen ? "Open Slit Valve" : "Close Slit Valve";
|
||
|
||
_balanceRoutine = new TMPressureBalanceRoutine();
|
||
|
||
_llVentTo = new LoadLockServoToRoutine(ModuleName.LoadLock);
|
||
_unLoadVentTo = new UnLoadServoToRoutine(ModuleName.UnLoad);
|
||
_balanceRoutine.Init(ModuleHelper.Converter(module));
|
||
|
||
_needPressureBalance = SC.GetValue<bool>("TM.NeedPressureBalance");
|
||
}
|
||
|
||
public override Result Start(params object[] objs)
|
||
{
|
||
Reset();
|
||
|
||
_isLockLock = ModuleHelper.IsLoadLock(_paramTarget);
|
||
_isUnLoad = _paramTarget == ModuleName.UnLoad.ToString();
|
||
_isPM = ModuleHelper.IsPm(_paramTarget);
|
||
_isBuffer = _paramTarget == ModuleName.Buffer.ToString();
|
||
|
||
if (_isPM)
|
||
{
|
||
PMToTm_V70 = DEVICE.GetDevice<IoValve>($"{_paramTarget}.V70");
|
||
_confinementRing = DEVICE.GetDevice<IoConfinementRing>($"{_paramTarget}.ConfinementRing");
|
||
_sicServo = DEVICE.GetDevice<SicMultipleServo>($"{_paramTarget}.PMServo");
|
||
_pmIoInterLock = DEVICE.GetDevice<IoInterLock>($"{_paramTarget}.PMInterLock");
|
||
_tc1 = DEVICE.GetDevice<IoTC>($"{_paramTarget}.TC1");
|
||
}
|
||
|
||
if (TMDevice.GetSlitValve(ModuleHelper.Converter(_paramTarget)) == null)
|
||
{
|
||
EV.PostWarningLog(Module, $"do not find slit valve info");
|
||
return Result.FAIL;
|
||
}
|
||
|
||
if ((_paramIsOpen && TMDevice.CheckSlitValveOpen(ModuleHelper.Converter(_paramTarget)))
|
||
|| (!_paramIsOpen && TMDevice.CheckSlitValveClose(ModuleHelper.Converter(_paramTarget))))
|
||
{
|
||
string message = _paramIsOpen ? "open" : "close";
|
||
return Result.DONE;
|
||
}
|
||
|
||
_tm.CloseAllVentPumpValue();
|
||
|
||
if (_paramIsOpen)
|
||
{
|
||
bool isAtmMode = SC.GetValue<bool>("System.IsATMMode");
|
||
if (ModuleHelper.IsLoadLock(_paramTarget))
|
||
{
|
||
LoadLock ll = DEVICE.GetDevice<LoadLock>($"{_paramTarget}.{_paramTarget}");
|
||
|
||
if (isAtmMode)
|
||
{
|
||
if (!ll.CheckAtm())
|
||
{
|
||
EV.PostWarningLog(Module, $"can not open slit valve, running in ATM mode, but {_paramTarget} not in ATM");
|
||
return Result.FAIL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (!ll.CheckVacuum())
|
||
{
|
||
EV.PostWarningLog(Module, $"can not open slit valve, {_paramTarget} not in vacuum");
|
||
return Result.FAIL;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ModuleHelper.IsPm(_paramTarget))
|
||
{
|
||
_pmPT1 = DEVICE.GetDevice<IoPressure>($"{_paramTarget}.PT1");
|
||
double atmBase = SC.GetValue<double>($"PM.AtmPressureBase");
|
||
double vacBase = SC.GetValue<double>($"PM.VacuumPressureBase");
|
||
|
||
PSU1 = DEVICE.GetDevice<IoPSU>($"{_paramTarget}.PSU1");
|
||
PSU2 = DEVICE.GetDevice<IoPSU>($"{_paramTarget}.PSU2");
|
||
PSU3 = DEVICE.GetDevice<IoPSU>($"{_paramTarget}.PSU3");
|
||
SCR1 = DEVICE.GetDevice<IoSCR>($"{_paramTarget}.SCR1");
|
||
SCR2 = DEVICE.GetDevice<IoSCR>($"{_paramTarget}.SCR2");
|
||
SCR3 = DEVICE.GetDevice<IoSCR>($"{_paramTarget}.SCR3");
|
||
|
||
if (WaferManager.Instance.CheckHasWafer(ModuleHelper.Converter(_paramTarget), 0))
|
||
{
|
||
_pmPVTempLimit = SC.GetValue<double>($"PM.{_paramTarget}.Heater.PickPVTempLimit");
|
||
}
|
||
else
|
||
{
|
||
_pmPVTempLimit = SC.GetValue<double>($"PM.{_paramTarget}.Heater.PlacePVTempLimit");
|
||
}
|
||
|
||
if (isAtmMode)
|
||
{
|
||
//if (_pmPT1.FeedBack < atmBase)
|
||
//{
|
||
// EV.PostAlarmLog(Module, $"can not open slit valve, running in ATM mode, but {_paramTarget} not in ATM");
|
||
// return Result.FAIL;
|
||
//}
|
||
}
|
||
else
|
||
{
|
||
if (_pmPT1.FeedBack > vacBase)
|
||
{
|
||
EV.PostAlarmLog(Module, $"can not open slit valve, {_paramTarget} not in vacuum");
|
||
return Result.FAIL;
|
||
}
|
||
}
|
||
}
|
||
|
||
ModuleName[] slitValveModules = new ModuleName[]
|
||
{
|
||
ModuleName.LoadLock,ModuleName.PM1,ModuleName.PM2
|
||
};
|
||
foreach (var slitValveModule in slitValveModules)
|
||
{
|
||
if (slitValveModule.ToString() == _paramTarget)
|
||
continue;
|
||
|
||
if (!_tm.CheckSlitValveClose(slitValveModule))
|
||
{
|
||
EV.PostWarningLog(Module, $"can not open slit valve {_paramTarget}, {slitValveModule} slit valve not closed, can not open at same time");
|
||
return Result.FAIL;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ModuleHelper.IsPm(_paramTarget))
|
||
{
|
||
_preTransferPSUEnable = SC.GetValue<bool>($"PM.{_paramTarget}.PreTransferPSUEnable");
|
||
_preTransferSCREnable = SC.GetValue<bool>($"PM.{_paramTarget}.PreTransferSCREnable");
|
||
}
|
||
|
||
_maxPressureDiffOpenSlitValve = SC.GetValue<double>("TM.MaxPressureDiffOpenSlitValve");
|
||
_timeout = SC.GetValue<int>("System.SlitValveMotionTimeout");
|
||
_isAtmMode = SC.GetValue<bool>("System.IsATMMode");
|
||
|
||
|
||
_tmV77DelayTime= SC.GetValue<int>($"TM.OpenSlitValveDelayTimeForPM");
|
||
_tmMfcFlow = SC.GetValue<double>($"TM.MFCFlowWhenV77Open");
|
||
|
||
Notify("Start");
|
||
|
||
return Result.RUN;
|
||
}
|
||
|
||
|
||
public override Result Monitor()
|
||
{
|
||
try
|
||
{
|
||
if (_isLockLock)
|
||
{
|
||
if (_paramIsOpen)
|
||
{
|
||
TimeDelay((int)RoutineStep.Delay1, 1);
|
||
|
||
ExecuteRoutine((int)RoutineStep.ChamberBalance, _balanceRoutine);
|
||
|
||
if (_needPressureBalance && !_isAtmMode)
|
||
{
|
||
TimeDelay((int)RoutineStep.Delay2, 1);
|
||
ExecuteRoutine((int)RoutineStep.LLRoutine, _llVentTo);
|
||
}
|
||
|
||
SetTmToLoadLockVent((int)RoutineStep.OpenTMToLLVent, true, _tm, _paramTarget, 5);
|
||
|
||
TimeDelay((int)RoutineStep.Delay3, 1);
|
||
CheckPressureCondition((int)RoutineStep.CheckPressureCondition, _tm, _paramTarget);
|
||
}
|
||
SetSlitValve((int)RoutineStep.SetSlitValve, TMDevice, _paramTarget, _paramIsOpen, _timeout);
|
||
TimeDelay((int)RoutineStep.Delay4, 1);
|
||
SetTmToLoadLockVent((int)RoutineStep.CloseTMToLLVent, false, _tm, _paramTarget, 5);
|
||
}
|
||
else if (_isUnLoad)
|
||
{
|
||
if (_paramIsOpen)
|
||
{
|
||
TimeDelay((int)RoutineStep.Delay1, 1);
|
||
|
||
ExecuteRoutine((int)RoutineStep.ChamberBalance, _balanceRoutine);
|
||
|
||
if (_needPressureBalance && !_isAtmMode)
|
||
{
|
||
TimeDelay((int)RoutineStep.Delay2, 1);
|
||
ExecuteRoutine((int)RoutineStep.LLRoutine, _unLoadVentTo);
|
||
|
||
}
|
||
|
||
SetTmToUnLoadVent((int)RoutineStep.OpenTMToLLVent, true, _tm, _paramTarget, 10);
|
||
|
||
TimeDelay((int)RoutineStep.Delay3, 1);
|
||
CheckPressureCondition((int)RoutineStep.CheckPressureCondition, _tm, _paramTarget);
|
||
}
|
||
SetSlitValve((int)RoutineStep.SetSlitValve, TMDevice, _paramTarget, _paramIsOpen, _timeout);
|
||
TimeDelay((int)RoutineStep.Delay4, 1);
|
||
SetTmToUnLoadVent((int)RoutineStep.CloseTMToLLVent, false, _tm, _paramTarget, 10);
|
||
}
|
||
else if (_isPM)
|
||
{
|
||
if (_paramIsOpen)//开腔体闸板阀时候的相关操作
|
||
{
|
||
SetPreTransfer((int)RoutineStep.SetPmPreTrasfer, _rotationStopTimeout);//旋转停止,加热停止
|
||
WaitSicServoLoadAngleRun((int)RoutineStep.WaitSicServoHome, 0, 90);//Load是绝对0点,执行Load角度0时候即为原点位,比直接回Home节省时间
|
||
WaitPVTempratureBelowSet((int)RoutineStep.WaitPVTempBelowSet, 600);
|
||
|
||
ExecuteRoutine((int)RoutineStep.ChamberBalance, _balanceRoutine);
|
||
SetPmToTmV70((int)RoutineStep.OpenTMToPMV70, true, _tm, _paramTarget, 5);
|
||
|
||
if (_needPressureBalance && !_isAtmMode)
|
||
{
|
||
SetTmMfc((int)RoutineStep.SetTmMfc, _tmMfcFlow);
|
||
SetSlowVentValve((int)RoutineStep.SetV77, _tm, _paramIsOpen, _timeout);
|
||
TimeDelay((int)RoutineStep.Delay1, _tmV77DelayTime); //5秒可配置
|
||
}
|
||
CheckPressureCondition((int)RoutineStep.CheckPressureCondition, _tm, _paramTarget);
|
||
}
|
||
|
||
SetSlitValve((int)RoutineStep.SetSlitValve, TMDevice, _paramTarget, _paramIsOpen, _timeout);
|
||
if (!_paramIsOpen)
|
||
{
|
||
//关闭闸板阀需要关闭V77
|
||
SetSlowVentValve((int)RoutineStep.SetV77Close, _tm, _paramIsOpen, _timeout);
|
||
}
|
||
SetPmToTmV70((int)RoutineStep.CloseTMToPMV70, false, _tm, _paramTarget, 5);
|
||
|
||
if (_paramIsOpen)
|
||
{
|
||
WaitPMIdle((int)RoutineStep.WaitPMIdle, _paramTarget, 20);
|
||
SetConfinementRingDownAndWait((int)RoutineStep.SetConfinementRingDown, 30); //隔热罩下降
|
||
}
|
||
|
||
if (!_paramIsOpen)
|
||
{
|
||
if(_isATMMode)
|
||
{
|
||
_pmPostTrasferNeedEnableHeat = false;
|
||
}
|
||
SetPostTransfer((int)RoutineStep.SetPostTransfer, _pmPostTrasferNeedEnableHeat);
|
||
TimeDelay((int)RoutineStep.Delay4, 2);
|
||
}
|
||
}
|
||
else if(_isBuffer)
|
||
{
|
||
SetSlitValve((int)RoutineStep.SetSlitValve, TMDevice, _paramTarget, _paramIsOpen, _timeout);
|
||
}
|
||
|
||
}
|
||
catch (RoutineBreakException)
|
||
{
|
||
return Result.RUN;
|
||
}
|
||
catch (RoutineFaildException)
|
||
{
|
||
return Result.FAIL;
|
||
}
|
||
|
||
|
||
Notify("Finished");
|
||
|
||
return Result.DONE;
|
||
}
|
||
|
||
public override void Abort()
|
||
{
|
||
_tm.CloseAllVentPumpValue();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开或关闭V85
|
||
/// </summary>
|
||
/// <param name="id"></param>
|
||
/// <param name="isOpen"></param>
|
||
/// <param name="timeDelay"></param>
|
||
private void SetTmToLoadLockVent(int id,bool isOpen, TM tm, string module, int timeDelay)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify((isOpen ? "Open" : "Close") + " TM to LoadLock Vent");
|
||
|
||
if (!_tm.SetTmToLLVent(isOpen, out string reason))
|
||
{
|
||
Stop(reason);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}, () =>
|
||
{
|
||
double tmPressure = tm.ChamberPressure;
|
||
double targetPressure = 0.0;
|
||
if (ModuleHelper.IsLoadLock(_paramTarget))
|
||
{
|
||
targetPressure = _ll.ChamberPressure;
|
||
}
|
||
else
|
||
{
|
||
Stop($"{module} not define pressure condition");
|
||
return false;
|
||
}
|
||
|
||
return Math.Abs(tmPressure - targetPressure) <= _maxPressureDiffOpenSlitValve;
|
||
},
|
||
timeDelay * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"can not complete in {timeDelay} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
private void SetTmToUnLoadVent(int id, bool isOpen, TM tm, string module, int timeDelay)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify((isOpen ? "Open" : "Close") + " TM to UnLoad Vent");
|
||
|
||
if (!_tm.SetTmToUnLoadVent(isOpen, out string reason))
|
||
{
|
||
Stop(reason);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}, () =>
|
||
{
|
||
double tmPressure = tm.ChamberPressure;
|
||
double targetPressure = _unLoad.ChamberPressure;
|
||
|
||
return Math.Abs(tmPressure - targetPressure) <= _maxPressureDiffOpenSlitValve;
|
||
},
|
||
timeDelay * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"can not complete in {timeDelay} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void SetPmToTmV70(int id, bool isOpen, TM tm, string module, int timeDelay)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify($"set V70 " + (isOpen ? "Open" : "Close"));
|
||
|
||
if (!PMToTm_V70.TurnValve(isOpen, out string reason))
|
||
{
|
||
Stop(reason);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}, () =>
|
||
{
|
||
if(isOpen)
|
||
{
|
||
double tmPressure = tm.ChamberPressure;
|
||
double targetPressure = 0.0;
|
||
|
||
if (ModuleHelper.IsPm(_paramTarget))
|
||
{
|
||
targetPressure = DEVICE.GetDevice<IoPressure>($"{module}.PT1").FeedBack;
|
||
}
|
||
else
|
||
{
|
||
Stop($"{module} not define pressure condition");
|
||
return false;
|
||
}
|
||
|
||
return Math.Abs(tmPressure - targetPressure) <= _maxPressureDiffOpenSlitValve;
|
||
}
|
||
else
|
||
return true;
|
||
},
|
||
timeDelay * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"can not complete in {timeDelay} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void SetSlitValve(int id, TM tm, string module, bool isOpen, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify($"set slit valve {module} " + (isOpen ? "Open" : "Close"));
|
||
|
||
if (!tm.SetSlitValve(ModuleHelper.Converter(module), isOpen, out string reason))
|
||
{
|
||
Stop(reason);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}, () =>
|
||
{
|
||
return isOpen ? tm.CheckSlitValveOpen(ModuleHelper.Converter(module)) : tm.CheckSlitValveClose(ModuleHelper.Converter(module));
|
||
|
||
}, timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"can not complete in {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void CheckPressureCondition(int id, TM tm, string target)
|
||
{
|
||
Tuple<bool, Result> ret = Execute(id, () =>
|
||
{
|
||
Notify($"check pressure condition to open {target} slit valve");
|
||
|
||
double tmPressure = tm.ChamberPressure;
|
||
double targetPressure = 0.0;
|
||
if (ModuleHelper.IsLoadLock(_paramTarget))
|
||
{
|
||
targetPressure = _ll.ChamberPressure;
|
||
}
|
||
else if(_paramTarget == ModuleName.UnLoad.ToString())
|
||
{
|
||
targetPressure = _unLoad.ChamberPressure;
|
||
}
|
||
else if (ModuleHelper.IsPm(_paramTarget))
|
||
{
|
||
targetPressure = DEVICE.GetDevice<IoPressure>($"{target}.PT1").FeedBack;
|
||
}
|
||
else if (_paramTarget == ModuleName.Buffer.ToString())
|
||
{
|
||
targetPressure = tm.ChamberPressure;
|
||
}
|
||
else
|
||
{
|
||
Stop($"{target} not define pressure condition");
|
||
return false;
|
||
}
|
||
|
||
double pressureDiff = Math.Abs(tmPressure - targetPressure);
|
||
if (pressureDiff > _maxPressureDiffOpenSlitValve)
|
||
{
|
||
Stop($"pressure difference {pressureDiff:F3} between TM and {target} exceed tolerance {_maxPressureDiffOpenSlitValve}");
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
});
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void SetSlowVentValve(int id, SicTM tm, bool isOpen, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
string op = isOpen ? "Open" : "Close";
|
||
|
||
Notify($"{op} Slow Vent Valve");
|
||
|
||
if (!tm.SetSlowVentValve(isOpen, out string reason))
|
||
{
|
||
Stop(reason);
|
||
return false;
|
||
}
|
||
|
||
return true;
|
||
}, () =>
|
||
{
|
||
return tm.CheckSlowVentValve(isOpen);
|
||
|
||
}, timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"Set Slow Vent Valve timeout, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void SetTmMfc(int id, double flow)
|
||
{
|
||
Tuple<bool, Result> ret = Execute(id, () =>
|
||
{
|
||
Notify($"Set TM MFC flow to {flow} ");
|
||
|
||
_tm.SetVentMfc(flow, out string reason);
|
||
|
||
return true;
|
||
});
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void SetConfinementRingUp(int id, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify($"Set Confinement RingUp");
|
||
|
||
_confinementRing.MoveUpPos(out string reason);
|
||
|
||
return true;
|
||
}, () =>
|
||
{
|
||
return _confinementRing.RingDone && _confinementRing.RingUpSensor;
|
||
|
||
}, timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"Set Confinement RingUp timeout, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void WaitPMIdle(int id, string _targetModule, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
return true;
|
||
}, () =>
|
||
{
|
||
string pmStatus = DATA.Poll($"{_targetModule}.Status") == null ? "" : DATA.Poll($"{_targetModule}.Status").ToString();
|
||
return pmStatus == "ProcessIdle" || pmStatus == "Idle";
|
||
|
||
}, timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"Wait PM Idle timeout, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
|
||
protected void SetConfinementRingDownAndWait(int id, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify($"Set ConfinementRing Down");
|
||
|
||
if (!_confinementRing.MoveDownPos(out string reason))
|
||
{
|
||
Stop(reason);
|
||
return false;
|
||
}
|
||
return true;
|
||
}, () =>
|
||
{
|
||
return _confinementRing.RingDone && _confinementRing.RingDownSensor;
|
||
},
|
||
timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT)
|
||
{
|
||
Stop($"Set ConfinementRing Down, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
|
||
public void SetPostTransfer(int id, bool postTransferEnableHeat)
|
||
{
|
||
Tuple<bool, Result> ret = Execute(id, () =>
|
||
{
|
||
Notify($"Set PostTransfer");
|
||
|
||
OP.DoOperation($"{_paramTarget}.PostTransfer", new object[] { postTransferEnableHeat });
|
||
|
||
return true;
|
||
});
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
public void SetPreTransfer(int id, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify($"Set PSU and SCR Disable");
|
||
|
||
if (_sicServo != null)
|
||
{
|
||
_sicServo.SetActualSpeed(0, 0);
|
||
}
|
||
if (!_preTransferPSUEnable)
|
||
{
|
||
PSU1.SetPSUEnable(false, out _);
|
||
PSU2.SetPSUEnable(false, out _);
|
||
PSU3.SetPSUEnable(false, out _);
|
||
}
|
||
if (!_preTransferSCREnable)
|
||
{
|
||
SCR1.SetEnable(false, out _);
|
||
SCR2.SetEnable(false, out _);
|
||
SCR3.SetEnable(false, out _);
|
||
}
|
||
return true;
|
||
}, () =>
|
||
{
|
||
if (_sicServo.ActualSpeedFeedback > 0)
|
||
{
|
||
return false;
|
||
}
|
||
if (!_preTransferPSUEnable)
|
||
{
|
||
if (PSU1 != null && PSU1.StatusFeedBack)
|
||
{
|
||
return false;
|
||
}
|
||
if (PSU2 != null && PSU2.StatusFeedBack)
|
||
{
|
||
return false;
|
||
}
|
||
if (PSU3 != null && PSU3.StatusFeedBack)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
if (!_preTransferSCREnable)
|
||
{
|
||
if (SCR1 != null && SCR1.StatusFeedBack)
|
||
{
|
||
return false;
|
||
}
|
||
if (SCR2 != null && SCR2.StatusFeedBack)
|
||
{
|
||
return false;
|
||
}
|
||
if (SCR3 != null && SCR3.StatusFeedBack)
|
||
{
|
||
return false;
|
||
}
|
||
}
|
||
return true;
|
||
|
||
}, timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT) //timeout
|
||
{
|
||
Stop($"Set PreTransfer timeout, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
|
||
private void WaitTempratureBelow900(int id, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
|
||
{
|
||
Notify($"Wait DiHeaterTempBelow900CSW");
|
||
return true;
|
||
|
||
}, () =>
|
||
{
|
||
if (_pmIoInterLock != null)
|
||
{
|
||
return _pmIoInterLock.DiHeaterTempBelow900CSW;
|
||
}
|
||
else
|
||
{
|
||
return true;
|
||
}
|
||
},
|
||
timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT)
|
||
{
|
||
Stop($"Wait PM Temprature below 900 timeout, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
|
||
private void WaitPVTempratureBelowSet(int id, int timeout)
|
||
{
|
||
Tuple<bool, Result> ret = ExecuteAndWait(id, ()=>
|
||
{
|
||
Notify($"Wait PV2Temp below{_pmPVTempLimit}℃ and PV3Temp below{_pmPVTempLimit}℃");
|
||
return true;
|
||
|
||
}, () =>
|
||
{
|
||
if (_tc1 != null && _pmPVTempLimit > 0)
|
||
{
|
||
return _tc1.L2PVFeedBack < _pmPVTempLimit && _tc1.L3PVFeedBack < _pmPVTempLimit;
|
||
}
|
||
else
|
||
{
|
||
return true;
|
||
}
|
||
},
|
||
timeout * 1000);
|
||
|
||
if (ret.Item1)
|
||
{
|
||
if (ret.Item2 == Result.FAIL)
|
||
{
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else if (ret.Item2 == Result.TIMEOUT)
|
||
{
|
||
Stop($"Wait PM Temprature below 900 timeout, over {timeout} seconds");
|
||
throw (new RoutineFaildException());
|
||
}
|
||
else
|
||
throw (new RoutineBreakException());
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|