using System.Threading; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.Event; using Aitex.Core.RT.IOCore; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; namespace EFEM.RT.Devices { public enum LoadLockDoorState { Opened, Closed, Unknown } public class LoadLockDevice : BaseDevice, IDevice { private IoSensor _sensorDoorOpen; private IoSensor _sensorArmExtendEnable; private IoTrigger _triggerSafetytoPM; private IoTrigger _triggerRBNotExtendPM; private static DOAccessor _openAtmDoorSignal; private static DOAccessor _closeAtmDoorSignal; private static DIAccessor _openAtmDoorFeedback; private static DIAccessor _closeAtmDoorFeedback; private static DOAccessor _openVtmDoorSignal; private static DOAccessor _closeVtmDoorSignal; private static DIAccessor _openVtmDoorFeedback; private static DIAccessor _closeVtmDoorFeedback; private bool _isDoorControledByStation; private static RD_TRIG atmDoorTrig = new RD_TRIG(); private static RD_TRIG vtmDoorTrig = new RD_TRIG(); private static LoadLockDoorState atmDoorState = LoadLockDoorState.Unknown; private static LoadLockDoorState vtmDoorState = LoadLockDoorState.Unknown; private static bool isIdle; public bool IsDoorOpen => !_sensorDoorOpen.Value && _sensorArmExtendEnable.Value; public static bool IsDoorOpenedByStation => _openAtmDoorFeedback.Value && !_closeAtmDoorFeedback.Value; public static bool IsDoorClosedByStation => _closeAtmDoorFeedback.Value && !_openAtmDoorFeedback.Value; public static bool IsOuterDoorOpenedByStation => _openVtmDoorFeedback.Value && !_closeVtmDoorFeedback.Value; public static bool IsOuterDoorClosedByStation => _closeVtmDoorFeedback.Value && !_openVtmDoorFeedback.Value; public static bool IsIdle => isIdle; private static bool isSimulator = SC.GetValue("System.IsSimulatorMode"); private static bool isDoorAlwaysOpen = SC.GetValue("System.IsLoadLockDoorAlwaysOpen"); public static RD_TRIG AtmDoorTrig { get { return atmDoorTrig; } } public static RD_TRIG VtmDoorTrig { get { return vtmDoorTrig; } } public static LoadLockDoorState LoadLockAtmDoorState { get { if(isDoorAlwaysOpen) { return LoadLockDoorState.Opened; } if(isSimulator) { if (_openAtmDoorSignal != null && _openAtmDoorSignal.Value && _closeAtmDoorSignal!= null && !_closeAtmDoorSignal.Value) { //Thread.Sleep(2000); return LoadLockDoorState.Opened; } if (_closeAtmDoorSignal != null && _closeAtmDoorSignal.Value && _openAtmDoorSignal != null && !_openAtmDoorSignal.Value) { //Thread.Sleep(2000); return LoadLockDoorState.Closed; } return LoadLockDoorState.Unknown; } else { if (_openAtmDoorFeedback != null && _openAtmDoorFeedback.Value && _closeAtmDoorFeedback != null && !_closeAtmDoorFeedback.Value) return LoadLockDoorState.Opened; if (_closeAtmDoorFeedback != null && _closeAtmDoorFeedback.Value && _openAtmDoorFeedback != null && !_openAtmDoorFeedback.Value) return LoadLockDoorState.Closed; return LoadLockDoorState.Unknown; } } } public static LoadLockDoorState LoadLockVtmDoorState { get { if (isDoorAlwaysOpen) { return LoadLockDoorState.Opened; } if (isSimulator) { if (_openVtmDoorSignal != null &&_openVtmDoorSignal.Value && _closeVtmDoorSignal != null && !_closeVtmDoorSignal.Value) { //Thread.Sleep(2000); return LoadLockDoorState.Opened; } if (_closeVtmDoorSignal != null && _closeVtmDoorSignal.Value && _openVtmDoorSignal != null && !_openVtmDoorSignal.Value) { //Thread.Sleep(2000); return LoadLockDoorState.Closed; } return LoadLockDoorState.Unknown; } else { if (_openVtmDoorFeedback != null && _openVtmDoorFeedback.Value && _closeVtmDoorFeedback != null && !_closeVtmDoorFeedback.Value) return LoadLockDoorState.Opened; if (_closeVtmDoorFeedback != null && _closeVtmDoorFeedback.Value && _openVtmDoorFeedback != null && !_openVtmDoorFeedback.Value) return LoadLockDoorState.Closed; return LoadLockDoorState.Unknown; } } } public LoadLockDevice(string module, string name, int slotNumber, IoSensor sensorDoorOpen, IoSensor sensorArmExtendEnable, DOAccessor openAtmDoorSignal, DOAccessor closeAtmDoorSignal, DIAccessor openAtmDoorFeedback, DIAccessor closeAtmDoorFeedback, DOAccessor openVtmDoorSignal,DOAccessor closeVtmDoorSignal, DIAccessor openVtmDoorFeedback, DIAccessor closeVtmDoorFeedback) { Module = module; Name = name; _sensorDoorOpen = sensorDoorOpen; _sensorArmExtendEnable = sensorArmExtendEnable; _openAtmDoorSignal = openAtmDoorSignal; _closeAtmDoorSignal = closeAtmDoorSignal; _openAtmDoorFeedback = openAtmDoorFeedback; _closeAtmDoorFeedback = closeAtmDoorFeedback; _openVtmDoorSignal = openVtmDoorSignal; _closeVtmDoorSignal = closeVtmDoorSignal; _openVtmDoorFeedback = openVtmDoorFeedback; _closeVtmDoorFeedback = closeVtmDoorFeedback; WaferManager.Instance.SubscribeLocation(name, slotNumber); _isDoorControledByStation = true; } public LoadLockDevice(string module, string name, int slotNumber, IoSensor sensorDoorOpen, IoSensor sensorArmExtendEnable,IoTrigger triggerSafetytoPM, IoTrigger triggerRBNotExtendPM) { Module = module; Name = name; _sensorDoorOpen = sensorDoorOpen; _sensorArmExtendEnable = sensorArmExtendEnable; _triggerRBNotExtendPM = triggerRBNotExtendPM; _triggerSafetytoPM = triggerSafetytoPM; WaferManager.Instance.SubscribeLocation(name, slotNumber); _isDoorControledByStation = false; // SafeytoPm(true); } public bool Initialize() { isIdle = true; DATA.Subscribe($"{Name}.WaferSize", () => WaferManager.Instance.GetWaferSize(ModuleHelper.Converter(Name), 0));//WaferManager.Instance.GetWafer(ModuleHelper.Converter(Name), 0).Size.ToString()); return true; } public void Monitor() { atmDoorTrig.CLK = LoadLockAtmDoorState == LoadLockDoorState.Closed; vtmDoorTrig.CLK = LoadLockVtmDoorState == LoadLockDoorState.Closed; if(atmDoorTrig.R || atmDoorTrig.T || vtmDoorTrig.R || vtmDoorTrig.T) { if ((DeviceDefineManager.Instance.GetValue("LLDoorControlByStation") ?? false) && Singleton.Instance.IsOnlineMode) { Singleton.Instance.SendSigStatEvent(ModuleName.LL1); } } } public void Terminate() { } public void Reset() { } public static bool OpenAtmDoor(out string reason) { isIdle = false; reason = string.Empty; EV.PostInfoLog("LoadLock",$"Open Atm Door"); if (_openAtmDoorSignal.Value && !_closeAtmDoorSignal.Value) { reason = "Atm door opened, can't open again"; isIdle = true; return true; } _closeAtmDoorSignal.SetValue(false, out _); _openAtmDoorSignal.SetValue(true, out _); isIdle = true; return true; } public static bool CloseAtmDoor(out string reason) { isIdle = false; reason = string.Empty; EV.PostInfoLog("LoadLock", "Close Atm Door"); if (_closeAtmDoorSignal.Value && !_openAtmDoorSignal.Value) { reason = "Atm door closed, can't open again"; isIdle = true; return true; } _openAtmDoorSignal.SetValue(false, out _); _closeAtmDoorSignal.SetValue(true, out _); isIdle = true; return true; } public static bool OpenVtmDoor(out string reason) { isIdle = false; reason = string.Empty; EV.PostInfoLog("LoadLock",$"Open Vtm Door"); if (_openVtmDoorSignal.Value && !_closeVtmDoorSignal.Value) { reason = "Vtm door opened, can't open again"; isIdle = true; return true; } _closeVtmDoorSignal.SetValue(false, out _); _openVtmDoorSignal.SetValue(true, out _); isIdle = true; return true; } public static bool CloseVtmDoor(out string reason) { isIdle = false; reason = string.Empty; EV.PostInfoLog("LoadLock", "Close Vtm Door"); if (_closeVtmDoorSignal.Value && !_openVtmDoorSignal.Value) { reason = "Vtm door closed, can't open again"; isIdle = true; return true; } _openVtmDoorSignal.SetValue(false, out _); _closeVtmDoorSignal.SetValue(true, out _); isIdle = true; return true; } public void SafeytoPm(bool value) { isIdle = false; EV.PostInfoLog("LoadLock", $"set SafeytoPm{value}"); _triggerSafetytoPM.SetTrigger(value,out _); isIdle = true; } public void NotExtendtoPm(bool value) { isIdle = false; EV.PostInfoLog("LoadLock", $"set NotExtendtoPm {value}"); _triggerSafetytoPM.SetTrigger(value, out _); isIdle = true; } public bool IsEnableTransferWafer(out string reason) { reason = string.Empty; if (_isDoorControledByStation) { return LoadLockAtmDoorState == LoadLockDoorState.Opened; } else { if(!isDoorAlwaysOpen) { if ((_sensorDoorOpen != null && !_sensorDoorOpen.Value)) //|| (_sensorArmExtendEnable != null && !_sensorArmExtendEnable.Value)) { reason = $"{Name} is not ready for transfer"; return false; } } } reason = ""; return true; } } }