using System; using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device.Devices; using Aitex.Core.RT.Device.Unit; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts { public class OpenStageWithWaferSizeLoadPort : LoadPort { public override bool IsWaferProtrude { get { return !_sensorWaferNotProtrude.Value; } } public WaferSize WaferSize { get { return _sizeDetector.Value; } } private IoWaferSizeDetector _sizeDetector; private IoSensor _sensorWaferNotProtrude; private RD_TRIG _trigPresentAbsent = new RD_TRIG(); private RD_TRIG _trigPresentAbsentDely = new RD_TRIG(); private F_TRIG _trigWaferProtrude = new F_TRIG(); DeviceTimer _deviceTimer = new DeviceTimer(); private int _queryPeriod = 0; //ms private bool _isStillThere = false; public override bool IsBusy { get; set; } public override LoadportCassetteState CassetteState { get { if (_sizeDetector.NotPresent3 && _sizeDetector.NotPresent4 && _sizeDetector.NotPresent6) { return LoadportCassetteState.Absent; } if (_sensorWaferNotProtrude.Value) { return LoadportCassetteState.Normal; } return LoadportCassetteState.Unknown; } } public void SetPrensentAbsentDelay(int ms) { _queryPeriod = ms; } /// /// /// /// /// /// /// public OpenStageWithWaferSizeLoadPort(string module, string name, IoWaferSizeDetector sensorPresent, IoSensor sensorWaferNotProtrude) : base( module, name) { if (string.IsNullOrEmpty(name)) throw new ArgumentException("name cannot be null or empty", "name"); _sizeDetector = sensorPresent ?? throw new ArgumentException("prensent sensor can not be null", "sensorPresent"); _sensorWaferNotProtrude = sensorWaferNotProtrude ?? throw new ArgumentException("protrude sensor cannot be null", "sensorWaferNotProtrude"); IsMapWaferByLoadPort = false; PortType = EnumLoadPortType.OpenStageWithWaferSize; Initalized = true; } public override bool Initialize() { DATA.Subscribe(Name, "IsWaferNotProtrude", () => _sensorWaferNotProtrude.Value); DATA.Subscribe(Name, "IsNotPresent3", () => _sizeDetector.NotPresent3); DATA.Subscribe(Name, "IsNotPresent4", () => _sizeDetector.NotPresent4); DATA.Subscribe(Name, "IsNotPresent6", () => _sizeDetector.NotPresent6); //DATA.Subscribe(Name, "CassetteState", () => CassetteState.ToString()); DATA.Subscribe(Name, "WaferSize", () => _sizeDetector.Value.ToString()); if (SC.ContainsItem("LoadPort.TimeDelayNotifyCassettePresent")) { _queryPeriod = SC.GetValue("LoadPort.TimeDelayNotifyCassettePresent"); } return base.Initialize(); } public override void Monitor() { base.Monitor(); //place foup _trigPresentAbsent.CLK = _sizeDetector.HasCassette; if (_queryPeriod == 0) { if (_trigPresentAbsent.R) { SetPlaced(true); SetPresent(true); } //remove foup if (_trigPresentAbsent.T) { SetPlaced(false); SetPresent(false); } } else { if (_trigPresentAbsent.R) { _deviceTimer.Start(_queryPeriod); } if (_sizeDetector.HasCassette && _deviceTimer.IsTimeout() && !_isStillThere) { SetPlaced(true); SetPresent(true); _isStillThere = true; _deviceTimer.Stop(); } //remove foup if (_trigPresentAbsent.T) { _deviceTimer.Start(_queryPeriod); } if (!_sizeDetector.HasCassette && _deviceTimer.IsTimeout() && _isStillThere) { SetPlaced(false); SetPresent(false); _isStillThere = false; _deviceTimer.Stop(); } } } public override void Reset() { base.Reset(); _trigWaferProtrude.RST = true; } public override bool IsEnableMapWafer() { return _sizeDetector.HasCassette && _sensorWaferNotProtrude.Value; } public override bool IsEnableTransferWafer() { return IsEnableTransferWafer(out _); } public override bool IsEnableTransferWafer(out string reason) { if (!_sizeDetector.HasCassette) { reason = "no FOUP placed"; return false; } if (_sensorWaferNotProtrude.Value == false) { reason = "Found wafer protrude"; return false; } if (!_isMapped) { reason = "FOUP not mapped"; return false; } reason = ""; return true; } public override bool Unload(out string reason) { reason = ""; _isMapped = false; OnUnloaded(); return true; } } }