using System; using System.Runtime.Remoting.Messaging; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using EFEM.RT.Devices.LoadPorts.JetOpenCst; using MECF.Framework.Common.Equipment; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots; namespace EFEM.RT.Routines { public class WaferMappingRoutine : CommonRoutine, IRoutine { private enum Mapping { CheckLoadPortReadyMap, CheckRobotMapInterlock, CheckRobotReadyMap, QueryRobotParameter, RobotServoOff, WaitRobotServoOff, SetWaferSizeParameter0000, SetWaferSizeParameter0114, RobotServoOn, WaitRobotServoOn, MapWafer, WaitMapping, GetWaferMap, } private bool MultiWaferSize = DeviceDefineManager.Instance.GetValue("MultiWaferSize") ?? false; private SCConfigItem _scPickTimeout = null; private int _timeout = 0; private LoadPortBaseDevice _lp; public bool IsDeviceNull => _lp == null; public WaferMappingRoutine() { Name = "Wafer Mapping"; _scPickTimeout = SC.GetConfigItem(SorterCommon.ScPathName.Robot_TimeLimitForPickWafer); } public bool Initalize() { return true; } public ModuleName Source { get; set; } private WaferSize _waferSize; public Result Start(params object[] objs) { Reset(); _timeout = SC.GetValue(SorterCommon.ScPathName.Robot_TimeLimitForPickWafer); Name = "Wafer Mapping"; Reset(); NeedSetParameter = true; string module = (string)objs[0]; ModuleName source; if (string.IsNullOrEmpty(module) || !Enum.TryParse(module, out source)) { LOG.Write("Start map wafer argument is not valid"); return Result.FAIL; } Source = source; if (ModuleHelper.IsLoadPort(Source)) { if (SC.GetValue($"LoadPort.{Source}.CstType") == 0) { _lp = DEVICE.GetDevice(Source.ToString()); _waferSize = _lp.GetCurrentWaferSize(); } else if (SC.GetValue($"LoadPort.{Source}.CstType") == 1) { _lp = DEVICE.GetDevice(Source.ToString()); _waferSize = _lp.GetCurrentWaferSize(); } else if (SC.GetValue($"LoadPort.{Source}.CstType") == 2) { _lp = DEVICE.GetDevice(Source.ToString()); _waferSize = _lp.GetCurrentWaferSize(); } } //if (_lp != null) //{ // var _lpOpen = _lp as OpenStageWithWaferSizeLoadPort; // _waferSize = _lpOpen.WaferSize; //} EV.PostMessage(ModuleName.System.ToString(), EventEnum.GeneralInfo, string.Format("Wafer Mapping {0} start.", Source.ToString())); return Result.RUN; } public Result Monitor() { try { if (ModuleHelper.IsLoadPort(Source)) CheckLoadPortReady((int)Mapping.CheckLoadPortReadyMap, _lp); if (DeviceDefineManager.Instance.GetValue("WAFSHEnable") == false) { CheckRobotReady((int)Mapping.CheckRobotReadyMap); //QueryRbParameterAndCompare0114((int)Mapping.QueryRobotParameter, "Query Robot parameters", 0114, "URS", _waferSize,_timeout, Notify, Stop); MapWafer((int)Mapping.MapWafer); WaitRobotMotion((int)Mapping.WaitMapping, robot, "Wait robot motion finish", _timeout, Notify, Stop); GetWaferMap((int)Mapping.GetWaferMap, "Get wafer Mapping", Source, _timeout, Notify, Stop); } else { GetWaferMap((int)Mapping.GetWaferMap, _lp, _timeout); } } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } EV.PostMessage(ModuleName.System.ToString(), EventEnum.GeneralInfo, string.Format("Wafer mapping {0} end.", Source.ToString())); return Result.DONE; } public void CheckLoadPortReady(int id, LoadPortBaseDevice device) { Tuple ret = Check(id, () => { Notify(String.Format("{0} check enable transfer", device.Name)); string reason = null; bool IsEnableMap = device.IsEnableMapWafer(out reason); if (!IsEnableMap) { EV.PostWarningLog(device.Name, $"{device.Name} can not maping,LP is not ready,{reason}. "); } return IsEnableMap; }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { Stop("Load Port not ready to map wafer"); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } public void CheckRobotReady(int id) { string reason = string.Empty; Tuple ret = Check(id, () => { Notify(String.Format("check robot ready map")); return CheckRobotMotionInterlock(out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { Stop(reason); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } protected override void Notify(string message) { EV.PostMessage(Module, EventEnum.GeneralInfo, String.Format("Wafer mapping:{0}", message)); } /// /// prepare process failed /// /// /// protected override void Stop(string failReason) { string reason = String.Empty; EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, string.Format("Wafer mapping {0} stopped, {1}", Source.ToString(), failReason)); } public void MapWafer(int id) { string reason = string.Empty; Tuple ret = Execute(id, () => { Notify(String.Format("Wafer Mapping for {0}", Source)); return robot.WaferMapping(Source, out reason); }); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { Stop(reason); throw (new RoutineFaildException()); } } } protected void GetWaferMap(int id, LoadPortBaseDevice device, int time) { Tuple ret = ExecuteAndWait(id, () => { Notify(String.Format("Query Mapping")); string reason = string.Empty; return device.QueryWaferMap(out reason); }, () => { 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 { Stop(String.Format("Query Mapping time out, using more than {0} seconds", time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } protected void GetWaferMap(int id, string name, ModuleName chamber, int time, Action notify, Action error) { Tuple ret = ExecuteAndWait(id, () => { notify(String.Format("Query Mapping")); string reason = string.Empty; return robot.QueryWaferMap(chamber, out reason); }, () => { if (robot.RobotState == RobotStateEnum.Idle) { 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("Query Mapping time out, using more than {0} seconds", time)); throw (new RoutineFaildException()); } else throw (new RoutineBreakException()); } } } }