using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Routine; using MECF.Framework.Common.Utilities; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.Loader; using CyberX8_RT.Devices.PUF; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Modules.PUF { public class PufOnlyPlaceToLoaderRoutine : RoutineBase, IRoutine { private enum PlaceStep { LipSealGotoUnlock, LipSealGotoUnlockWait, VacuumLevelCheck, SideConditionRoutine, SideConditionRoutineWait, RotationGotoLoaderPlaceDown, RotationGotoLoaderPlaceDownWait, FirstPlaceVacuumCheck, FirstPlaceVacuumCheckWait, SecondPlaceVacuumCheck, SecondPlaceVacuumCheckWait, VacuumOff, End } #region 常量 private const string SideA = "SideA"; private const string SideB = "SideB"; private const string WAFER_ABSENT = "WaferAbsent"; #endregion #region 内部变量 private bool _isSecondPlaceVacuumCheck = false; private string _side; private JetAxisBase _flipAxis; private JetAxisBase _rotationAxis; private PufVacuum _vacuum; private JetAxisBase _loaderCrsAxis; private PufWaferPickSubRoutine _pufWaferPickSubRoutine; private PufPlaceVacuumCheckRoutine _pufPlaceVacuumCheckRoutine; #endregion /// /// 构造函数 /// /// public PufOnlyPlaceToLoaderRoutine(string module) : base(module) { _pufWaferPickSubRoutine = new PufWaferPickSubRoutine(module); } /// /// 中止 /// public void Abort() { if (_pufWaferPickSubRoutine != null) { _pufWaferPickSubRoutine.Abort(); } _flipAxis.StopPositionOperation(); _rotationAxis.StopPositionOperation(); Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Run(PlaceStep.LipSealGotoUnlock, LipSealGotoUnlock, _delay_1ms) .WaitWithStopCondition(PlaceStep.LipSealGotoUnlockWait, CheckLipSealEndStatus, CheckLipSealStopStatus) .Run(PlaceStep.VacuumLevelCheck, CheckWaferPresent, _delay_1ms) .RunConditionSubRoutine(PlaceStep.SideConditionRoutine, SideConditionIndex, new IRoutine[] { _pufWaferPickSubRoutine }, new object[] { _side }) .WaitConditionSubRoutine(PlaceStep.SideConditionRoutineWait) .Run(PlaceStep.RotationGotoLoaderPlaceDown, () => _rotationAxis.PositionStation("LoaderPutDown"), _delay_1ms) .WaitWithStopCondition(PlaceStep.RotationGotoLoaderPlaceDownWait, CheckRotationPositionStatus, CheckRotationPositionRunStop) .Run(PlaceStep.FirstPlaceVacuumCheck, () => StartPlaceVacuumCheckRoutine(false, 1), _delay_1ms) .WaitWithStopCondition(PlaceStep.FirstPlaceVacuumCheckWait, CheckFirstPlaceVacuumCheckRoutineStatus, () => { return false; }) .Run(PlaceStep.SecondPlaceVacuumCheck, StartSecondPlaceVacuumCheckRoutine, _delay_1ms) .WaitWithStopCondition(PlaceStep.SecondPlaceVacuumCheckWait, CheckPlaceVacuumCheckRoutineEndStatus, CheckSecondPlaceVacuumCheckRoutineStopStatus) .Run(PlaceStep.VacuumOff, VacuumOff, _delay_1ms) .End(PlaceStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// LipSeal Goto Unlock /// /// private bool LipSealGotoUnlock() { if (ModuleHelper.IsInstalled(ModuleName.Loader1)) { return _loaderCrsAxis.PositionStation("Unlock"); } else { return true; } } /// /// 检验Lip Seal完成状态 /// /// private bool CheckLipSealEndStatus() { if (ModuleHelper.IsInstalled(ModuleName.Loader1)) { return _loaderCrsAxis.Status == RState.End; } else { return true; } } /// /// 检验Lip Seal完成状态 /// /// private bool CheckLipSealStopStatus() { if (ModuleHelper.IsInstalled(ModuleName.Loader1)) { bool result= _loaderCrsAxis.Status == RState.Failed; if (result) { NotifyError(eEvent.ERR_PUF, $"lipsel axis goto unlock failed", 0); } return result; } else { return true; } } /// /// 检验是否存在Wafer /// /// private bool CheckWaferPresent() { if (_side == SideA) { if (!_vacuum.ChuckAWaferPresent) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"{_side} has no Wafer"); return false; } } else { if (!_vacuum.ChuckBWaferPresent) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"{_side} has no Wafer"); return false; } } return true; } /// /// Side条件获取SubRoutine索引 /// /// private int SideConditionIndex() { if (_flipAxis.CheckPositionIsInStation(_flipAxis.MotionData.MotorPosition, _side)) { return 1; } else { return 0; } } /// /// 检验Rotation移动状态 /// /// private bool CheckRotationPositionStatus() { return _rotationAxis.Status == RState.End; } /// /// 检验Rotation是否还在运动 /// /// private bool CheckRotationPositionRunStop() { return _rotationAxis.Status == RState.Failed; } /// /// 启动Place Vacuum Check routine /// /// private bool StartPlaceVacuumCheckRoutine(bool showError, int times) { return _pufPlaceVacuumCheckRoutine.Start(_side, showError, times) == RState.Running; } /// /// 检验第一次Place Vacuum Check routine运行情况 /// /// private bool CheckFirstPlaceVacuumCheckRoutineStatus() { RState rsState = _pufPlaceVacuumCheckRoutine.Monitor(); if (rsState == RState.End) { return true; } if (rsState == RState.Failed || rsState == RState.Timeout) { _isSecondPlaceVacuumCheck = true; return true; } return false; } /// /// 启动Place Vacuum Check routine完成状态 /// /// private bool CheckPlaceVacuumCheckRoutineEndStatus() { RState rsState = _pufPlaceVacuumCheckRoutine.Monitor(); return rsState == RState.End; } /// /// 启动第二次Place Vacuum Check routine /// /// private bool StartSecondPlaceVacuumCheckRoutine() { if (_isSecondPlaceVacuumCheck) { return StartPlaceVacuumCheckRoutine(true, 2); } else { return true; } } /// /// 检验第二次Place Vacuum Check routine错误状态 /// /// private bool CheckSecondPlaceVacuumCheckRoutineStopStatus() { RState rState = _pufPlaceVacuumCheckRoutine.Monitor(); if (rState == RState.Failed || rState == RState.Timeout) { return true; } return false; } /// /// 关闭Vacuum /// /// private bool VacuumOff() { if (_side == "SideA") { return _vacuum.VacuumAOff(); } else if (_side == "SideB") { return _vacuum.VacuumBOff(); } return false; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _side = objs[0].ToString(); _flipAxis = DEVICE.GetDevice($"{Module}.Flip"); _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); _vacuum = DEVICE.GetDevice($"{Module}.Vacuum"); GetCrsAxis(); _isSecondPlaceVacuumCheck = false; _pufPlaceVacuumCheckRoutine = new PufPlaceVacuumCheckRoutine(Module); return Runner.Start(Module, "Start Place To Loader"); } /// /// 获取lipseal Axis /// private void GetCrsAxis() { if (_side==SideA) { _loaderCrsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LSA"); } else { _loaderCrsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LSB"); } } } }