using Aitex.Core.Common; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using EFEM.RT.Devices; using EFEMSC; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase; using System; namespace EFEM.RT.Routines { public class InitRoutine : CommonRoutine, IRoutine, IEfemRoutine { private enum Home { DeviceReset, FfuStart1, FfuStart2, RobotClear, RobotInit, WaitingRobotInit, RobotHome, WaitingRobotHome, RobotSet, AlignClear, AlignerInit, WaitingAlignerInit, AlignerHome, WaitingAlignerHome, AlignerMoveUp, WaitingAlignerUp, Coolingbuffer1Home, Coolingbuffer2Home, Aligner1Home, Aligner2Home, AxisClearAlarm, AxisServon, AxisServonDelay, AxisSetConfig, AxisSetConfigDelay, AxisHome, CloseAtmShutterDoor, CloseVtmShutterDoor, LoadportAClear, LoadportAHome, WaitingLoadportAHome, LoadportBClear, LoadportBHome, WaitingLoadportBHome, LoadportCClear, LoadportCHome, WaitingLoadportCHome, LoadportDClear, LoadportDHome, WaitingLoadportDHome, LoadportEClear, LoadportEHome, WaitingLoadportEHome, LoadportFClear, LoadportFHome, WaitingLoadportFHome, LoadportGClear, LoadportGHome, WaitingLoadportGHome, LoadportHClear, LoadportHHome, WaitingLoadportHHome, LoadportIClear, LoadportIHome, WaitingLoadportIHome, LoadportJClear, LoadportJHome, WaitingLoadportJHome, LoadportAllReset, LoadportAllInit, RobotBlade1Grip, RobotBlade1ConfirmWafer, RobotBlade1Release, CheckWaferPrecense, CheckBlade1WaferPrecense, CheckBlade1WaferPrecenseWait, CheckBlade2WaferPrecense, CheckBlade2WaferPrecenseWait, RobotBlade2Grip, RobotBlade2ConfirmWafer, RobotBlade2Release, QuerySignalStatus, RobotBlade1Hold, RobotBlade2Hold, FlipperHome } private SetSpeedRoutine RbSetRoutine = null; private bool _scanBuffer = true; private SCConfigItem _scRobotHomeTimeout = null; private int _scFfuSpeed; private int _timeoutRobot = 0; private int _timeoutBuffer = 0; public InitRoutine(string module, string name) { Module = module; Name = name; RbSetRoutine = new SetSpeedRoutine(module, name); } public bool Initalize() { RbSetRoutine.Initalize(); _scRobotHomeTimeout = SC.GetConfigItem(SorterCommon.ScPathName.Robot_TimeLimitRobotHome); IsStopped = true; return true; } public void Terminate() { RbSetRoutine.Terminate(); } public Result Start(params object[] objs) { Name = "Init"; Reset(); _timeoutRobot = _scRobotHomeTimeout.IntValue; _timeoutBuffer = SC.GetValue(ScPathName.Coolbuffer_DownTimeout); RbSetRoutine.Speed = SC.GetValue(SorterCommon.ScPathName.Robot_RobotSpeed); if (DeviceDefineManager.Instance.GetValue("FfuMemoBusControl") ?? false) { _scFfuSpeed = SC.GetValue("System.FFUSetSpeed"); } EV.PostMessage(ModuleName.System.ToString(), EventEnum.HomeBegins, ModuleName.System.ToString()); robot = DEVICE.GetDevice(DeviceName.Robot); _scanBuffer = true; WaferSensorResetCreate(); IsStopped = false; return Result.RUN; } public Result Monitor() { if (IsStopped) return Result.DONE; try { DeviceReset((int)Home.DeviceReset, "Device Reset", 1, Notify, Stop); if (DeviceDefineManager.Instance.GetValue("FfuMemoBusControl") ?? false) { FfuSpeedSet((int)Home.FfuStart1, "FFU1", _scFfuSpeed, _timeoutRobot, Notify, Stop); FfuSpeedSet((int)Home.FfuStart2, "FFU2", _scFfuSpeed, _timeoutRobot, Notify, Stop); } RobotReset((int)Home.RobotClear, robot, "Robot reset", _timeoutRobot, Notify, Stop); RobotHome((int)Home.RobotHome, robot, "Robot home", Notify, Stop); WaitRobotMotion((int)Home.WaitingRobotHome, robot, "Robot homing...", _timeoutRobot, Notify, Stop); //GripRobotBlade((int)Home.RobotBlade1Hold, Hand.Blade1, robot, _timeoutRobot); //GripRobotBlade((int)Home.RobotBlade2Hold, Hand.Blade2, robot, _timeoutRobot); CheckBladeWaferIsExist((int)Home.CheckBlade1WaferPrecense, robot, Hand.Blade1, _timeoutRobot); WaitRobotMotion((int)Home.CheckBlade1WaferPrecenseWait, robot, "wait check blade1", _timeoutRobot, Notify, Stop); CheckBladeWaferIsExist((int)Home.CheckBlade2WaferPrecense, robot, Hand.Blade2, _timeoutRobot); WaitRobotMotion((int)Home.CheckBlade2WaferPrecenseWait, robot, "wait check blade2", _timeoutRobot, Notify, Stop); ConfirmRobotBladeWafer((int)Home.RobotBlade1ConfirmWafer, Hand.Blade1); ConfirmRobotBladeWafer((int)Home.RobotBlade2ConfirmWafer, Hand.Blade2); // if (NeedRobotGripAndUngrip) { HomeGripAndUngripRobotBlade((int)Home.RobotBlade1Grip, Hand.Blade1, robot, _timeoutRobot); HomeGripAndUngripRobotBlade((int)Home.RobotBlade2Grip, Hand.Blade2, robot, _timeoutRobot); } // //CheckRobotBladeWaferPrecense((int)Home.CheckWaferPrecense, robot, _timeoutRobot); //// RobotSignalStatus((int)Home.QuerySignalStatus, robot, _timeoutRobot); //HomeReleaseRobotBlade((int)Home.RobotBlade1Release, Hand.Blade1, robot, _timeoutRobot); //HomeReleaseRobotBlade((int)Home.RobotBlade2Release, Hand.Blade2, robot, _timeoutRobot); if (DeviceDefineManager.Instance.GetValue("CoolingBufferInstalled") ?? false) { if (!SC.GetValue("System.CoolingBuffer1Disable")) CooingbufferHome((int)Home.Coolingbuffer1Home, buffer1, "Cooling buffer1 moving down", _timeoutBuffer, Notify, Stop); if (!SC.GetValue("System.CoolingBuffer2Disable")) CooingbufferHome((int)Home.Coolingbuffer2Home, buffer2, "Cooling buffer2 moving down", _timeoutBuffer, Notify, Stop); if (!SC.GetValue("System.Aligner1Disable") && SC.ContainsItem("Aligner.AlignerType") && SC.GetValue("Aligner.AlignerType") == 1) CooingbufferHome((int)Home.Aligner1Home, aligner1, "Aligner1 moving down", _timeoutBuffer, Notify, Stop); if (!SC.GetValue("System.Aligner2Disable") && SC.ContainsItem("Aligner.AlignerType") && SC.GetValue("Aligner.AlignerType") == 1) CooingbufferHome((int)Home.Aligner2Home, aligner2, "Aligner2 moving down", _timeoutBuffer, Notify, Stop); } if (!SC.GetValue("System.FlipperDisable")) { FlipperHome((int)Home.FlipperHome, GetFlipper(), "Flipper Home...", _timeoutBuffer, Notify, Stop); } //if (LoadLockDoorControlByStation) //{ // LoadLockCloseAtmDoor((int)Home.CloseAtmShutterDoor, DEVICE.GetDevice(ModuleName.LL1.ToString()), "Wait Atm Door Close", _timeoutRobot, Notify, Stop); // LoadLockCloseVtmDoor((int)Home.CloseVtmShutterDoor, DEVICE.GetDevice(ModuleName.LL1.ToString()), "Wait Vtm Door Close", _timeoutRobot, Notify, Stop); //} //if (initIndex < LoadPortQuantity) //{ // LoadportReset((int)Home.LoadportAClear + initIndex * 3, DEVICE.GetDevice($"LP{initIndex + 1}"), $"LP{initIndex + 1} reset", _timeoutRobot, Notify, Stop); // initIndex++; // return Result.RUN; //} LoadportAllReset((int)Home.LoadportAllReset, _timeoutRobot); LoadportAllInit((int)Home.LoadportAllInit, _timeoutRobot); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { IsStopped = true; return Result.FAIL; } EV.PostMessage(ModuleName.System.ToString(), EventEnum.HomeEnds, ModuleName.System.ToString()); IsStopped = true; return Result.DONE; } public void FfuSpeedSet(int id, string name, int speed, int time, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, () => { var device = DEVICE.GetDevice(name); notify($"{device.Name} start and set speed"); string reason = string.Empty; device.StartAndSetSpeed(speed); return true; }, () => { var device = DEVICE.GetDevice(name); switch (device.Name) { case "FFU1": if (Ffu.SpeedSet1) { notify($"{device.Name} is running"); return true; } break; case "FFU2": if (Ffu.SpeedSet2) { notify($"{device.Name} is running"); return true; } break; } return false; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { error(String.Format("{0} timeout, than {1} seconds", name, time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } protected void WaitRobotSet(int id, string name, IRoutine routines, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, routines); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { error(name); throw (new RoutineFaildException()); } else if (ret.Item2 == Result.RUN) { throw (new RoutineBreakException()); } } } protected void DeviceReset(int id, string name, int time, Action notify, Action error) { Tuple ret = Delay(id, () => { notify(String.Format("Device reset")); Singleton.Instance.PostMsg(DeviceEntity.MSG.RESET); return true; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.RUN) { throw (new RoutineBreakException()); } } } #region aligner public void AlignerReset(int id, Aligner device, string name, int time, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, () => { notify(String.Format("{0} clear error", device.Name)); string reason = string.Empty; return device.Clear(out reason); }, () => { if (device.Busy == false) { return true; } return false; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { error(String.Format("{0} timeout, than {1} seconds", name, time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } public void AlignerInit(int id, Aligner device, string name, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("{0} Home", device.Name)); string reason = string.Empty; return device.Init(out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } public void AlignerHome(int id, Aligner device, string name, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("{0} Home", device.Name)); string reason = string.Empty; return device.Home(out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } public void AlignerMoveUp(int id, Aligner device, string name, Action notify, Action error) { Tuple ret = Execute(id, () => { notify(String.Format("{0} Lift up", device.Name)); string reason = string.Empty; return device.LiftUp(out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } } } #endregion aligner #region Loadport ///等待 Loadport public void QueryLoadportState(int id, LoadPort device, string name, int time, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, () => { notify(String.Format("{0} query state", device.Name)); string reason = string.Empty; device.QueryState(out reason); return true; }, () => { if (!device.IsBusy) { return true; } return false; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { error(String.Format("{0} query timeout, than {1} seconds", name, time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } #endregion Loadport private void WaferSensorResetCreate() { if (!_scanBuffer) return; //var sensors = new List //{ // DeviceModel.SensorCoolingStageSLOT1WaferON != null ? DeviceModel.SensorCoolingStageSLOT1WaferON.Value : true, // DeviceModel.SensorCoolingStageSLOT2WaferON != null ? DeviceModel.SensorCoolingStageSLOT2WaferON.Value : true, // DeviceModel.SensorCoolingStageSLOT3WaferON != null ? DeviceModel.SensorCoolingStageSLOT3WaferON.Value : true, // DeviceModel.SensorCoolingStageSLOT4WaferON != null ? DeviceModel.SensorCoolingStageSLOT4WaferON.Value : true, // DeviceModel.SensorCoolingStageSLOT5WaferON != null ? DeviceModel.SensorCoolingStageSLOT5WaferON.Value : true, // DeviceModel.SensorCoolingStageSLOT6WaferON != null ? DeviceModel.SensorCoolingStageSLOT6WaferON.Value : true, //}; var index = 0; //foreach (var sensor in sensors) //{ // if (!sensor && WaferManager.Instance.CheckNoWafer(ModuleName.CoolingBuffer1, index)) // { // WaferManager.Instance.CreateWafer(ModuleName.CoolingBuffer1, index, WaferStatus.Normal); // } // else if (sensor && WaferManager.Instance.CheckHasWafer(ModuleName.CoolingBuffer1, index)) // { // WaferManager.Instance.DeleteWafer(ModuleName.CoolingBuffer1, index); // } // if (!sensor && WaferManager.Instance.CheckNoWafer(ModuleName.CoolingBuffer2, index)) // { // WaferManager.Instance.CreateWafer(ModuleName.CoolingBuffer2, index, WaferStatus.Normal); // } // else if (sensor && WaferManager.Instance.CheckHasWafer(ModuleName.CoolingBuffer2, index)) // { // WaferManager.Instance.DeleteWafer(ModuleName.CoolingBuffer2, index); // } // index++; //} //var robotSensors = new List //{ // DeviceModel.SensorRBlowerArmhavewafer != null ? DeviceModel.SensorRBlowerArmhavewafer.Value : true, // DeviceModel.SensorRBupperArmhavewafer != null ? DeviceModel.SensorRBupperArmhavewafer.Value : true, //}; //index = 0; //foreach (var sensor in robotSensors) //{ // if (!sensor && WaferManager.Instance.CheckNoWafer(ModuleName.Robot, index)) // { // WaferManager.Instance.CreateWafer(ModuleName.Robot, index, WaferStatus.Normal); // } // else if (sensor && WaferManager.Instance.CheckHasWafer(ModuleName.Robot, index)) // { // WaferManager.Instance.DeleteWafer(ModuleName.Robot, index); // } // index++; //} if (DeviceModel.SensorPreAlignerWaferOn != null && !DeviceModel.SensorPreAlignerWaferOn.Value && WaferManager.Instance.CheckNoWafer(ModuleName.Aligner, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Aligner, 0, WaferStatus.Normal); } else { if (DeviceDefineManager.Instance.GetValue("AlignerInstalled") ?? false) WaferManager.Instance.DeleteWafer(ModuleName.Aligner, 0); //if (SC.ContainsItem("System.Aligner1Disable") ? !SC.GetValue("System.Aligner1Disable") : false) // WaferManager.Instance.DeleteWafer(ModuleName.Aligner1, 0); //if (SC.ContainsItem("System.Aligner2Disable") ? !SC.GetValue("System.Aligner2Disable") : false) // WaferManager.Instance.DeleteWafer(ModuleName.Aligner2, 0); } //var loadLockQuantity = DeviceDefineManager.Instance.GetValue("LoadLockQuantity") ?? 0; //if (loadLockQuantity > 0 && Singleton.Instance.IsOnlineMode) //{ // for (int i = 1; i <= loadLockQuantity; i++) // { // var moduleName = ModuleHelper.Converter($"LL{i}"); // if (WaferManager.Instance.CheckHasWafer(moduleName, 0)) // { // WaferManager.Instance.DeleteWafer(moduleName, 0); // } // } //} _scanBuffer = false; } public void CooingbufferHome(int id, IoCoolingBuffer device, string name, int time, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, () => { if (device == null) { EV.PostAlarmLog("System", String.Format("{0} Device is Null", name)); return false; } if (SC.GetValue($"System.{device.Name}Disable")) { EV.PostInfoLog("System", String.Format("{0} is Disable", device.Name)); return true; } notify(String.Format("{0} {1}", device.Name, name)); string reason = string.Empty; return device.Home(out reason); }, () => { if (SC.GetValue($"System.{device.Name}Disable")) { //EV.PostInfoLog("System", String.Format("{0} is Disable", device.Name)); return true; } if (device.Error == true) { return null; } return device.CheckMovedDown() && !device.Busy; }, time * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw (new RoutineFaildException()); } else if (ret.Item2 == Result.TIMEOUT) //timeout { error(String.Format("{0} timeout, than {1} seconds", name, time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } protected override void Notify(string message) { EV.PostMessage(Module, EventEnum.GeneralInfo, String.Format("Home sequence :{0}", message)); } /// /// prepare process failed /// /// /// protected override void Stop(string failReason) { string reason = String.Empty; EV.PostMessage(Module, EventEnum.HomeFailed, failReason); } } }