using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using MECF.Framework.Common.CommonData.Loader; 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.AXIS.CANOpen; using CyberX8_RT.Modules.PUF; using CyberX8_RT.Modules; using System; using CyberX8_RT.Modules.Transporter; using Aitex.Core.RT.SCCore; namespace CyberX8_RT.Devices.Loader { public class LoaderInstallCRSRoutine : RoutineBase, IRoutine { private enum InstallStep { CheckPreCondition, TiltGotoVertical, TiltGotoVerticalCheck, LSGotoUnlock, LSGotoUnlockWait, ShuttleGotoIN, ShuttleGotoINWait, BernoulliBladderOn, BernoulliBladderOnCheck, BernoulliN2On, BernoulliN2OnCheck, WSBladderOn, WSBladderOnCheck, LSVacuumOn, LSVacuumOnCheck, VacuumLevelCheck, VacuumLevelCheckWait, ShuttleGotoLS, ShuttleGotoLSWait, LSGotoLock, LSGotoLockWait, BernoulliN2Off, BernoulliN2OffCheck, WSBladderOff, WSBladderOffCheck, Wait500MSForWSBladder, LSVacuumOff, LSVacuumOffCheck, Wait500MS, ShuttleGotoMID, ShuttleGotoMIDWait, HomingLSAxis, HomingLSAxisWait, End } #region 内部变量 private string _side = ""; private JetAxisBase _lsAxis; private LoaderSideBernoulliBladderRoutine _bernoulliBladderRoutine; private LoaderSideBernoulliN2PressureRoutine _bernoulliN2PressureRoutine; private LoaderSideVacuumRoutine _vacuumRoutine; private LoaderSideVacuumLevelCheckRoutine _vacuumLevelCheckRoutine; private LoaderSideWhBladderRoutine _whBladderRoutine; private JetAxisBase _shuttleAxis; private JetAxisBase _tiltAxis; private JetAxisBase _rotationAxis; private LoaderCommonDevice _loaderCommonDevice; private LoaderSideDevice _sideDevice; /// /// WaferSize /// private int _waferSize; #endregion /// /// 构造函数 /// /// public LoaderInstallCRSRoutine(string module,string side) : base(module) { _side = side; } /// /// 中止 /// public void Abort() { Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Run(InstallStep.CheckPreCondition, CheckPreCondition, _delay_1ms) //1. Tilt Goto Vertical .Run(InstallStep.TiltGotoVertical, () => { return _tiltAxis.PositionStation("VERT",false); }, NullFun, _delay_1ms) .WaitWithStopCondition(InstallStep.TiltGotoVerticalCheck, () => { return _tiltAxis.Status == RState.End; }, () => { return _tiltAxis.Status == RState.Failed; }) //2. LS Goto Unlock .Run(InstallStep.LSGotoUnlock, () => { return _lsAxis.PositionStation($"Unlock{_waferSize}", false); }, NullFun, _delay_1ms) .WaitWithStopCondition(InstallStep.LSGotoUnlockWait, () => { return _lsAxis.Status == RState.End; }, () => { return _lsAxis.Status == RState.Failed; }) //3. Shuttle Goto IN .Run(InstallStep.ShuttleGotoIN, () => { return _shuttleAxis.PositionStation("IN", false); }, NullFun, _delay_1ms) .WaitWithStopCondition(InstallStep.ShuttleGotoINWait, () => { return _shuttleAxis.Status == RState.End; }, () => { return _shuttleAxis.Status == RState.Failed; }) //4. BernoulliBladder On .Run(InstallStep.BernoulliBladderOn, () => { return _bernoulliBladderRoutine.Start(true) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.BernoulliBladderOnCheck, () => { return CommonFunction.CheckRoutineEndState(_bernoulliBladderRoutine); }, () => CheckRoutineStopStatus(_bernoulliBladderRoutine, "BernoulliBladder On failed")) //5. Bernoulli N2 On .Run(InstallStep.BernoulliN2On, () => { return _bernoulliN2PressureRoutine.Start(true) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.BernoulliN2OnCheck, () => { return CommonFunction.CheckRoutineEndState(_bernoulliN2PressureRoutine); }, () => CheckRoutineStopStatus(_bernoulliN2PressureRoutine, " BernoulliN2 On failed")) //6. WS Bladder On .Run(InstallStep.WSBladderOn, () => { return _whBladderRoutine.Start(true) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.WSBladderOnCheck, () => { return CommonFunction.CheckRoutineEndState(_whBladderRoutine); }, () => CheckRoutineStopStatus(_whBladderRoutine, "WSBladder On failed")) //7. LS Vacuum On .Run(InstallStep.LSVacuumOn, () => { return _vacuumRoutine.Start(true) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.LSVacuumOnCheck, () => { return CommonFunction.CheckRoutineEndState(_vacuumRoutine); }, () => CheckRoutineStopStatus(_vacuumRoutine, "LS Vacuum On failed")) //8. LS Vacuum Level Check .Run(InstallStep.VacuumLevelCheck, () => { return _vacuumLevelCheckRoutine.Start(true) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.VacuumLevelCheckWait, () => { return CommonFunction.CheckRoutineEndState(_vacuumLevelCheckRoutine); }, () => CheckRoutineStopStatus(_vacuumLevelCheckRoutine, "LS Vacuum Level Check failed")) //9. Shuttle Goto LS .Run(InstallStep.ShuttleGotoLS, () => { return _shuttleAxis.PositionStation("LS", false); }, NullFun, _delay_1ms) .WaitWithStopCondition(InstallStep.ShuttleGotoLSWait, () => { return _shuttleAxis.Status == RState.End; }, () => { return _shuttleAxis.Status == RState.Failed; }) //10. LS Goto Lock .Run(InstallStep.LSGotoLock, () => { return _lsAxis.PositionStation($"Lock{_waferSize}", false, 0, 0, 0, false); }, NullFun, _delay_1ms) .WaitWithStopCondition(InstallStep.LSGotoLockWait, () => { return _lsAxis.Status == RState.End; }, () => { return _lsAxis.Status == RState.Failed; }) //11. Bernoulli N2 Off .Run(InstallStep.BernoulliN2Off, () => { return _bernoulliN2PressureRoutine.Start(false) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.BernoulliN2OffCheck, () => { return CommonFunction.CheckRoutineEndState(_bernoulliN2PressureRoutine); }, () => CheckRoutineStopStatus(_bernoulliN2PressureRoutine, " BernoulliN2 Off failed")) //12. WS Bladder Off .Run(InstallStep.WSBladderOff, () => { return _whBladderRoutine.Start(false) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.WSBladderOffCheck, () => { return CommonFunction.CheckRoutineEndState(_whBladderRoutine); }, () => CheckRoutineStopStatus(_whBladderRoutine, "WSBladder Off failed")) //13. Wait 0.5s for WS Bladder .Delay(InstallStep.Wait500MSForWSBladder, 500) //14. LS Vacuum Off .Run(InstallStep.LSVacuumOff, () => { return _vacuumRoutine.Start(false) == RState.Running; }, _delay_1ms) .WaitWithStopCondition(InstallStep.LSVacuumOffCheck, () => { return CommonFunction.CheckRoutineEndState(_vacuumRoutine); }, () => CheckRoutineStopStatus(_vacuumRoutine, "LS Vacuum Off failed")) //15. Wait 0.5s .Delay(InstallStep.Wait500MS, 500) //16. Shuttle Goto MID .Run(InstallStep.ShuttleGotoMID, () => { return _shuttleAxis.PositionStation("MID", false); }, NullFun, _delay_1ms) .WaitWithStopCondition(InstallStep.ShuttleGotoMIDWait, () => { return _shuttleAxis.Status == RState.End; }, () => { return _shuttleAxis.Status == RState.Failed; }) //17. Home LS Axis .Run(InstallStep.HomingLSAxis, () => { return _lsAxis.Home(); }, _delay_1ms) .WaitWithStopCondition(InstallStep.HomingLSAxisWait, () => { return _lsAxis.Status == RState.End; }, () => { return _lsAxis.Status == RState.Failed; }) .End(InstallStep.End, NullFun, 10); return Runner.Status; } /// /// 启动 /// /// /// /// public RState Start(params object[] objs) { if (SC.ContainsItem($"Loader1.{_side}WaferSize")) { _waferSize = SC.GetValue($"Loader1.{_side}WaferSize"); } _shuttleAxis = GetShuttleAxis(); _lsAxis = GetLsAxis(); _tiltAxis = GetTiltAxis(); _loaderCommonDevice = DEVICE.GetDevice($"{Module}.Common"); _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); _sideDevice = DEVICE.GetDevice($"{Module}.{_side}"); _vacuumRoutine = new LoaderSideVacuumRoutine($"{Module}.{_side}"); _vacuumLevelCheckRoutine = new LoaderSideVacuumLevelCheckRoutine($"{Module}.{_side}"); _whBladderRoutine = new LoaderSideWhBladderRoutine($"{Module}.{_side}"); _bernoulliBladderRoutine = new LoaderSideBernoulliBladderRoutine($"{Module}.{_side}"); _bernoulliN2PressureRoutine = new LoaderSideBernoulliN2PressureRoutine($"{Module}.{_side}"); Runner.Start(Module, "Install LS"); return RState.Running; } /// /// 检验Routine异常状态 /// /// private bool CheckRoutineStopStatus(IRoutine routine, string error) { bool result = CommonFunction.CheckRoutineStopState(routine); if (result) { NotifyError(eEvent.ERR_LOADER, $"{error}", 0); } return result; } /// /// 获取Shuttle轴对象 /// /// private JetAxisBase GetShuttleAxis() { switch (_side) { case "SideA": return DEVICE.GetDevice($"{Module}.ShuttleA"); default: return DEVICE.GetDevice($"{Module}.ShuttleB"); } } /// /// 获取CRS轴对象 /// /// private JetAxisBase GetLsAxis() { switch (_side) { case "SideA": return DEVICE.GetDevice($"{Module}.LSA"); default: return DEVICE.GetDevice($"{Module}.LSB"); } } /// /// 获取Tilt轴对象 /// /// private JetAxisBase GetTiltAxis() { switch (_side) { case "SideA": return DEVICE.GetDevice($"{Module}.TiltA"); default: return DEVICE.GetDevice($"{Module}.TiltB"); } } /// /// 检验前置条件 /// /// private bool CheckPreCondition() { if (!CheckHomeCondition()) { return false; } if (!CheckInstallCRSAxisCondition()) { return false; } if (!InstallCRSStatusCheck()) { return false; } return true; } /// /// 检验Home条件 /// /// private bool CheckHomeCondition() { //检验PUF、Loader Transporter,Robot均Homed //Efem Home if (ModuleHelper.IsInstalled(ModuleName.EFEM)) { EfemEntity efemEntity = Singleton.Instance.GetModule(ModuleName.EFEM.ToString()); if (!efemEntity.IsHomed) { LOG.WriteLog(eEvent.ERR_EFEM_ROBOT, Module, $"{ModuleName.EFEM.ToString()} is not home, Cannot execute GotoSavedPosition"); return false; } } if (ModuleHelper.IsInstalled(ModuleName.PUF1)) { PUFEntity puf1Entity = Singleton.Instance.GetModule(ModuleName.PUF1.ToString()); if (!puf1Entity.IsHomed) { NotifyError(eEvent.ERR_LOADER, "PUF1 is not homed", -1); return false; } } if (ModuleHelper.IsInstalled(ModuleName.Transporter2)) { TransporterEntity loaderTransportEntity = Singleton.Instance.GetModule(ModuleName.Transporter2.ToString()); if (!loaderTransportEntity.IsHomed) { NotifyError(eEvent.ERR_LOADER, "Loader Transporter is not homed", -1); return false; } } return true; } /// /// 检验Axis条件 /// /// /// private bool CheckInstallCRSAxisCondition() { if (!_rotationAxis.IsHomed) { NotifyError(eEvent.ERR_LOADER, $"Rotation is not homed", -1); return false; } if (!_shuttleAxis.IsHomed) { NotifyError(eEvent.ERR_LOADER, $"{_shuttleAxis.Name} is not homed", -1); return false; } if (!_tiltAxis.IsHomed) { NotifyError(eEvent.ERR_LOADER, $"{_tiltAxis.Name} is not homed", -1); return false; } if (!_lsAxis.IsHomed) { NotifyError(eEvent.ERR_LOADER, $"{_lsAxis.Name} is not homed", -1); return false; } //LS已经运动到 Setup 位 double crsPosition = _lsAxis.MotionData.MotorPosition; if (!_lsAxis.CheckPositionIsInStation(crsPosition, $"Setup{_waferSize}")) { NotifyError(eEvent.ERR_LOADER, $"LS {crsPosition} not in Setup{_waferSize}", -1); return false; } //Rotation已经运动到 loaderA 位(sideA 下片时)或 loaderB 位(sideB 下片时) double rotationPosition = _rotationAxis.MotionData.MotorPosition; if (_side == "SideA") { if (!_rotationAxis.CheckPositionIsInStation(rotationPosition, $"LOADA{_waferSize}")) { NotifyError(eEvent.ERR_LOADER, $"Rotation {rotationPosition} not in LOADA{_waferSize}", -1); return false; } } else { if (!_rotationAxis.CheckPositionIsInStation(rotationPosition, $"LOADB{_waferSize}")) { NotifyError(eEvent.ERR_LOADER, $"Rotation {rotationPosition} not in LOADB{_waferSize}", -1); return false; } } //Shuttle已经运动到除 IN 外任何位置 double shuttlePosition = _shuttleAxis.MotionData.MotorPosition; if (_shuttleAxis.CheckPositionIsInStation(shuttlePosition, "IN")) { NotifyError(eEvent.ERR_LOADER, $"Shuttle {shuttlePosition} is in IN", -1); return false; } return true; } /// /// 检验Status条件 /// /// /// private bool InstallCRSStatusCheck() { LoaderSideData sideData = _sideDevice.SideData; LoaderCommonData commonData = _loaderCommonDevice.CommonData; //Bernoulli Bladder(WS Bladder on) if (!sideData.BernoulliBladder) { NotifyError(eEvent.ERR_LOADER, "Bernoulli Bladder is off", -1); return false; } //Bernoulli N2(BernoulliN2 off) if (sideData.BernoulliN2) { NotifyError(eEvent.ERR_LOADER, "Bernoulli N2 is on", -1); return false; } //CRS Vacuum检验(Vacuum off) if (sideData.CRSVacuum) { LOG.WriteLog(eEvent.ERR_LOADER, Module, "LS Vacuum is on"); return false; } //Wafer Shuttle Present if (!commonData.WaferHolderPresent) { LOG.WriteLog(eEvent.ERR_LOADER, Module, "Wafer Shuttle is absent"); return false; } //WS Clamp On if (!commonData.WaferHolderClamp) { NotifyError(eEvent.ERR_LOADER, "Wafer Shuttle Clamp is off", -1); return false; } //WS Bladder off if (sideData.WHBladder) { LOG.WriteLog(eEvent.ERR_LOADER, Module, "WS Bladder is on"); return false; } //Drip Tray Fluid(正常) if (commonData.DripTrayFluid) { LOG.WriteLog(eEvent.ERR_LOADER, Module, "Drip Tray Fluid is on"); return false; } return true; } } }