using Aitex.Core.Common; 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.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using Aitex.Sorter.Common; using FabConnect.SecsGemInterface.Common.ToolModel; using FACore.E87FA; using FurnaceRT.Equipments.LPs; using FurnaceRT.Equipments.PMs; using FurnaceRT.Equipments.Systems; using log4net.Repository.Hierarchy; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using MECF.Framework.FA.Core.E87FA; using MECF.Framework.FA.Core.FAControl; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.CarrierIdReaders.CarrierIDReaderBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Xml; using static Aitex.Core.RT.Device.Unit.IOE84Passive; using static MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase.LoadPortBaseDevice; namespace FurnaceRT.Devices { public class IoLP : BaseDevice, IDevice, ILoadPort { private DIAccessor _diLeftClamp; private DIAccessor _diRightClamp; private DIAccessor _diLeftRelease; private DIAccessor _diRightRelease; private DIAccessor _diInPosition1; private DIAccessor _diInPosition2; private DIAccessor _diInPosition3; private DIAccessor _diDetect; private DOAccessor _doClamp; private DOAccessor _doRelease; private DOAccessor _doPresenceLight; private DOAccessor _doPlacementLight; private DOAccessor _doLoadLight; private DOAccessor _doUnloadLight; private DOAccessor _doManualLight; private IoSensor _foupPresentSensor; private bool _isSimulatorMode; private string _previousAccessMode = ""; public bool IsFoupPresent { get { if (_isSimulatorMode) return CarrierManager.Instance.CheckHasCarrier(LPModuleName.ToString(), 0); if (_diInPosition1 != null && _diInPosition2 != null && _diInPosition3 != null && _doPresenceLight != null) { // _doPresenceLight.Value = _diInPosition1.Value && _diInPosition2.Value && _diInPosition3.Value; _doPlacementLight.Value = _diInPosition1.Value && _diInPosition2.Value && _diInPosition3.Value; } if (_diInPosition1 != null && _diInPosition2 != null && _diInPosition3 != null && _diDetect != null && _doPlacementLight != null) { // _doPlacementLight.Value = _diDetect.Value && _diInPosition1.Value && _diInPosition2.Value && _diInPosition3.Value; _doPresenceLight.Value = _diDetect.Value; } if (_diInPosition1 != null && _diInPosition2 != null && _diInPosition3 != null && _diDetect != null) return _diInPosition1.Value && _diInPosition2.Value && _diInPosition3.Value && _diDetect.Value; return false; } } public DeviceStatus Status { get { if (_diLeftClamp != null && _diRightClamp != null && _diLeftRelease != null && _diRightRelease != null && _diLeftClamp.Value && _diRightClamp.Value && !_diLeftRelease.Value && !_diRightRelease.Value) return DeviceStatus.Clamp; if (_diLeftClamp != null && _diRightClamp != null && _diLeftRelease != null && _diRightRelease != null && !_diLeftClamp.Value && !_diRightClamp.Value && _diLeftRelease.Value && _diRightRelease.Value) return DeviceStatus.Release; return DeviceStatus.Unknown; } } public CarrierInfo CurrentCarrier { get { return CarrierManager.Instance.GetCarrier(Name); } } public bool ReadIDReady { get; set; } = true; private E84Passiver _e84; public RD_TRIG _trtbtrg = new RD_TRIG(); public R_TRIG _cstAddtrg = new R_TRIG(); public R_TRIG _cstRemovetrg = new R_TRIG(); public bool IsLoadCompleted { get; set; } public bool IsUnloadCompleted { get; set; } public bool IsInitCompleted { get; set; } public CarrierOnLPState m_CarrierOnState { get; set; } = CarrierOnLPState.Unknow; public IoLP(string module, XmlElement node, string ioModule = "") { base.Module = string.IsNullOrEmpty(node.GetAttribute("module")) ? module : node.GetAttribute("module"); base.Name = node.GetAttribute("id"); base.Display = node.GetAttribute("display"); base.DeviceID = node.GetAttribute("schematicId"); LPModuleName = (ModuleName)Enum.Parse(typeof(ModuleName), Name); _diLeftClamp = ParseDiNode("diLeftClamp", node, ioModule); _diRightClamp = ParseDiNode("diRightClamp", node, ioModule); _diLeftRelease = ParseDiNode("diLeftRelease", node, ioModule); _diRightRelease = ParseDiNode("diRightRelease", node, ioModule); _diInPosition1 = ParseDiNode("diInPosition1", node, ioModule); _diInPosition2 = ParseDiNode("diInPosition2", node, ioModule); _diInPosition3 = ParseDiNode("diInPosition3", node, ioModule); _diDetect = ParseDiNode("diDetect", node, ioModule); _doClamp = ParseDoNode("doClamp", node, ioModule); _doRelease = ParseDoNode("doRelease", node, ioModule); _doPresenceLight = ParseDoNode("doPresence", node, ioModule); _doPlacementLight = ParseDoNode("doPlacement", node, ioModule); _doLoadLight = ParseDoNode("doLoad", node, ioModule); _doUnloadLight = ParseDoNode("doUnload", node, ioModule); _doManualLight = ParseDoNode("doManual", node, ioModule); } public bool Initialize() { _isSimulatorMode = SC.GetValue("System.IsSimulatorMode"); DATA.Subscribe($"{Module}.{Name}.UIFoupSensor", () => GetUIFoupSensor(), SubscriptionAttribute.FLAG.IgnoreSaveDB); DATA.Subscribe($"{Name}.DeviceStatus", () => Status.ToString()); var foupSensorID = Name == "LP1" ? "17" : "18"; if (SC.GetStringValue("LoadPort.LoadPortPosition") == "Upper") { foupSensorID += "A"; } _foupPresentSensor = DEVICE.GetDevice($"System.SensorStation{foupSensorID}Presence"); OP.Subscribe($"{Module}.{Name}.SetClamp", (string cmd, object[] param) => { Clamp(out string reason); return true; }); OP.Subscribe($"{Module}.{Name}.SetRelease", (string cmd, object[] param) => { Unclamp(out string reason); return true; }); SubscribeDataVariable(); SubscribeAlarm(); return true; } public void Monitor() { var accessMode = DATA.Poll($"{Name}.AccessMode"); if (accessMode != null) { if (accessMode.ToString().ToUpper() == "AUTO") { //auto时候,默认是夹紧状态 if (!_doClamp.Value && _previousAccessMode != accessMode.ToString()) { Clamp(out _); } } if (accessMode.ToString().ToUpper() == "MANUAL") { ///1.manual模式,如果没有foup,不夹紧 //2.manual模式,如果有foup,同时有load job,要夹紧,取走之后,不夹紧 if (!IsFoupPresent /*&& !_doRelease.Value*/ && _previousAccessMode != accessMode.ToString()) { Unclamp(out _); } } _previousAccessMode = accessMode.ToString(); } if (ModuleHelper.IsLoadPort(ModuleHelper.Converter(Name))) { var lpFoupInfo = CarrierManager.Instance.GetCarrier(Name); if (lpFoupInfo != null) { SetVisibility(lpFoupInfo, !lpFoupInfo.IsEmpty); Singleton.Instance.SetUIWaferCount(lpFoupInfo, ModuleHelper.Converter(Name), out var wafers); } } if (_e84 == null) _e84 = DEVICE.GetDevice($"{Name}.Loadport{Name.Replace("LP", "")}E84"); //RecordSignalChange(); //MonitorIndicator(); MonitorCSTADD(); if (!SC.GetValue("System.IsSimulatorMode")) { MonitorCSTRemove(); } } public void MonitorCSTRemove() { _cstRemovetrg.CLK = !IsFoupPresent; if (!CurrentCarrier.IsEmpty || SC.GetValue("System.IsSimulatorMode")) { if (_cstRemovetrg.Q) { if (IsUnloadCompleted) { ConfirmRemoveCarrier(); } else if (IsLoadCompleted) { _carrierId = ""; } } } } protected virtual void ConfirmRemoveCarrier() { _isPlaced = false; //IsComplete = false; _isMapped = false; //if (m_CarrierOnState != CarrierOnLPState.Off) { if (m_CarrierOnState == CarrierOnLPState.On) { //if (_lpE84Callback != null && IsAccessAuto) //{ // if (_lpE84Callback.GetCurrentE84State() != E84State.Busy || // !_lpE84Callback.GetE84SignalState(E84SignalID.VALID)) // { // OnError("Unexpected carrier removed on access auto"); // } //} } WaferManager.Instance.DeleteWafer(ModuleHelper.Converter(Name), 0, 25); //for (int i = 0; i < 25; i++) //{ // WaferManager.Instance.DeleteWafer(ModuleHelper.Converter(Name), 0, 25); //} var removeCarrierID = _carrierId; if (CarrierManager.Instance.CheckHasCarrier(Name, 0)) removeCarrierID = CarrierManager.Instance.GetCarrier(Name, 0).CarrierId; m_CarrierOnState = CarrierOnLPState.Off; SerializableDictionary dvid = new SerializableDictionary(); FaLoadPort faLoadPort = FALoadPortManager.Instance.GetLoadPort(PortID); // No_state = 0, //Manual, //Auto, if (faLoadPort != null && faLoadPort.GetAccessMode() == 1) Singleton.Instance.Eqp_NoteCarrierRemoved(PortID, true); else Singleton.Instance.Eqp_NoteCarrierRemoved(PortID, false); dvid["PortID"] = PortID; dvid["PORT_CTGRY"] = SpecPortName; dvid["CarrierType"] = SpecCarrierType; dvid["CarrierIndex"] = InfoPadCarrierIndex; //dvid["InfoPadSensorIndex"] = InfoPadSensorIndex; dvid["CarrierID"] = removeCarrierID ?? ""; dvid["CAR_ID"] = removeCarrierID ?? ""; EV.Notify(EventCarrierRemoved, dvid); //EV.Notify(EventCarrierRemoved1, dvid); CarrierManager.Instance.DeleteCarrier(Name); if (_lpcallback != null) _lpcallback.CarrerRemove(removeCarrierID); EV.PostInfoLog("LoadPort", $"{LPModuleName} carrier:{removeCarrierID} was removed."); _carrierId = ""; } } public void MonitorCSTADD() { _cstAddtrg.CLK = IsFoupPresent; _trtbtrg.CLK = IsUnloadCompleted; if (IsUnloadCompleted) { FaLoadPort faLoadPort = FALoadPortManager.Instance.GetLoadPort(PortID); if (faLoadPort != null) { // No_state = 0, //Manual, //Auto, if (!IsFoupPresent && _trtbtrg.R) { if (faLoadPort.LoadPortTransferStateMachine.TransferState != FACore.E87FA.LPTransferState.OUT_OF_SERVICE && faLoadPort.LoadPortTransferStateMachine.TransferState != FACore.E87FA.LPTransferState.READY_TO_LOAD) { FALoadPortManager.Instance.EqpInformLoadPortTransferReady(PortID, IsFoupPresent); } } if (_trtbtrg.R && IsFoupPresent) { if (faLoadPort.LoadPortTransferStateMachine.TransferState != FACore.E87FA.LPTransferState.OUT_OF_SERVICE && faLoadPort.LoadPortTransferStateMachine.TransferState != FACore.E87FA.LPTransferState.READY_TO_UNLOAD) { FALoadPortManager.Instance.EqpInformLoadPortTransferReady(PortID, IsFoupPresent); } } } } else if (!IsUnloadCompleted) { FaLoadPort faLoadPort = FALoadPortManager.Instance.GetLoadPort(PortID); if (faLoadPort != null) { if (faLoadPort.LoadPortTransferStateMachine.TransferState != FACore.E87FA.LPTransferState.OUT_OF_SERVICE && faLoadPort.LoadPortTransferStateMachine.TransferState != FACore.E87FA.LPTransferState.TRANSFER_BLOCKED) { FALoadPortManager.Instance.EqpInformLoadPortTransferBlock(PortID); } } } if (_cstAddtrg.Q && IsUnloadCompleted) { if (!Singleton.Instance.IsAutoMode && !Singleton.Instance.IsReturnWaferMode) { if (!CarrierManager.Instance.CheckHasCarrier(Name, 0)) { CarrierManager.Instance.CreateCarrier(Name, CarrierType.SD, Name); } } ConfirmAddCarrier(); } } protected virtual void ConfirmAddCarrier() { _isPlaced = true; //IsComplete = false; //if (m_CarrierOnState != CarrierOnLPState.On) { if (m_CarrierOnState == CarrierOnLPState.Off) { //if (_lpE84Callback != null && IsAccessAuto) //{ // if (_lpE84Callback.GetCurrentE84State() != E84State.Busy || // !_lpE84Callback.GetE84SignalState(E84SignalID.VALID)) // { // OnError("Unexpected carrier placed on access auto"); // } //} } if (CarrierManager.Instance.GetCarrier(Name).IsEmpty) { CarrierManager.Instance.CreateCarrier(Name); } m_CarrierOnState = CarrierOnLPState.On; SerializableDictionary dvid = new SerializableDictionary(); Singleton.Instance.Eqp_NoteCarrierArrived(PortID); var lpmodule = Singleton.Instance.Modules[ModuleHelper.Converter(Name)] as LoadPortModule; FaLoadPort faLoadPort = FALoadPortManager.Instance.GetLoadPort(PortID); if (faLoadPort.GetAccessMode() == 1) { ReadIDReady = false; lpmodule.Invoke("ReadID"); } dvid["PortID"] = PortID; dvid["PORT_CTGRY"] = SpecPortName; dvid["CarrierType"] = SpecCarrierType; dvid["CarrierIndex"] = InfoPadCarrierIndex; //dvid["InfoPadSensorIndex"] = InfoPadSensorIndex; EV.Notify(EventCarrierArrived, dvid); //EV.Notify(EventCarrierArrived1, dvid); if (_lpcallback != null) _lpcallback.CarrierArrive(); _isMapped = false; EV.PostInfoLog("LoadPort", $"{LPModuleName} carrier arrived."); } } public bool GetUIFoupSensor() { var foupInfo = CarrierManager.Instance.GetCarrier(Name); if (SC.GetValue("System.IsSimulatorMode")) { if (foupInfo != null && !foupInfo.IsEmpty) { return true; } } else { if (IsFoupPresent && foupInfo != null && !foupInfo.IsEmpty) { return true; } } return false; } public void SetVisibility(CarrierInfo carrierInfo, bool setValue) { if (carrierInfo == null) { return; } carrierInfo.UIExitFoup = setValue; carrierInfo.UICarrierColorVisibility = setValue; carrierInfo.UICarrierStatusVisibility = setValue; carrierInfo.UICarrierTypeVisibility = setValue; carrierInfo.UICarrierWaferCountVisibility = setValue; carrierInfo.UICarrierType = carrierInfo.CarrierType.ToString(); var contianPM1 = Singleton.Instance.Modules.ContainsKey(ModuleName.PM1); if (contianPM1 && !string.IsNullOrEmpty(carrierInfo.UICarrierType)) { var pmModule = Singleton.Instance.Modules[ModuleName.PM1] as PMModule; carrierInfo.UICarrierColor = pmModule.GetCarrierUIColor(carrierInfo.UICarrierType, carrierInfo.UICarrierStatusEnum); } } public void Reset() { } public void Terminate() { } //private bool SetExtend(out string reason, int time, object[] param) //{ // reason = ""; // if (param == null || param.Length == 0) // { // reason = "invalid parameter"; // return false; // } // bool.TryParse(param[0].ToString(), out bool isExtend); // return SetExtend(isExtend, out reason); //} //public bool SetExtend(bool isExtend, out string reason) //{ // return _doExtend.SetValue(isExtend, out reason) && _doRetract.SetValue(!isExtend, out reason); //} #region ILoadPort public IndicatorState IndicatiorLoad { get; set; } public IndicatorState IndicatiorUnload { get; set; } public IndicatorState IndicatiorPresence { get; set; } public IndicatorState IndicatorAlarm { get; set; } public IndicatorState IndicatiorPlacement { get; set; } public IndicatorState IndicatiorOpAccess { get; set; } public IndicatorState IndicatiorAccessAuto { get; set; } public IndicatorState IndicatiorAccessManual { get; set; } public IndicatorState IndicatiorStatus1 { get; set; } public IndicatorState IndicatiorStatus2 { get; set; } public IndicatorState IndicatiorManualMode { get; set; } public IndicatorState IndicatiorClampUnclamp { get; set; } public IndicatorState IndicatiorDockUndock { get; set; } public static Dictionary LoadPortIndicatorLightMap = new Dictionary() { {IndicatorType.Load, Indicator.LOAD}, {IndicatorType.Unload, Indicator.UNLOAD}, {IndicatorType.AccessAuto, Indicator.ACCESSAUTO }, {IndicatorType.AccessManual, Indicator.ACCESSMANUL}, {IndicatorType.Alarm, Indicator.ALARM}, {IndicatorType.Presence, Indicator.PRESENCE}, {IndicatorType.Placement, Indicator.PLACEMENT}, {IndicatorType.Status1, Indicator.RESERVE1}, {IndicatorType.Status2, Indicator.RESERVE2}, }; public virtual DeviceState State { get { if (MapError || ReadCarrierIDError) { return DeviceState.Error; } return DeviceState.Unknown; } } public bool IsPresent { get { return _isPresent; } } public bool IsPlacement { get { return _isPlaced; } } public bool IsMapped { get { return _isMapped; } } public virtual bool IsError { get; set; } public virtual string ErrorCode { get; set; } = ""; public bool MapError { get; protected set; } public bool ReadCarrierIDError { get; set; } public IndicatorState[] IndicatorStateFeedback { get; set; } public virtual FoupClampState ClampState { get; set; } public virtual FoupDockState DockState { get; set; } public virtual FoupDoorState DoorState { get; set; } public virtual FoupDoorPostionEnum DoorPosition { get; set; } public virtual bool IsVacuumON { get; set; } public virtual CasstleType CasstleType { get; set; } public string SlotMap { get { return GetSlotMap(); } } public string CarrierId { get { return _carrierId; } } public string LPLotID { get { return _lplotID; } } public RD_TRIG PresentTrig { get { return _presentTrig; } } public RD_TRIG PlacedtTrig { get { return _placetTrig; } } public RD_TRIG AccessSwPressedTrig { get { return _accessSwPressedTrig; } } public RD_TRIG ClampedTrig { get { return _clampTrig; } } public RD_TRIG DockTrig { get { return _dockTrig; } } public RD_TRIG DoorTrig { get { return _doorTrig; } } protected virtual bool _isPresent { get; set; } protected virtual bool _isPlaced { get; set; } protected bool _isDocked { get => DockState == FoupDockState.Docked; } public string InfoPadCarrierType { get; set; } protected bool _isAccessSwPressed; protected string _carrierId = string.Empty; protected string _rfid; protected string _lplotID; protected bool _isMapped; private readonly RD_TRIG _presentTrig = new RD_TRIG(); private readonly RD_TRIG _placetTrig = new RD_TRIG(); private readonly RD_TRIG _accessSwPressedTrig = new RD_TRIG(); private readonly RD_TRIG _clampTrig = new RD_TRIG(); private readonly RD_TRIG _dockTrig = new RD_TRIG(); private readonly RD_TRIG _doorTrig = new RD_TRIG(); public R_TRIG TrigWaferProtrude = new R_TRIG(); public int PortID { get => (int)LPModuleName; } protected string EventCarrierArrived = "CARRIER_ARRIVED"; protected string EventCarrierIdRead = "CARRIER_ID_READ"; protected string EventCarrierIdReadFailed = "CARRIER_ID_READ_FAILED"; protected string EventCarrierIdWrite = "CARRIER_ID_WRITE"; protected string EventCarrierIdWriteFailed = "CARRIER_ID_WRITE_FAILED"; protected string EventSlotMapAvailable = "SLOT_MAP_AVAILABLE"; protected string EventCarrierRemoved = "CARRIER_REMOVED"; protected string EventCarrierUnloaded = "CARRIER_UNLOADED"; protected string EventCarrierLoaded = "CARRIER_LOADED"; protected string EventLPHomed = "LP_HOMED"; //protected string PORT_ID = "PORT_ID"; //protected string CAR_ID = "CAR_ID"; //protected string SLOT_MAP = "SLOT_MAP"; //protected string PORT_CTGRY = "PORT_CTGRY"; //protected string RF_ID = "RF_ID"; //protected string PORT_CARRIER_TYPE = "PORT_CARRIER_TYPE"; private string EventRfIdRead = "RF_ID_READ"; private string EventRfIdReadFailed = "RF_ID_READ_FAILED"; private string EventRfIdWrite = "RF_ID_WRITE"; private string EventRfIdWriteFailed = "RF_ID_WRITE_FAILED"; public string AlarmLoadPortError { get => LPModuleName.ToString() + "Error"; } public string AlarmLoadPortCommunicationError { get => LPModuleName.ToString() + "CommunicationError"; } public string AlarmLoadPortWaferProtrusion { get => LPModuleName.ToString() + "WaferProtrusion"; } public string AlarmLoadPortLoadTimeOut { get => LPModuleName.ToString() + "LoadTimeOut"; } public string AlarmLoadPortLoadFailed { get => LPModuleName.ToString() + "LoadFailed"; } public string AlarmLoadPortUnloadTimeOut { get => LPModuleName.ToString() + "UnloadTimeOut"; } public string AlarmLoadPortUnloadFailed { get => LPModuleName.ToString() + "UnloadFailed"; } public string AlarmLoadPortMappingError { get => LPModuleName.ToString() + "MappingError"; } public string AlarmLoadPortMappingTimeout { get => LPModuleName.ToString() + "MappingTimeout"; } public string AlarmCarrierIDReadError { get => LPModuleName.ToString() + "CarrierIDReadFail"; } public string AlarmCarrierIDWriteError { get => LPModuleName.ToString() + "CarrierIDWriteFail"; } public string AlarmLoadPortHomeFailed { get => LPModuleName.ToString() + "HomeFailed"; } public string AlarmLoadPortHomeTimeout { get => LPModuleName.ToString() + "HomeTimeout"; } public string AlarmLoadE84TP1Timeout { get => LPModuleName.ToString() + "E84LoadTP1TimeOut"; } public string AlarmLoadE84TP2Timeout { get => LPModuleName.ToString() + "E84LoadTP2TimeOut"; } public string AlarmLoadE84TP3Timeout { get => LPModuleName.ToString() + "E84LoadTP3TimeOut"; } public string AlarmLoadE84TP4Timeout { get => LPModuleName.ToString() + "E84LoadTP4TimeOut"; } public string AlarmLoadE84TP5Timeout { get => LPModuleName.ToString() + "E84LoadTP5TimeOut"; } public string AlarmLoadE84TP6Timeout { get => LPModuleName.ToString() + "E84LoadTP6TimeOut"; } public string AlarmUnloadE84TP1Timeout { get => LPModuleName.ToString() + "E84UnloadTP1TimeOut"; } public string AlarmUnloadE84TP2Timeout { get => LPModuleName.ToString() + "E84UnloadTP2TimeOut"; } public string AlarmUnloadE84TP3Timeout { get => LPModuleName.ToString() + "E84UnloadTP3TimeOut"; } public string AlarmUnloadE84TP4Timeout { get => LPModuleName.ToString() + "E84UnloadTP4TimeOut"; } public string AlarmUnloadE84TP5Timeout { get => LPModuleName.ToString() + "E84UnloadTP5TimeOut"; } public string AlarmUnloadE84TP6Timeout { get => LPModuleName.ToString() + "E84UnloadTP6TimeOut"; } public string AlarmLoadPortMapCrossedWafer => LPModuleName.ToString() + "MapCrossedWafer"; public string AlarmLoadPortMapDoubleWafer => LPModuleName.ToString() + "MapDoubleWafer"; public string AlarmLoadPortMapUnknownWafer => LPModuleName.ToString() + "MapUnknownWafer"; public string AlarmLoadPortCarrierIDIndexConfigError => LPModuleName.ToString() + "LoadPortCarrierIDIndexConfigError"; private IE87CallBack _lpcallback = null; public IE87CallBack LPCallBack { get { return _lpcallback; } set { _lpcallback = value; } } private IE84CallBack _lpE84Callback = null; public IE84CallBack LPE84Callback { get { return _lpE84Callback; } set { _lpE84Callback = value; _lpE84Callback.OnE84ActiveSignalChange += _lpE84Callback_OnE84ActiveSignalChange; _lpE84Callback.OnE84PassiveSignalChange += _lpE84Callback_OnE84PassiveSignalChange; _lpE84Callback.OnE84HandOffComplete += _lpE84Callback_OnE84HandOffComplete; _lpE84Callback.OnE84HandOffStart += _lpE84Callback_OnE84HandOffStart; _lpE84Callback.OnE84HandOffTimeout += _lpE84Callback_OnE84HandOffTimeout; } } private ICarrierIDReader _carrierIDReadercallback = null; public ICarrierIDReader CarrierIDReaderCallBack { get { return _carrierIDReadercallback; } set { _carrierIDReadercallback = value; } } public virtual CIDReaderBaseDevice CurrentReader { get; set; } public virtual CIDReaderBaseDevice[] CIDReaders { get; set; } public virtual bool IsBypassCarrierIDReader { get { return SC.ContainsItem($"LoadPort.{LPModuleName}.BypassCarrierIDReader") ? SC.GetValue($"LoadPort.{LPModuleName}.BypassCarrierIDReader") : false; } } public virtual bool IsAutoDetectCarrierType { get { return SC.ContainsItem($"LoadPort.{LPModuleName}.AutoDetectCarrierType") ? SC.GetValue($"LoadPort.{LPModuleName}.AutoDetectCarrierType") : true; } } public virtual bool IsAutoReadCarrierID { get { return SC.ContainsItem($"LoadPort.{LPModuleName}.EnableAutoCarrierIdRead") ? SC.GetValue($"LoadPort.{LPModuleName}.EnableAutoCarrierIdRead") : true; } } public virtual LoadportCassetteState CassetteState { get; set; } public virtual int ValidSlotsNumber { get => 25; } public ModuleName LPModuleName { get; protected set; } public WaferSize Size { get; set; } = WaferSize.WS12; public virtual WaferSize GetCurrentWaferSize() { return Size; } public virtual bool IsVerifyPreDefineWaferCount { get => false; } public virtual int PreDefineWaferCount { get; set; } public virtual int InfoPadCarrierIndex { get; set; } public string SpecPortName { get; set; } = string.Empty; public virtual string SpecCarrierType { get; set; } = ""; public virtual string SpecCarrierInformation { get { if (_isPresent) return "Index:" + InfoPadCarrierIndex.ToString() + "\r\n" + "Type:" + SpecCarrierType + "\r\n" + "Size:" + GetCurrentWaferSize().ToString() + (IsVerifyPreDefineWaferCount ? ("\r\n" + "Pre-Count:" + PreDefineWaferCount.ToString()) : ""); return ""; } } public bool IsAccessSwPressed { get { return _isAccessSwPressed; } } private void SubscribeDataVariable() { DoorState = FoupDoorState.Unknown; WaferManager.Instance.SubscribeLocation(LPModuleName, 25); //CarrierManager.Instance.SubscribeLocation(LPModuleName.ToString()); DATA.Subscribe(Name, "IsPresent", () => IsFoupPresent); DATA.Subscribe(Name, "IsPlaced", () => _isPlaced); DATA.Subscribe(Name, "IsClamped", () => ClampState == FoupClampState.Close); DATA.Subscribe(Name, "IsDocked", () => DockState == FoupDockState.Docked); DATA.Subscribe(Name, "IsDoorOpen", () => DoorState == FoupDoorState.Open); DATA.Subscribe(Name, "IsAccessSwPressed", () => IsAccessSwPressed); //DATA.Subscribe(Name, "CarrierId", () => _carrierId); DATA.Subscribe(Name, "LPLotID", () => _lplotID); DATA.Subscribe(Name, "IsMapped", () => _isMapped); DATA.Subscribe(Name, "IsAutoDetectCarrierType", () => IsAutoDetectCarrierType); //DATA.Subscribe($"{Name}.LoadportState", () => Status.ToString()); //DATA.Subscribe($"{Name}.Status", () => ""); //DATA.Subscribe($"{Name}.LoadportBusy", () => ); DATA.Subscribe($"{Name}.LoadportError", () => ErrorCode); DATA.Subscribe($"{Name}.CassetteState", () => CassetteState); DATA.Subscribe($"{Name}.FoupClampState", () => ClampState); DATA.Subscribe($"{Name}.FoupDockState", () => DockState); DATA.Subscribe($"{Name}.FoupDoorState", () => DoorState); DATA.Subscribe($"{Name}.FoupDoorPosition", () => DoorPosition); DATA.Subscribe($"{Name}.SlotMap", () => SlotMap); DATA.Subscribe($"{Name}.IndicatiorLoad", () => IndicatiorLoad); DATA.Subscribe($"{Name}.IndicatiorUnload", () => IndicatiorUnload); DATA.Subscribe($"{Name}.IndicatiorPresence", () => IndicatiorPresence); DATA.Subscribe($"{Name}.IndicatiorPlacement", () => IndicatiorPlacement); DATA.Subscribe($"{Name}.IndicatiorAlarm", () => IndicatorAlarm); DATA.Subscribe($"{Name}.IndicatiorAccessAuto", () => IndicatiorAccessAuto); DATA.Subscribe($"{Name}.IndicatiorAccessManual", () => IndicatiorAccessManual); DATA.Subscribe($"{Name}.IndicatiorOpAccess", () => IndicatiorOpAccess); DATA.Subscribe($"{Name}.IndicatiorStatus1", () => IndicatiorStatus1); DATA.Subscribe($"{Name}.IndicatiorStatus2", () => IndicatiorStatus2); DATA.Subscribe($"{Name}.CasstleType", () => (int)CasstleType); DATA.Subscribe($"{Name}.InfoPadCarrierType", () => SpecCarrierType); DATA.Subscribe($"{Name}.InfoPadCarrierTypeInformation", () => SpecCarrierInformation); DATA.Subscribe($"{Name}.InfoPadCarrierIndex", () => InfoPadCarrierIndex); DATA.Subscribe($"{Name}.CarrierWaferSize", () => GetCurrentWaferSize().ToString()); DATA.Subscribe($"{Name}.PreDefineWaferCount", () => PreDefineWaferCount); DATA.Subscribe($"{Name}.IsVerifyPreDefineWaferCount", () => IsVerifyPreDefineWaferCount); EV.Subscribe(new EventItem("Event", EventCarrierArrived, "Carrier arrived")); EV.Subscribe(new EventItem("Event", EventCarrierRemoved, "Carrier removed")); EV.Subscribe(new EventItem("Event", EventCarrierIdRead, "Carrier ID read")); EV.Subscribe(new EventItem("Event", EventCarrierIdReadFailed, "Carrier ID read failed")); EV.Subscribe(new EventItem("Event", EventCarrierIdWrite, "Carrier ID write")); EV.Subscribe(new EventItem("Event", EventCarrierIdWriteFailed, "Carrier ID write failed")); EV.Subscribe(new EventItem("Event", EventSlotMapAvailable, "Slot map available")); EV.Subscribe(new EventItem("Event", EventCarrierUnloaded, "Carrier unloaded")); EV.Subscribe(new EventItem("Event", EventCarrierLoaded, "Carrier loaded")); EV.Subscribe(new EventItem("Event", EventRfIdRead, "Carrier RFID read")); EV.Subscribe(new EventItem("Event", EventRfIdReadFailed, "Carrier RFID read failed")); EV.Subscribe(new EventItem("Event", EventRfIdWrite, "Carrier RFID write")); EV.Subscribe(new EventItem("Event", EventRfIdWriteFailed, "Carrier RFID write failed")); SubscribeAlarm(); IndicatorStateFeedback = new IndicatorState[20]; if (_lpE84Callback != null) { _lpE84Callback.OnE84ActiveSignalChange += _lpE84Callback_OnE84ActiveSignalChange; _lpE84Callback.OnE84PassiveSignalChange += _lpE84Callback_OnE84PassiveSignalChange; _lpE84Callback.OnE84HandOffComplete += _lpE84Callback_OnE84HandOffComplete; _lpE84Callback.OnE84HandOffStart += _lpE84Callback_OnE84HandOffStart; _lpE84Callback.OnE84HandOffTimeout += _lpE84Callback_OnE84HandOffTimeout; } } private void SubscribeAlarm() { EV.Subscribe(new EventItem("Alarm", AlarmLoadPortError, $"Load Port {Name} occurred error.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortCommunicationError, $"Load Port {Name}error.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortWaferProtrusion, $"Load Port {Name} wafer protrusion error.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortLoadTimeOut, $"Load Port {Name} load timeout.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortLoadFailed, $"Load Port {Name} load failed.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortUnloadTimeOut, $"Load Port {Name} unload timeout.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortUnloadFailed, $"Load Port {Name} unload failed.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortMappingError, $"Load Port {Name} mapping error.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortMappingTimeout, $"Load Port {Name} mapping Timeout.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmCarrierIDReadError, $"Load Port {Name} occurred error when read carrier ID.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmCarrierIDWriteError, $"Load Port {Name} occurred error when write carrierID.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortMapCrossedWafer, $"Load Port {Name} mapped crossed wafer.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortMapDoubleWafer, $"Load Port {Name} mapped double wafer.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortMapUnknownWafer, $"Load Port {Name} mapped unknown wafer.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortCarrierIDIndexConfigError, $"Load Port {Name} carrierID reader configuration is invalid.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortHomeFailed, $"Load Port {Name} occurred error when home.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadPortHomeTimeout, $"Load Port {Name} home timeout.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadE84TP1Timeout, $"Load Port {Name} occurred TP1 timeout during loading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadE84TP2Timeout, $"Load Port {Name} occurred TP2 timeout during loading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadE84TP3Timeout, $"Load Port {Name} occurred TP3 timeout during loading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadE84TP4Timeout, $"Load Port {Name} occurred TP4 timeout during loading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadE84TP5Timeout, $"Load Port {Name} occurred TP5 timeout during loading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmLoadE84TP6Timeout, $"Load Port {Name} occurred TP6 timeout during loading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmUnloadE84TP1Timeout, $"Load Port {Name} occurred TP1 timeout during unloading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmUnloadE84TP2Timeout, $"Load Port {Name} occurred TP2 timeout during unloading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmUnloadE84TP3Timeout, $"Load Port {Name} occurred TP3 timeout during unloading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmUnloadE84TP4Timeout, $"Load Port {Name} occurred TP4 timeout during unloading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmUnloadE84TP5Timeout, $"Load Port {Name} occurred TP5 timeout during unloading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); EV.Subscribe(new EventItem("Alarm", AlarmUnloadE84TP6Timeout, $"Load Port {Name} occurred TP6 timeout during unloading foup.", EventLevel.Alarm, EventType.EventUI_Notify)); } private void _lpE84Callback_OnE84PassiveSignalChange(E84SignalID arg2, bool arg3) { } private void _lpE84Callback_OnE84HandOffTimeout(IOE84Passive.E84Timeout _timeout, string LoadorUnload) { if (LoadorUnload == "Load") { switch (_timeout) { case IOE84Passive.E84Timeout.TP1: EV.Notify(AlarmLoadE84TP1Timeout); //OnError(AlarmLoadE84TP1Timeout); break; case IOE84Passive.E84Timeout.TP2: EV.Notify(AlarmLoadE84TP2Timeout); //OnError(AlarmLoadE84TP2Timeout); break; case IOE84Passive.E84Timeout.TP3: EV.Notify(AlarmLoadE84TP3Timeout); //OnError(AlarmLoadE84TP3Timeout); break; case IOE84Passive.E84Timeout.TP4: EV.Notify(AlarmLoadE84TP4Timeout); //OnError(AlarmLoadE84TP4Timeout); break; case IOE84Passive.E84Timeout.TP5: EV.Notify(AlarmLoadE84TP5Timeout); //OnError(AlarmLoadE84TP5Timeout); break; default: break; } } if (LoadorUnload == "Unload") { switch (_timeout) { case IOE84Passive.E84Timeout.TP1: EV.Notify(AlarmUnloadE84TP1Timeout); //OnError(AlarmUnloadE84TP1Timeout); break; case IOE84Passive.E84Timeout.TP2: EV.Notify(AlarmUnloadE84TP2Timeout); //OnError(AlarmUnloadE84TP2Timeout); break; case IOE84Passive.E84Timeout.TP3: EV.Notify(AlarmUnloadE84TP3Timeout); //OnError(AlarmUnloadE84TP3Timeout); break; case IOE84Passive.E84Timeout.TP4: EV.Notify(AlarmUnloadE84TP4Timeout); //OnError(AlarmUnloadE84TP4Timeout); break; case IOE84Passive.E84Timeout.TP5: EV.Notify(AlarmUnloadE84TP5Timeout); //OnError(AlarmUnloadE84TP5Timeout); break; default: break; } } } public void OnE84HandOffStart(bool isload) { if (_lpcallback != null) _lpcallback.OnE84HandoffStart(isload); } public void OnE84HandOffComplete(bool isload) { if (_lpcallback != null) _lpcallback.OnE84HandoffComplete(isload); } private void _lpE84Callback_OnE84HandOffStart(string arg2) { OnE84HandOffStart(arg2 == "Load"); } private void _lpE84Callback_OnE84HandOffComplete(string arg2) { OnE84HandOffComplete(arg2 == "Load"); } private void _lpE84Callback_OnE84ActiveSignalChange(E84SignalID arg2, bool arg3) { ; } public virtual void OnSlotMapRead(string _slotMap) { if (_slotMap.Length != ValidSlotsNumber) { EV.PostAlarmLog("LoadPort", "Mapping Data Error."); } for (int i = 0; i < _slotMap.Length; i++) { // No wafer: "0", Wafer: "1", Crossed:"2", Undefined: "?", Overlapping wafers: "W" WaferInfo wafer = null; switch (_slotMap[i]) { case '0': WaferManager.Instance.DeleteWafer(LPModuleName, i); CarrierManager.Instance.UnregisterCarrierWafer(Name, i); break; case '1': wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Normal); WaferManager.Instance.UpdateWaferSize(LPModuleName, i, GetCurrentWaferSize()); CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer); break; case '2': wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Crossed); WaferManager.Instance.UpdateWaferSize(LPModuleName, i, GetCurrentWaferSize()); CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer); EV.Notify(AlarmLoadPortMapCrossedWafer); EV.PostInfoLog("LoadPort", $"{LPModuleName} map crossed wafer on carrier:{_carrierId},slot:{i + 1}."); break; case 'W': wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Double); WaferManager.Instance.UpdateWaferSize(LPModuleName, i, GetCurrentWaferSize()); CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer); EV.Notify(AlarmLoadPortMapDoubleWafer); EV.PostInfoLog("LoadPort", $"{LPModuleName} map double wafer on carrier:{_carrierId},slot:{i + 1}."); break; case '?': wafer = WaferManager.Instance.CreateWafer(LPModuleName, i, WaferStatus.Unknown); WaferManager.Instance.UpdateWaferSize(LPModuleName, i, GetCurrentWaferSize()); CarrierManager.Instance.RegisterCarrierWafer(Name, i, wafer); EV.PostInfoLog("LoadPort", $"{LPModuleName} map unknown wafer on carrier:{_carrierId},slot:{i + 1}."); break; } } SerializableDictionary dvid = new SerializableDictionary(); dvid["SlotMap"] = _slotMap; dvid["PortID"] = PortID; dvid["PORT_CTGRY"] = SpecPortName; dvid["CarrierType"] = SpecCarrierType; dvid["CarrierID"] = CarrierId; EV.Notify(EventSlotMapAvailable, dvid); if (_slotMap.Contains("2")) { MapError = true; EV.Notify(AlarmLoadPortMappingError); } if (_slotMap.Contains("W")) { MapError = true; EV.Notify(AlarmLoadPortMappingError); } if (_slotMap.Contains("?")) { MapError = true; EV.Notify(AlarmLoadPortMappingError); } if (LPCallBack != null) LPCallBack.MappingComplete(_carrierId, _slotMap); _isMapped = true; } private string GetSlotMap() { WaferInfo[] wafers = WaferManager.Instance.GetWafers(ModuleHelper.Converter(Name)); string slot = ""; for (int i = 0; i < 25; i++) { slot += wafers[i].IsEmpty ? "0" : "1"; } return slot; } public void ProceedSetCarrierID(string cid) { _carrierId = cid; CarrierManager.Instance.UpdateCarrierId(Name, cid); } public virtual bool SetE84Available(out string reason) { if (_lpE84Callback != null) { _lpE84Callback.SetHoAutoControl(false); _lpE84Callback.SetHoAvailable(true); } reason = ""; return true; } public virtual bool SetE84Unavailable(out string reason) { if (_lpE84Callback != null) { _lpE84Callback.SetHoAutoControl(false); _lpE84Callback.SetHoAvailable(false); } reason = ""; return true; } public virtual bool SetIndicator(IndicatorType light, IndicatorState state) { return true; } public virtual bool Unload(out string reason) { reason = ""; //_doUnloadFoup.SetValue(true, out reason); //_doLoadFoup.SetValue(false, out reason); //_doInit.SetValue(false, out reason); IsLoadCompleted = false; IsUnloadCompleted = true; return true; } public bool Load(out string reason) { reason = ""; //_doUnloadFoup.SetValue(false, out reason); //_doLoadFoup.SetValue(true, out reason); //_doInit.SetValue(false, out reason); IsUnloadCompleted = false; IsLoadCompleted = true; return true; } public bool Init(out string reason) { reason = ""; //_doUnloadFoup.SetValue(false, out reason); //_doLoadFoup.SetValue(false, out reason); //_doInit.SetValue(true, out reason); IsLoadCompleted = false; IsUnloadCompleted = true; return true; } public bool Stop() { var reason = ""; //_doLoadFoup.SetValue(false, out reason); //_doUnloadFoup.SetValue(false, out reason); //_doInit.SetValue(false, out reason); return true; } public virtual bool FALoad(out string reason) { reason = ""; //_doLoadFoup.SetValue(true, out reason); return true; } public virtual bool WriteRfid(string cid, int startpage, int length, out string reason) { reason = ""; return true; } public virtual bool ReadRfId(out string reason) { reason = ""; return true; } public virtual bool FAUnload(out string reason) { reason = ""; //_doUnloadFoup.SetValue(true, out reason); return true; } public virtual bool Unclamp(out string reason) { reason = ""; _doClamp?.SetValue(false, out reason); _doRelease?.SetValue(true, out reason); return true; } public virtual bool Clamp(out string reason) { reason = ""; _doClamp?.SetValue(true, out reason); _doRelease?.SetValue(false, out reason); return true; } public virtual bool ReadCarrierID() { int offset = SC.ContainsItem($"LoadPort.{LPModuleName}.StartPage") ? SC.GetValue($"LoadPort.{LPModuleName}.StartPage") : 0; int length = SC.ContainsItem($"LoadPort.{LPModuleName}.DataReadSize") ? SC.GetValue($"LoadPort.{LPModuleName}.DataReadSize") : 16; if (SC.ContainsItem($"CarrierInfo.{LPModuleName}CIDReaderIndex{InfoPadCarrierIndex}")) { int cidindex = SC.GetValue($"CarrierInfo.{LPModuleName}CIDReaderIndex{InfoPadCarrierIndex}"); if (CIDReaders != null && CIDReaders.Length > cidindex) _carrierIDReadercallback = CIDReaders[cidindex]; else { return true; } } if (_carrierIDReadercallback != null) { if (SC.ContainsItem("CarrierID.CarrierIdReaderProtocolType") && SC.GetStringValue("CarrierID.CarrierIdReaderProtocolType") == "1:N") return _carrierIDReadercallback.ReadCarrierID(offset, length, int.Parse(Name.ToString().Replace("LP", ""))); return _carrierIDReadercallback.ReadCarrierID(offset, length); } return false; } #endregion } }