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.Reflection; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Modules.PUF { public class PufSwapRoutine : RoutineBase, IRoutine { private enum SwapStep { CheckPreStatus, RotationLoaderPickup, RotationLoaderPickupWait, VerticalLoaderPickup, VerticalLoaderPickupWait, SideAVacuumOn, StickDistance, StickDistanceWait, StickDistanceCheck, VerticalFlip, WaitVerticalFlip, RotationFlip, WaitRotationFlip, FlipSideB, WaitFlipSideB, PlaceToLoader, PlaceToLoaderWait, End } #region 常量 private const string CURRENT_STATION_LIST = "CurrentStationList"; private const string WAFER_PRESENT = "WaferPresent"; private const string SIDE_A = "SideA"; #endregion #region 内部变量 private LoaderEntity _loaderEntity; private JetAxisBase _flipAxis; private JetAxisBase _rotationAxis; private JetAxisBase _verticalAxis; private JetAxisBase _gantryAxis; private LoaderSideDevice _loaderSide; private PufVacuum _vacuum; private PufDistanceSensor _distanceSensor; private PufPlaceToLoaderRoutine _placeToLoaderRoutine; #endregion /// /// 构造函数 /// /// public PufSwapRoutine(string module) : base(module) { _placeToLoaderRoutine = new PufPlaceToLoaderRoutine(Module); } /// /// 中止 /// public void Abort() { Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Run(SwapStep.CheckPreStatus,CheckCondition,_delay_1ms) .Run(SwapStep.RotationLoaderPickup, ()=> { return AxisGotoPosition(_rotationAxis, "LoaderPickup",0); }, _delay_1ms) .WaitWithStopCondition(SwapStep.RotationLoaderPickupWait, () => { return _rotationAxis.Status == RState.End; }, () => { return CheckRotationStopStatus(0); }) .Run(SwapStep.VerticalLoaderPickup, () => { return AxisGotoPosition(_verticalAxis, "LoaderPickup", 0); }, _delay_1ms) .WaitWithStopCondition(SwapStep.VerticalLoaderPickupWait, () => { return _verticalAxis.Status == RState.End; }, () => { return CheckVerticalStopStatus(0); }) .Run(SwapStep.SideAVacuumOn, SideAVacuumOn, CheckSideAWaferPresent, 5000) .Run(SwapStep.StickDistance, StickDistance, 100) .WaitWithStopCondition(SwapStep.StickDistanceWait, () => { return _verticalAxis.Status == RState.End; }, () => { return CheckVerticalStopStatus(0); }) .Wait(SwapStep.StickDistanceCheck, CheckStickDistanceStatus, 1000) .Run(SwapStep.VerticalFlip, () => { return AxisGotoPosition(_verticalAxis,"Flip",1); }, _delay_1ms) .WaitWithStopCondition(SwapStep.WaitVerticalFlip, () => { return _verticalAxis.Status == RState.End; }, () => { return CheckVerticalStopStatus(1); }) .Run(SwapStep.RotationFlip, () => { return AxisGotoPosition(_rotationAxis,"Flip",1); }, _delay_1ms) .WaitWithStopCondition(SwapStep.WaitRotationFlip, () => { return _rotationAxis.Status == RState.End; }, () => { return CheckRotationStopStatus(1); }) .Run(SwapStep.FlipSideB, () => { return AxisGotoPosition(_flipAxis,"SideB", 1); }, _delay_1ms) .WaitWithStopCondition(SwapStep.WaitFlipSideB, () => { return _flipAxis.Status == RState.End; }, () => { return CheckFlipStopStatus(1); }) .Run(SwapStep.PlaceToLoader, () => _placeToLoaderRoutine.Start("SideB") == RState.Running, _delay_1ms) .WaitWithStopCondition(SwapStep.PlaceToLoaderWait, ()=>CommonFunction.CheckRoutineEndState(_placeToLoaderRoutine), CheckPlaceToRoutineStopStatus) .End(SwapStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// Side a打开真空 /// /// private bool SideAVacuumOn() { bool result= _vacuum.VacuumAOn(); if (!result) { NotifyError(eEvent.ERR_PUF, "side A Vacuum on failed", 0); } return result; } /// /// 检验SideA是否存在Wafer /// /// private bool CheckSideAWaferPresent() { bool result= _vacuum.ChuckAVacuumStatus == WAFER_PRESENT; if(result) { LoaderEntity loaderEntity = Singleton.Instance.GetModule(ModuleName.Loader1.ToString()); if(loaderEntity!=null) { WaferHolderInfo waferHolder = loaderEntity.WaferHolderInfo; if(_loaderSide.Name==SIDE_A) { if (WaferManager.Instance.CheckHasWafer(ModuleName.Loader1, 0)) { WaferManager.Instance.WaferMoved(ModuleName.Loader1, 0, ModuleHelper.Converter(Module), 0); } else { NotifyError(eEvent.ERR_PUF, "Loader sideA has no wafer",0); return false; } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.Loader1, 1)) { WaferManager.Instance.WaferMoved(ModuleName.Loader1, 1, ModuleHelper.Converter(Module), 0); } else { NotifyError(eEvent.ERR_PUF, "Loader sideA has no wafer", 0); return false; } } } } return result; } /// /// Stick Distance /// /// private bool StickDistance() { bool result= _distanceSensor.GotoStickDistance(); if(!result) { NotifyError(eEvent.ERR_PUF, "goto stick distance failed", 0); } return result; } /// /// Stick Distance检验结果 /// /// private bool CheckStickDistanceStatus() { bool result= _distanceSensor.CheckStickDistanceStatus(); if (!result) { NotifyError(eEvent.ERR_PUF, "check stick distance failed", 0); } return result; } /// /// Axis goto position /// /// /// /// /// private bool AxisGotoPosition(JetAxisBase axis,string position,int index) { bool result = axis.PositionStation(position); if(!result) { NotifyError(eEvent.ERR_PUF, $"{axis.Module} goto {position} failed",index); } return result; } /// /// 检验Flip异常状态 /// /// private bool CheckFlipStopStatus(int index) { bool result = _flipAxis.Status == RState.Failed || _flipAxis.Status == RState.Timeout; if (result) { NotifyError(eEvent.ERR_PUF, "flip motion failed", index); } return result; } /// /// 检验Rotation异常状态 /// /// private bool CheckRotationStopStatus(int index) { bool result = _rotationAxis.Status == RState.Failed || _rotationAxis.Status == RState.Timeout; if (result) { NotifyError(eEvent.ERR_PUF, "rotation motion failed", index); } return result; } /// /// 检验Vertical异常状态 /// /// private bool CheckVerticalStopStatus(int index) { bool result = _verticalAxis.Status == RState.Failed || _verticalAxis.Status == RState.Timeout; if (result) { NotifyError(eEvent.ERR_PUF, "vetical motion failed", index); } return result; } /// /// 检验PlaceToLoader异常状态 /// /// private bool CheckPlaceToRoutineStopStatus() { bool result = CommonFunction.CheckRoutineStopState(_placeToLoaderRoutine); if (result) { NotifyError(eEvent.ERR_PUF, "place wafer failed", 2); } return result; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { InitializeParameters(); return Runner.Start(Module, "Start Swap"); } /// /// 初始化参数 /// private void InitializeParameters() { _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"); _distanceSensor = DEVICE.GetDevice($"{Module}.DistanceSensor"); GetLoaderSide(); } /// /// 检验条件 /// /// private bool CheckCondition() { //Loader1.Rotation 在LOADA bool isLoaderInstall = ModuleHelper.IsInstalled(ModuleName.Loader1); if (isLoaderInstall) { JetAxisBase loaderRotationAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.Rotation"); 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"); 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"); 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")) { NotifyError(eEvent.ERR_PUF, $"Loader ShuttleB {loaderShuttleBPosition} is not in OPEN",-1); return false; } //Loader1.TiltB 在HORI JetAxisBase loaderTiltBAxis = DEVICE.GetDevice($"{ModuleName.Loader1}.TiltB"); double loaderTiltBPosition = loaderTiltBAxis.MotionData.MotorPosition; if (!loaderTiltBAxis.CheckPositionIsInStation(loaderTiltBPosition, "HORI")) { NotifyError(eEvent.ERR_PUF, $"Loader TiltB {loaderTiltBPosition} is not in HORI",-1); 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; } if (!_loaderSide.SideData.DoorUnlock) { NotifyError(eEvent.ERR_PUF, "Loader1 Door is Locked",-1); return false; } //if (_loaderSide.SideData.WHBladder) //{ // NotifyError(eEvent.ERR_PUF,, "Loader1 WS Bladder is on"); // return false; //} if (_loaderSide.SideData.TransBladder) { NotifyError(eEvent.ERR_PUF, "Loader1 Translate Bladder is on",-1); return false; } if (_loaderSide.SideData.TransHigh) { NotifyError(eEvent.ERR_PUF, "Loader1 Translate High Pre 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 verticalPosition = _verticalAxis.MotionData.MotorPosition; if (!_verticalAxis.CheckPositionIsInStation(verticalPosition, "Park")) { NotifyError(eEvent.ERR_PUF, $"vertical axis {verticalPosition} is not at Park Station",-1); return false; } double rotaionPosition = _rotationAxis.MotionData.MotorPosition; if (_rotationAxis.CheckPositionIsEmpty(rotaionPosition)) { NotifyError(eEvent.ERR_PUF, $"rotation axis {rotaionPosition} is not at Station",-1); return false; } double flipPosition = _flipAxis.MotionData.MotorPosition; if (_flipAxis.CheckPositionIsEmpty(flipPosition)) { NotifyError(eEvent.ERR_PUF, $"flip axis {flipPosition} is not at Station",-1); return false; } //A面 if (_loaderSide.Name == SIDE_A) { if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 0)) { NotifyError(eEvent.ERR_PUF, "loader side A has no wafer",-1); return false; } } else { if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 1)) { NotifyError(eEvent.ERR_PUF, "loader side B has no wafer",-1); 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"); } } /// /// 重试 /// /// public RState Retry(int step) { InitializeParameters(); List preStepIds = new List(); if (step == 0||step==-1) { return Runner.Retry(SwapStep.CheckPreStatus, preStepIds, Module, "Swap Retry"); } else if (step == 1) { AddPreSteps(SwapStep.VerticalFlip, preStepIds); return Runner.Retry(SwapStep.VerticalFlip, preStepIds, Module, $"Swap step {SwapStep.VerticalFlip} Retry"); } else { AddPreSteps(SwapStep.PlaceToLoader, preStepIds); return Runner.Retry(SwapStep.PlaceToLoader, preStepIds, Module, $"Swap step {SwapStep.PlaceToLoader} Retry"); } } /// /// 忽略前 /// /// /// private void AddPreSteps(SwapStep step, List preStepIds) { for (int i = 0; i < (int)step; i++) { preStepIds.Add((SwapStep)i); } } /// /// 检验完成情况 /// /// public bool CheckCompleteCondition() { if (WaferManager.Instance.CheckHasWafer(Module, 1)) { NotifyError(eEvent.ERR_PUF, "Side B has wafer", 0); return false; } if (Module == ModuleName.PUF1.ToString()) { if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 0)) { NotifyError(eEvent.ERR_PUF, "Loader Side A has wafer", 0); return false; } } else { if (WaferManager.Instance.CheckNoWafer(ModuleName.Loader1, 1)) { NotifyError(eEvent.ERR_PUF, "Loader Side B has wafer", 0); return false; } } return true; } } }