using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using MECF.Framework.Common.DBCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.Common.Utilities; using MECF.Framework.Common.WaferHolder; using CyberX8_Core; using CyberX8_RT.Devices.AXIS; using CyberX8_RT.Devices.Loader; using CyberX8_RT.Devices.PUF; using CyberX8_RT.Modules.Loader; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Modules.PUF { public class PufPlaceToLoaderRoutine : RoutineBase, IRoutine { private enum PlaceStep { CheckStatus, OnlyPlaceToLoader, OnlyPlaceToLoaderWait, SwitchWaferHolder, LastVerticalFlip, LastVerticalFlipWait, LastVerticalPark, LastVerticalParkWait, LastRotationPark, LastRotationParkWait, End } #region 常量 private const string CURRENT_STATION_LIST = "CurrentStationList"; private const string SIDE_A = "SideA"; #endregion #region 内部变量 private string _side; private LoaderEntity _loaderEntity; private JetAxisBase _flipAxis; private JetAxisBase _rotationAxis; private JetAxisBase _verticalAxis; private PufVacuum _vacuum; private LoaderSideDevice _loaderSide; private JetAxisBase _loaderCrsAxis; private JetAxisBase _gantryAxis; private PufOnlyPlaceToLoaderRoutine _onlyPlaceToLoaderRoutine; #endregion /// /// 构造函数 /// /// public PufPlaceToLoaderRoutine(string module) : base(module) { } /// /// 中止 /// public void Abort() { _flipAxis.StopPositionOperation(); _rotationAxis.StopPositionOperation(); _verticalAxis.StopPositionOperation(); Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Run(PlaceStep.CheckStatus,CheckPreCondition,_delay_1ms) .Run(PlaceStep.OnlyPlaceToLoader,StartOnlyPlaceToLoader,_delay_1ms) .WaitWithStopCondition(PlaceStep.OnlyPlaceToLoaderWait,CheckPlaceEndStatus,CheckPlaceStopStatus) .Run(PlaceStep.SwitchWaferHolder,SwitchWaferHolderSideWafer,_delay_1ms) .Run(PlaceStep.LastVerticalFlip, () => _verticalAxis.PositionStation("Flip"), _delay_1ms) .WaitWithStopCondition(PlaceStep.LastVerticalFlipWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop) .Run(PlaceStep.LastVerticalPark, () => _verticalAxis.PositionStation("Park"), _delay_1ms) .WaitWithStopCondition(PlaceStep.LastVerticalParkWait, CheckVerticalPositionStatus, CheckVerticalPositionRunStop) .Run(PlaceStep.LastRotationPark, () => _rotationAxis.PositionStation("Park"), _delay_1ms) .WaitWithStopCondition(PlaceStep.LastRotationParkWait, CheckRotationPositionStatus, CheckRotationPositionRunStop) .End(PlaceStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// 执行放片至Loader /// /// private bool StartOnlyPlaceToLoader() { return _onlyPlaceToLoaderRoutine.Start(_side) == RState.Running; } /// /// 检验放片状态 /// /// private bool CheckPlaceEndStatus() { return _onlyPlaceToLoaderRoutine.Monitor() ==RState.End; } /// /// 检验放片停止状态 /// /// private bool CheckPlaceStopStatus() { RState state = _onlyPlaceToLoaderRoutine.Monitor(); if(state==RState.Failed||state==RState.Timeout) { return true; } return false; } /// /// WaferHolder交换片 /// /// private bool SwitchWaferHolderSideWafer() { WaferHolderInfo waferHolderInfo = _loaderEntity.WaferHolderInfo; if (waferHolderInfo != null) { if (Module == ModuleName.PUF1.ToString()) { WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), 1, ModuleName.Loader1, 0); WaferInfo loaderWaferInfo = WaferManager.Instance.GetWafer(ModuleName.Loader1, 0); waferHolderInfo.WaferAId = loaderWaferInfo.WaferID; waferHolderInfo.WaferAType = (int)loaderWaferInfo.WaferType; WaferHolderDataRecorder.UpdateWaferHolderData(waferHolderInfo.Id, waferHolderInfo); MaterialTrackerManager.Instance.UpdateModuleMaterial(ModuleName.Loader1.ToString()); } else { WaferManager.Instance.WaferMoved(ModuleHelper.Converter(Module), 1, ModuleName.Loader1, 1); WaferInfo loaderWaferInfo = WaferManager.Instance.GetWafer(ModuleName.Loader1, 1); waferHolderInfo.WaferBId = loaderWaferInfo.WaferID; waferHolderInfo.WaferBType = (int)loaderWaferInfo.WaferType; WaferHolderDataRecorder.UpdateWaferHolderData(waferHolderInfo.Id, waferHolderInfo); MaterialTrackerManager.Instance.UpdateModuleMaterial(ModuleName.Loader1.ToString()); } } return true; } /// /// 检验Rotation移动状态 /// /// private bool CheckRotationPositionStatus() { return _rotationAxis.Status == RState.End; } /// /// 检验Rotation是否还在运动 /// /// private bool CheckRotationPositionRunStop() { return _rotationAxis.Status == RState.Failed; } /// /// 检验Vertical移动状态 /// /// private bool CheckVerticalPositionStatus() { return _verticalAxis.Status == RState.End; } /// /// 检验Vertical是否还在运动 /// /// private bool CheckVerticalPositionRunStop() { return _verticalAxis.Status == RState.Failed; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _side = objs[0].ToString(); _loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); _flipAxis = DEVICE.GetDevice($"{Module}.Flip"); _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); _verticalAxis = DEVICE.GetDevice($"{Module}.Vertical"); _vacuum = DEVICE.GetDevice($"{Module}.Vacuum"); _gantryAxis = DEVICE.GetDevice($"{ModuleName.Transporter2}.Gantry"); GetLoaderSide(); GetCrsAxis(); _onlyPlaceToLoaderRoutine = new PufOnlyPlaceToLoaderRoutine(Module.ToString()); return Runner.Start(Module, "Place To Loader"); } /// /// 检验是否存在Wafer /// /// private bool CheckWaferPresent() { if (_side == "SideA") { if (!_vacuum.ChuckAWaferPresent) { NotifyError(eEvent.ERR_PUF, $"{_side} has no Wafer", -1); return false; } } else { if (!_vacuum.ChuckBWaferPresent) { NotifyError(eEvent.ERR_PUF, $"{_side} has no Wafer",-1); return false; } } return true; } /// /// 检验前置条件 /// /// private bool CheckPreCondition() { if(!CheckWaferPresent()) { return false; } bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1); if (isLoaderInstall) { if(_loaderSide.SideData.WaferPresent) { NotifyError(eEvent.ERR_PUF, $"{_loaderSide.Module}.{_loaderSide.Name} has Wafer",-1); return false; } JetAxisBase loaderRotationaxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation"); if (loaderRotationaxis != null) { double loaderRotationPosition = loaderRotationaxis.MotionData.MotorPosition; if (!loaderRotationaxis.CheckPositionIsInStation(loaderRotationPosition, "LOADA")) { NotifyError(eEvent.ERR_PUF, $"Loader Rotation {loaderRotationPosition} is not in LOADA", -1); return false; } } if (Module == ModuleName.PUF1.ToString()) { //Loader1.SwingA 在Open JetAxisBase loaderShuttleAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.ShuttleA"); if (loaderShuttleAAxis != null) { double loaderShuttleAPosition = loaderShuttleAAxis.MotionData.MotorPosition; if (!loaderShuttleAAxis.CheckPositionIsInStation(loaderShuttleAPosition, "OPEN")) { NotifyError(eEvent.ERR_PUF, $"Loader ShuttleA {loaderShuttleAPosition} is not in OPEN", -1); return false; } } //Loader1.TiltA 在HORI JetAxisBase loaderTiltAAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltA"); if (loaderTiltAAxis != null) { double loaderTiltAPosition = loaderTiltAAxis.MotionData.MotorPosition; if (!loaderTiltAAxis.CheckPositionIsInStation(loaderTiltAPosition, "HORI")) { NotifyError(eEvent.ERR_PUF, $"Loader TiltA {loaderTiltAPosition} is not in HORI", -1); return false; } } } if (Module == ModuleName.PUF2.ToString()) { //Loader1.SwingB 在Open JetAxisBase loaderShuttleBAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.ShuttleB"); double loaderShuttleBPosition = loaderShuttleBAxis.MotionData.MotorPosition; if (!loaderShuttleBAxis.CheckPositionIsInStation(loaderShuttleBPosition, "OPEN")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader ShuttleB {loaderShuttleBPosition} is not in OPEN"); return false; } //Loader1.TiltB 在HORI JetAxisBase loaderTiltBAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltB"); double loaderTiltBPosition = loaderTiltBAxis.MotionData.MotorPosition; if (!loaderTiltBAxis.CheckPositionIsInStation(loaderTiltBPosition, "HORI")) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"Loader TiltB {loaderTiltBPosition} is not in HORI"); return false; } } //Loader Handle Wafer状态确认 // Lip Seal Vacuum "ON" if (!_loaderSide.SideData.CRSVacuum) { NotifyError(eEvent.ERR_PUF, "Loader1 LS Vacuum is off", -1); return false; } //Bernoulli Bladder "ON",Retracted Green Light if (!_loaderSide.SideData.BernoulliBladder) { NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli Bladder is off",-1); return false; } if (_loaderSide.SideData.BernoulliExtended) { NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli Retracted is off", -1); return false; } //其他SideA/B均为OFF if (_loaderSide.SideData.BernoulliN2) { NotifyError(eEvent.ERR_PUF, "Loader1 Bernoulli N2 is on",-1); return false; } } //Loader Transporter在Loader右侧 bool loaderTransporterInstalled = ModuleHelper.IsInstalled(ModuleName.Transporter2); if (loaderTransporterInstalled && !_gantryAxis.JudgeCompareTargetStation("Loader", "Right")) { NotifyError(eEvent.ERR_PUF, "Loader Transporter is not in Loader right position", -1); return false; } double rotationPosition = _rotationAxis.MotionData.MotorPosition; if (_rotationAxis.CheckPositionIsEmpty(rotationPosition)) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"rotation axis {rotationPosition} is not at Station"); return false; } double flipPosition = _flipAxis.MotionData.MotorPosition; if (_flipAxis.CheckPositionIsEmpty(flipPosition)) { LOG.WriteLog(eEvent.ERR_PUF, Module, $"flip axis {flipPosition} is not at Station"); return false; } return true; } /// /// 获取LoaderSide /// private void GetLoaderSide() { if (Module == ModuleName.PUF1.ToString()) { _loaderSide = DEVICE.GetDevice($"{ModuleName.Loader1}.SideA"); } else { _loaderSide = DEVICE.GetDevice($"{ModuleName.Loader1}.SideB"); } } /// /// 获取lipseal Axis /// private void GetCrsAxis() { if(Module==ModuleName.PUF1.ToString()) { _loaderCrsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LSA"); } else { _loaderCrsAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.LSB"); } } } }