|
@@ -1,815 +0,0 @@
|
|
|
-using Aitex.Core.Common;
|
|
|
-using Aitex.Core.Common.DeviceData;
|
|
|
-using Aitex.Core.RT.DataCenter;
|
|
|
-using Aitex.Core.RT.Device;
|
|
|
-using Aitex.Core.RT.Event;
|
|
|
-using Aitex.Core.RT.Log;
|
|
|
-using Aitex.Core.RT.SCCore;
|
|
|
-using Aitex.Core.Util;
|
|
|
-using Aitex.Sorter.Common;
|
|
|
-using MECF.Framework.Common.Equipment;
|
|
|
-using MECF.Framework.Common.CommonData;
|
|
|
-using MECF.Framework.Common.SubstrateTrackings;
|
|
|
-using System;
|
|
|
-using System.Collections;
|
|
|
-using System.Collections.Generic;
|
|
|
-using Venus_Core;
|
|
|
-
|
|
|
-using Venus_RT.Devices.YASKAWA;
|
|
|
-using Venus_RT.Modules;
|
|
|
-using Venus_RT.Modules.LPs;
|
|
|
-
|
|
|
-namespace Venus_RT.Devices.EFEM
|
|
|
-{
|
|
|
- /// <summary>
|
|
|
- /// EFEM object class
|
|
|
- /// </summary>
|
|
|
- sealed class Efem : EfemBase, IEfem
|
|
|
- {
|
|
|
- //---------------------------------Fields----------------------------------------
|
|
|
- //
|
|
|
- private readonly JetPMBase[] _pm = new JetPMBase[2];
|
|
|
- private readonly Loadport[] _LPMs = new Loadport[2];
|
|
|
- private readonly SignalTower _signalT = new SignalTower();
|
|
|
- //private readonly CoolingStage[] _aligner = new CoolingStage[2];
|
|
|
- //private string _robotMoveAction;
|
|
|
- private RobotMoveInfo _robotMoveInfo = new RobotMoveInfo();
|
|
|
- private LidState _CassetteDoor;
|
|
|
- private LidState _SideDoor;
|
|
|
- private F_TRIG _bSysVacPressure1 = new F_TRIG();
|
|
|
- private F_TRIG _bSysCompressedAirPressure = new F_TRIG();
|
|
|
- private R_TRIG _bFlowGaugeSensor = new R_TRIG();
|
|
|
- private R_TRIG _bLeakageSensor = new R_TRIG();
|
|
|
- private F_TRIG _bDiffPressureSensorSetting1 = new F_TRIG();
|
|
|
- private F_TRIG _bDiffPressureSensorSetting2 = new F_TRIG();
|
|
|
- private F_TRIG _bIonizerAlarm = new F_TRIG();
|
|
|
- private F_TRIG _bFFuAlarm = new F_TRIG();
|
|
|
- private F_TRIG _bAreaSensor = new F_TRIG();
|
|
|
- private F_TRIG _bModeSwitch = new F_TRIG();
|
|
|
- private RD_TRIG _bCassetteDoorTrig = new RD_TRIG();
|
|
|
- private RD_TRIG _bSideDoorTrig = new RD_TRIG();
|
|
|
-
|
|
|
- public Dictionary<ModuleName, bool> IsBufferPinUp = new Dictionary<ModuleName, bool>();
|
|
|
-
|
|
|
-
|
|
|
- public override ILoadport this[ModuleName mod]
|
|
|
- {
|
|
|
- get
|
|
|
- {
|
|
|
- if (!ModuleHelper.IsLoadPort(mod))
|
|
|
- throw new ApplicationException($"{mod} is NOT Loadport");
|
|
|
-
|
|
|
- return _LPMs[mod - ModuleName.LP1];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- //---------------------------------Properties------------------------------------
|
|
|
- //
|
|
|
- public LidState CassetteDoor
|
|
|
- {
|
|
|
- get => _CassetteDoor;
|
|
|
- set
|
|
|
- {
|
|
|
- _CassetteDoor = value;
|
|
|
-
|
|
|
- _bCassetteDoorTrig.CLK = _CassetteDoor == LidState.Close;
|
|
|
- if (_bCassetteDoorTrig.T)
|
|
|
- {
|
|
|
- EV.Notify(CassetteDoorOpen);
|
|
|
-
|
|
|
- EV.PostWarningLog(Module.ToString(), "Cassette door opened");
|
|
|
- }
|
|
|
- if (_bCassetteDoorTrig.R)
|
|
|
- {
|
|
|
- EV.Notify(CassetteDoorClose);
|
|
|
-
|
|
|
- EV.PostInfoLog(Module.ToString(), "Cassette door closed");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public LidState DoorSwitch
|
|
|
- {
|
|
|
- get => _SideDoor;
|
|
|
- set
|
|
|
- {
|
|
|
- _SideDoor = value;
|
|
|
-
|
|
|
- _bSideDoorTrig.CLK = _SideDoor == LidState.Close;
|
|
|
- if (_bSideDoorTrig.T)
|
|
|
- {
|
|
|
- EV.Notify(EFEMSideDoorOpen);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM Side door open");
|
|
|
- }
|
|
|
- if (_bSideDoorTrig.R)
|
|
|
- {
|
|
|
- EV.PostInfoLog(Module.ToString(), "EFEM Side door close");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- private string CassetteDoorOpen = "CassetteDoorOpen";
|
|
|
- private string CassetteDoorClose = "CassetteDoorClose";
|
|
|
-
|
|
|
- private string EFEMSideDoorOpen = "EFEMSideDoorOpen";
|
|
|
-
|
|
|
- private string EFEMVacuumPressureError = "EFEMVacuumPressureError";
|
|
|
- private string EFEMCDAError = "EFEMCDAError";
|
|
|
- private string EFEMFlowGaugeSensorError = "EFEMFlowGaugeSensorError";
|
|
|
- private string EFEMLeakageAlarm = "EFEMLeakageAlarm";
|
|
|
- private string EFEMIonizerAlarm = "EFEMIonizerAlarm";
|
|
|
- private string EFEMFFUAlarm = "EFEMFFUAlarm";
|
|
|
- private string EFEMOffline = "EFEMOffline";
|
|
|
- private string EFEMCommunicationError = "EFEMCommunicationError";
|
|
|
- private string WaferTransferFailed = "WaferTransferFailed";
|
|
|
- private string EFEMError = "EFEMError";
|
|
|
-
|
|
|
- // Constructor
|
|
|
- //
|
|
|
- public Efem()
|
|
|
- {
|
|
|
- Module = ModuleName.EfemRobot;
|
|
|
-
|
|
|
- _pm[0] = DEVICE.GetDevice<JetPMBase>(ModuleName.PMA.ToString());
|
|
|
- _pm[1] = DEVICE.GetDevice<JetPMBase>(ModuleName.PMB.ToString());
|
|
|
-
|
|
|
- _comm = new EfemComm();
|
|
|
-
|
|
|
- _LPMs[0] = new Loadport(ModuleName.LP1, this);
|
|
|
- _LPMs[1] = new Loadport(ModuleName.LP2, this);
|
|
|
-
|
|
|
- IsBufferPinUp[ModuleName.Aligner1] = false;
|
|
|
- IsBufferPinUp[ModuleName.Aligner2] = false;
|
|
|
- IsBufferPinUp[ModuleName.Cooling1] = false;
|
|
|
- IsBufferPinUp[ModuleName.Cooling2] = false;
|
|
|
-
|
|
|
- //if ((EfemEntity.EfemType)SC.GetValue<int>($"EFEM.EfemType") == EfemEntity.EfemType.BrooksEFEM)
|
|
|
- //{
|
|
|
- // BrooksProxy = new BrooksEFEMProxy();
|
|
|
- // BrooksProxy.CommandUpdated += MsgOnCommandUpdated;
|
|
|
- // BrooksProxy.EventUpdated += MsgOnEventUpdated;
|
|
|
- // BrooksProxy.ErrorOccurred += MsgOnErrorOccurred;
|
|
|
- //}
|
|
|
-
|
|
|
- _msgHandler = new MessageHandler(this);
|
|
|
- _msgHandler.CommandUpdated += MsgOnCommandUpdated;
|
|
|
- _msgHandler.EventUpdated += MsgOnEventUpdated;
|
|
|
- _msgHandler.ErrorOccurred += MsgOnErrorOccurred;
|
|
|
-
|
|
|
- CarrierManager.Instance.SubscribeLocation(ModuleName.LP1.ToString(), 1);
|
|
|
- CarrierManager.Instance.SubscribeLocation(ModuleName.LP2.ToString(), 1);
|
|
|
-
|
|
|
- Action<ModuleName, int> _subscribeLoc = (ModuleName module, int waferCount) => {
|
|
|
- if (ModuleHelper.IsInstalled(module))
|
|
|
- {
|
|
|
- WaferManager.Instance.SubscribeLocation(module, waferCount);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- _subscribeLoc(ModuleName.EfemRobot, 2);
|
|
|
- _subscribeLoc(ModuleName.Aligner1, 1);
|
|
|
- _subscribeLoc(ModuleName.Aligner2, 1);
|
|
|
- _subscribeLoc(ModuleName.Cooling1, 1);
|
|
|
- _subscribeLoc(ModuleName.Cooling2, 1);
|
|
|
- _subscribeLoc(ModuleName.LP1, SC.GetValue<int>("EFEM.LoadPort.SlotNumber"));
|
|
|
- _subscribeLoc(ModuleName.LP2, SC.GetValue<int>("EFEM.LoadPort.SlotNumber"));
|
|
|
- //_subscribeLoc(ModuleName.Flipper, 1);
|
|
|
- _subscribeLoc(ModuleName.Buffer, 10);
|
|
|
-
|
|
|
- DATA.Subscribe("EfemRobot.RobotMoveAction", () => _robotMoveInfo);
|
|
|
- DATA.Subscribe("LP1.JobDone", () =>
|
|
|
- {
|
|
|
- return _LPMs[0].JobDone;
|
|
|
- });
|
|
|
-
|
|
|
- DATA.Subscribe("LP1.NotifyJobDone", () =>
|
|
|
- {
|
|
|
- if (!_LPMs[0].JobDone || !_LPMs[0].HasCassette)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (SC.GetValue<int>("System.Job.BuzzerTimeWhenJobDone") >= 0
|
|
|
- && _LPMs[0].TimerNotifyJobDone.ElapsedMilliseconds > SC.GetValue<int>("System.Job.BuzzerTimeWhenJobDone") * 1000)
|
|
|
- return false;
|
|
|
-
|
|
|
- return _LPMs[0].JobDone;
|
|
|
- });
|
|
|
-
|
|
|
- DATA.Subscribe("LP2.JobDone", () =>
|
|
|
- {
|
|
|
- return _LPMs[1].JobDone;
|
|
|
- });
|
|
|
- DATA.Subscribe("LP2.NotifyJobDone", () =>
|
|
|
- {
|
|
|
- if (!_LPMs[1].JobDone || !_LPMs[1].HasCassette)
|
|
|
- return false;
|
|
|
-
|
|
|
- if (SC.GetValue<int>("System.Job.BuzzerTimeWhenJobDone") >= 0
|
|
|
- && _LPMs[1].TimerNotifyJobDone.ElapsedMilliseconds > SC.GetValue<int>("System.Job.BuzzerTimeWhenJobDone") * 1000)
|
|
|
- return false;
|
|
|
-
|
|
|
- return _LPMs[1].JobDone;
|
|
|
- });
|
|
|
-
|
|
|
- Func<ModuleName, int, string> _waferSize = (ModuleName module, int slot) => {
|
|
|
- string sSize = WaferSize.WS12.ToString();
|
|
|
- if (ModuleHelper.IsInstalled(module))
|
|
|
- {
|
|
|
- sSize = WaferManager.Instance.GetWafer(module, slot).Size.ToString();
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- sSize = WaferSize.WS12.ToString();
|
|
|
- }
|
|
|
-
|
|
|
- return sSize;
|
|
|
- };
|
|
|
- DATA.Subscribe("Aligner1.WaferSize", () => _waferSize(ModuleName.Aligner1, 0));
|
|
|
- DATA.Subscribe("Aligner2.WaferSize", () => _waferSize(ModuleName.Aligner2, 0));
|
|
|
- DATA.Subscribe("Cooling1.WaferSize", () => _waferSize(ModuleName.Cooling1, 0));
|
|
|
- DATA.Subscribe("Cooling2.WaferSize", () => _waferSize(ModuleName.Cooling2, 0));
|
|
|
- DATA.Subscribe("EfemRobot.WaferSize", () => _waferSize(ModuleName.EfemRobot, 0));
|
|
|
- DATA.Subscribe("Buffer.WaferSize", () => _waferSize(ModuleName.Buffer, 0));
|
|
|
- DATA.Subscribe("EFEM.CassetteDoor", () => CassetteDoor);
|
|
|
-
|
|
|
- DATA.Subscribe("EfemRobot.GripStateBlade1", () => GripStateBlade1);
|
|
|
- DATA.Subscribe("EfemRobot.GripStateBlade2", () => GripStateBlade2);
|
|
|
-
|
|
|
-
|
|
|
- GripStateBlade1 = "Unknown";
|
|
|
- GripStateBlade2 = "Unknown";
|
|
|
-
|
|
|
- _bCassetteDoorTrig.CLK = true;
|
|
|
- _bSideDoorTrig.CLK = true;
|
|
|
-
|
|
|
- EV.Subscribe(new EventItem("Event", CassetteDoorOpen, "Cassette Door Open"));
|
|
|
- EV.Subscribe(new EventItem("Event", CassetteDoorClose, "Cassette Door Close"));
|
|
|
-
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMSideDoorOpen, "EFEM Side Door Open", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMVacuumPressureError, "EFEM Vacuum pressure error", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMCDAError, "EFEM CDA error", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMFlowGaugeSensorError, "EFEM flow gauge sensor error", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMLeakageAlarm, "EFEM leakage alarm", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMIonizerAlarm, "EFEM Ionizer alarm", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMFFUAlarm, "EFEM FFU alarm", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMOffline, "EFEM offline", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMCommunicationError, "EFEM Communication error", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", WaferTransferFailed, "Wafer Transfer Failed", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- EV.Subscribe(new EventItem("Event", EFEMError, "EFEM Error", EventLevel.Alarm, EventType.HostNotification));
|
|
|
- }
|
|
|
-
|
|
|
- // Methods
|
|
|
- //
|
|
|
- public bool HomeAll()
|
|
|
- {
|
|
|
- AddAction(new HomeAllAction(this, ModuleName.EFEM));
|
|
|
- AddAction(new OrgshAction(this, ModuleName.EFEM));
|
|
|
- AddAction(new TrackAction(this, ModuleName.EFEM));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool Home(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new HomeModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool Load(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new LoadModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool Unload(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new UnloadModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool ReadCarrierId(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new ReadCarrierIdModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool WriteCarrierId(ModuleName mod, string id)
|
|
|
- {
|
|
|
- AddAction(new WriteCarrierIdModuleAction(this, mod, id));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool ReadTagData(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new ReadTagDataModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool WriteTagData(ModuleName mod, string tagData)
|
|
|
- {
|
|
|
- AddAction(new WriteTagDataModuleAction(this, mod, tagData));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool Dock(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new DockModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool Undock(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new UndockModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool Clamp(ModuleName mod, bool isUnloadClamp)
|
|
|
- {
|
|
|
- AddAction(new ClampModuleAction(this, mod, isUnloadClamp));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool Unclamp(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new UnclampModuleAction(this, mod));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
- public bool SetThick(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new SetThicknessModuleAction(this, mod, "Thick"));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool SetThin(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new SetThicknessModuleAction(this, mod, "Thin"));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool ClearError()
|
|
|
- {
|
|
|
- AddAction(new ClearErrorAction(this));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public void AbortRobot()
|
|
|
- {
|
|
|
- AddAction(new AbortAction(this));
|
|
|
- }
|
|
|
-
|
|
|
- public void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target)
|
|
|
- {
|
|
|
- _robotMoveInfo.Action = action;
|
|
|
- _robotMoveInfo.ArmTarget = hand == Hand.Blade1 ? RobotArm.ArmA : (hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB);
|
|
|
- _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{target}";
|
|
|
- }
|
|
|
-
|
|
|
- public bool Pick(MoveParam mp)
|
|
|
- {
|
|
|
- if (!WaferManager.Instance.CheckWafer(mp.SrcModule, mp.SrcSlot, WaferStatus.Normal))
|
|
|
- {
|
|
|
- EV.PostAlarmLog("System", $"{mp.SrcModule} slot {mp.SrcSlot + 1} wafer is not normal");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (ModuleHelper.IsPm(mp.SrcModule))
|
|
|
- {
|
|
|
- JetPMBase pM = GetPM(mp.SrcModule);
|
|
|
-
|
|
|
- if (pM.IsSlitDoorClosed)
|
|
|
- {
|
|
|
- EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- AddAction(new PinAction(mp.SrcModule, pM, MovementPosition.Up, false, mp.Arm, true));
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = mp.SrcModule, Arm = mp.Arm, Pos = ExtendPos.GB }));
|
|
|
-
|
|
|
- AddAction(new PinAction(mp.SrcModule, pM, MovementPosition.Down, true, mp.Arm, true));
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = mp.SrcModule, Arm = mp.Arm, Pos = ExtendPos.G4 }));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- SetRobotMovingInfo(RobotAction.Picking, mp.Arm, mp.SrcModule);
|
|
|
- AddAction(new PickAction(this, mp));
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool Place(MoveParam mp)
|
|
|
- {
|
|
|
- if (ModuleHelper.IsPm(mp.DestModule))
|
|
|
- {
|
|
|
- JetPMBase pM = GetPM(mp.DestModule);
|
|
|
-
|
|
|
- if (pM.IsSlitDoorClosed)
|
|
|
- {
|
|
|
- EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = mp.DestModule, Arm = mp.Arm, Pos = ExtendPos.PB }));
|
|
|
- AddAction(new PinAction(mp.DestModule, pM, MovementPosition.Up, true, mp.Arm, false));
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = mp.DestModule, Arm = mp.Arm, Pos = ExtendPos.P4 }));
|
|
|
- AddAction(new PinAction(mp.DestModule, pM, MovementPosition.Up, false, mp.Arm, false));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- SetRobotMovingInfo(RobotAction.Placing, mp.Arm, mp.DestModule);
|
|
|
- AddAction(new PlaceAction(this, mp));
|
|
|
- }
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public void PickAndPlace(MoveParam pickParam, MoveParam placeParam)
|
|
|
- {
|
|
|
- if (!WaferManager.Instance.CheckWafer(pickParam.SrcModule, pickParam.SrcSlot, WaferStatus.Normal))
|
|
|
- {
|
|
|
- EV.PostAlarmLog("System", $"{pickParam.SrcModule} slot {pickParam.SrcSlot + 1} wafer is not normal");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- if (ModuleHelper.IsPm(pickParam.SrcModule))
|
|
|
- {
|
|
|
- JetPMBase pM = GetPM(pickParam.SrcModule);
|
|
|
-
|
|
|
- if (pM.IsSlitDoorClosed)
|
|
|
- {
|
|
|
- EV.PostAlarmLog(pM.Module.ToString(), "Slit 门必须打开");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- AddAction(new PinAction(pickParam.SrcModule, pM, MovementPosition.Up, false, pickParam.Arm, true));
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = pickParam.SrcModule, Arm = pickParam.Arm, Pos = ExtendPos.GB }));
|
|
|
-
|
|
|
- AddAction(new PinAction(pickParam.SrcModule, pM, MovementPosition.Down, true, pickParam.Arm, true));
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = pickParam.SrcModule, Arm = pickParam.Arm, Pos = ExtendPos.G4 }));
|
|
|
-
|
|
|
-
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = placeParam.DestModule, Arm = placeParam.Arm, Pos = ExtendPos.PB }));
|
|
|
- AddAction(new PinAction(placeParam.DestModule, pM, MovementPosition.Up, true, placeParam.Arm, false));
|
|
|
- AddAction(new ExtendAction(this, new ExtendParam { Module = placeParam.DestModule, Arm = placeParam.Arm, Pos = ExtendPos.P4 }));
|
|
|
- AddAction(new PinAction(placeParam.DestModule, pM, MovementPosition.Up, false, placeParam.Arm, false));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- SetRobotMovingInfo(RobotAction.Picking, pickParam.Arm, pickParam.SrcModule);
|
|
|
- AddAction(new PickAction(this, pickParam));
|
|
|
-
|
|
|
- SetRobotMovingInfo(RobotAction.Placing, placeParam.Arm, placeParam.DestModule);
|
|
|
- AddAction(new PlaceAction(this, placeParam));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public bool Extend(ExtendParam ep)
|
|
|
- {
|
|
|
- AddAction(new ExtendAction(this, ep));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public void Goto(MoveParam ep)
|
|
|
- {
|
|
|
- //_robotMoveAction = string.Format($"{ep.SrcModule}.Goto");
|
|
|
- AddAction(new GotoAction(this, ep));
|
|
|
- }
|
|
|
-
|
|
|
- public bool Retract(ExtendParam ep)
|
|
|
- {
|
|
|
- AddAction(new ExtendAction(this, ep));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool Map(ModuleName mod)
|
|
|
- {
|
|
|
- if (_LPMs[mod - ModuleName.LP1].Protrusion)
|
|
|
- {
|
|
|
- EV.PostAlarmLog(mod.ToString(), $"{mod} wafer protrusion, can not do Map");
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- _LPMs[mod - ModuleName.LP1].Map();
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public bool Grip(Hand blade, bool isGrip)
|
|
|
- {
|
|
|
- AddAction(new GripAction(this, blade, isGrip));
|
|
|
-
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool SetPinUp(ModuleName mod)
|
|
|
- {
|
|
|
- AddAction(new LiftAction(this, mod, true));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool SetPinDown(ModuleName mod)
|
|
|
- {
|
|
|
- if ((EfemEntity.EfemType)SC.GetValue<int>($"EFEM.EfemType") == EfemEntity.EfemType.BrooksEFEM)
|
|
|
- return true;
|
|
|
-
|
|
|
- AddAction(new LiftAction(this, mod, false));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool Align(ModuleName mod, float delayTime, Aitex.Core.Common.WaferSize size)
|
|
|
- {
|
|
|
- AddAction(new AlignAction(this, mod, size));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public bool SetLamp(LightType light, LightStatus status)
|
|
|
- {
|
|
|
- AddAction(new LedAction(this, light, status));
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- public void TurnOffBuzzer()
|
|
|
- {
|
|
|
- AddAction(new LedAction(this, LightType.BUZZER1, LightStatus.OFF));
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- //public void SwitchOnBuzzerAndRed()
|
|
|
- //{
|
|
|
- // AddAction(new LedAction(this, LightType.RED, LightStatus.ON));
|
|
|
- // AddAction(new LedAction(this, LightType.YELLOW, LightStatus.OFF));
|
|
|
- // AddAction(new LedAction(this, LightType.GREEN, LightStatus.OFF));
|
|
|
- // AddAction(new LedAction(this, LightType.BUZZER1, LightStatus.ON));
|
|
|
- //}
|
|
|
-
|
|
|
- public override void ReceiveMessage(string sRec)
|
|
|
- {
|
|
|
- _msgHandler.ReceiveMessage(sRec);
|
|
|
- }
|
|
|
-
|
|
|
- public override void SetOnline(ModuleName mod, bool online)
|
|
|
- {
|
|
|
- this[mod].SetOnline(online);
|
|
|
- }
|
|
|
-
|
|
|
- public override void SetBusy(ModuleName mod, bool busy)
|
|
|
- {
|
|
|
- this[mod].Status = DeviceState.Busy;
|
|
|
- }
|
|
|
-
|
|
|
- //--------------------------------Constructor------------------------------------
|
|
|
- //
|
|
|
- private JetPMBase GetPM(ModuleName mod)
|
|
|
- {
|
|
|
- if (!ModuleHelper.IsPm(mod))
|
|
|
- throw new ArgumentException("Module argument error");
|
|
|
-
|
|
|
- return _pm[mod - ModuleName.PMA];
|
|
|
- }
|
|
|
-
|
|
|
- //----------------------------------Private Method-------------------------------
|
|
|
- //
|
|
|
- private void MsgOnEventUpdated(object sender, EventArgs e)
|
|
|
- {
|
|
|
- if (!(e is EfemEventArgs))
|
|
|
- return;
|
|
|
-
|
|
|
- EfemEventArgs eArg = e as EfemEventArgs;
|
|
|
-
|
|
|
- switch (eArg.CommandType)
|
|
|
- {
|
|
|
- case EfemOperation.SigStatus:
|
|
|
- // EVT:SIGSTAT/Parameter/DATA1/DATA2;
|
|
|
- string sParam = eArg.DataList[0]; // "SYSTEM" or "Pn"
|
|
|
-
|
|
|
- // DATA1 & DATA2
|
|
|
- int nData1 = Convert.ToInt32(eArg.DataList[1], 16);
|
|
|
- int nData2 = Convert.ToInt32(eArg.DataList[2], 16);
|
|
|
-
|
|
|
- BitArray baData1 = new BitArray(new int[] { nData1 });
|
|
|
- BitArray baData2 = new BitArray(new int[] { nData2 });
|
|
|
-
|
|
|
- if (0 == string.Compare(sParam, Constant.SYS, true))
|
|
|
- {
|
|
|
- // EVT:SIGSTAT/System/00000000/00000004;
|
|
|
- // DATA1
|
|
|
- _bSysVacPressure1.CLK = baData1[0]; // bit 0
|
|
|
- _bSysCompressedAirPressure.CLK = baData1[2]; // bit 2
|
|
|
- _bFlowGaugeSensor.CLK = baData1[4]; // bit 4
|
|
|
- _bLeakageSensor.CLK = baData1[5]; // bit 5
|
|
|
- this.DoorSwitch = baData1[6] ? LidState.Close : LidState.Open; // bit 6
|
|
|
- //bDrivePower = baData1[7]; // bit 7
|
|
|
- _bDiffPressureSensorSetting1.CLK = baData1[8]; // bit 8
|
|
|
- _bDiffPressureSensorSetting2.CLK = baData1[9]; // bit 9
|
|
|
- _bIonizerAlarm.CLK = baData1[10]; // bit 10
|
|
|
- _bFFuAlarm.CLK = baData1[11]; // bit 11
|
|
|
- _bAreaSensor.CLK = baData1[12]; // bit 12
|
|
|
- _bModeSwitch.CLK = baData1[13]; // bit 13
|
|
|
- this.CassetteDoor = baData1[15] ? LidState.Close : LidState.Open; // bit 15
|
|
|
-
|
|
|
- // Post warning and alarm
|
|
|
- if (!baData1[0]) // Bit[0] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMVacuumPressureError);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM System vacuum source pressure low");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[1]) // Bit[1] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMIonizerAlarm);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM Ionizer compressed air error");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[2]) // Bit[2] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMCDAError);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM System compressed air pressure low");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[4]) // Bit[4] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMFlowGaugeSensorError);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM Flow gauge sensor error");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[5]) // Bit[5] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMLeakageAlarm);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM Leakage alarm");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[10]) // Bit[10] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMIonizerAlarm);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM Ionizer alarm");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[11]) // Bit[11] ON=Normal, OFF=Abnormal
|
|
|
- {
|
|
|
- EV.Notify(EFEMFFUAlarm);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "FFU alarm");
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
|
|
|
- }
|
|
|
- if (!baData1[13]) // Bit[13] ON=RUN, OFF=Maintain
|
|
|
- {
|
|
|
- EV.Notify(EFEMOffline);
|
|
|
- EV.PostAlarmLog(Module.ToString(), "EFEM switch to Maintain mode, HomeAll to recover");
|
|
|
- //Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.ToInit);
|
|
|
- }
|
|
|
- // DATA2
|
|
|
- _signalT.ChangeLightStatus(LightType.RED, baData2[0] ? LightStatus.ON : baData2[5] ? LightStatus.BLINK : LightStatus.OFF);
|
|
|
- _signalT.ChangeLightStatus(LightType.GREEN, baData2[1] ? LightStatus.ON : baData2[6] ? LightStatus.BLINK : LightStatus.OFF);
|
|
|
- _signalT.ChangeLightStatus(LightType.YELLOW, baData2[2] ? LightStatus.ON : baData2[7] ? LightStatus.BLINK : LightStatus.OFF);
|
|
|
- _signalT.ChangeLightStatus(LightType.BLUE, baData2[3] ? LightStatus.ON : baData2[8] ? LightStatus.BLINK : LightStatus.OFF);
|
|
|
- _signalT.ChangeLightStatus(LightType.WHITE, baData2[4] ? LightStatus.ON : baData2[9] ? LightStatus.BLINK : LightStatus.OFF);
|
|
|
- _signalT.ChangeLightStatus(LightType.BUZZER1, baData2[10] ? LightStatus.ON : LightStatus.OFF);
|
|
|
-
|
|
|
- /* EFEM 程序中目前没有实现
|
|
|
- _RobotErr.CLK = baData2[27]; // bit 27
|
|
|
-
|
|
|
- bool bArmNotExtendLLA = baData2[30]; // bit 30
|
|
|
- bool bArmNotExtendLLB = baData2[31]; // bit 31
|
|
|
- */
|
|
|
- } // system event
|
|
|
- else
|
|
|
- {
|
|
|
- _LPMs[eArg.Module - ModuleName.LP1].HandleEvent(eArg);
|
|
|
- } // FOUP EVENT
|
|
|
- break;
|
|
|
- case EfemOperation.GetWaferInfo:
|
|
|
- _LPMs[eArg.Module - ModuleName.LP1].HandleEvent(eArg);
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void MsgOnCommandUpdated(object sender, EventArgs e)
|
|
|
- {
|
|
|
- EfemActionArgs arg = e as EfemActionArgs;
|
|
|
- if (arg == null) throw new ArgumentNullException("Argument is Null");
|
|
|
-
|
|
|
- if (arg.CommandType == EfemOperation.Ready)
|
|
|
- {
|
|
|
- this.CommunicationConnected = true;
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.CommReady);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- EfemActionBase action = null;
|
|
|
-
|
|
|
- lock (_lockerAction)
|
|
|
- {
|
|
|
- foreach (var item in _actions)
|
|
|
- {
|
|
|
- if (item is EfemActionBase a1)
|
|
|
- {
|
|
|
- if (a1.Type == arg.CommandType && item.Status != ActionStatus.Completed)
|
|
|
- {
|
|
|
- action = a1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (action == null)
|
|
|
- {
|
|
|
- //EV.PostAlarmLog(arg.Module.ToString(), $"NO activated {arg.CommandType} in the queue");
|
|
|
- LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"NO activated [{arg.ID}] [{arg.CommandType}] in the queue");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- // 更新 action 状态
|
|
|
- action.Status = arg.Status;
|
|
|
-
|
|
|
- if (arg.Status == ActionStatus.Completed)
|
|
|
- {
|
|
|
- ModuleName mod = action.Module;
|
|
|
-
|
|
|
- // Map 命令比较特别, module 是LPX但是用robot做mapping
|
|
|
- if (mod == ModuleName.EFEM || mod == ModuleName.EfemRobot || ModuleHelper.IsAligner(mod) || ModuleHelper.IsCooling(mod) || arg.CommandType == EfemOperation.Map)
|
|
|
- {
|
|
|
- if ((action.Type != EfemOperation.Light) && (action.Type != EfemOperation.Lift))
|
|
|
- {
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.ActionDone, arg.CommandType);
|
|
|
- }
|
|
|
-
|
|
|
- if (action.Type == EfemOperation.Lift)
|
|
|
- {
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.LiftActionDone, arg.CommandType);
|
|
|
- }
|
|
|
- }
|
|
|
- else if (ModuleHelper.IsLoadPort(mod))
|
|
|
- {
|
|
|
- Singleton<RouteManager>.Instance.EFEM.NotifyLP(mod, LoadportEntity.MSG.ActionDone);
|
|
|
- }
|
|
|
-
|
|
|
- if(arg.CommandType == EfemOperation.Pick || arg.CommandType == EfemOperation.Place)
|
|
|
- SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.System);
|
|
|
-
|
|
|
- action.OnPostWork(arg.Data);
|
|
|
-
|
|
|
- LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"efem action [{action.GetType().Name}] [{action.ID}][{action.Type}] removed from queue");
|
|
|
-
|
|
|
- _actions.Remove(action);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private void MsgOnErrorOccurred(object sender, EventArgs e)
|
|
|
- {
|
|
|
- if (!(e is EfemErrorArgs arg))
|
|
|
- return;
|
|
|
-
|
|
|
- this.Status = DeviceState.Error;
|
|
|
-
|
|
|
- EfemActionBase action = null;
|
|
|
-
|
|
|
- lock (_lockerAction)
|
|
|
- {
|
|
|
- foreach (var item in _actions)
|
|
|
- {
|
|
|
- if (item is EfemActionBase a1)
|
|
|
- {
|
|
|
- if (a1.Type == arg.CommandType && item.Status != ActionStatus.Completed)
|
|
|
- {
|
|
|
- action = a1;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (action == null)
|
|
|
- {
|
|
|
- LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"NO activated [{arg.ID}] [{arg.Module}] [{arg.CommandType}] in the queue");
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- ModuleName mod = action.Module;
|
|
|
- if (mod == ModuleName.EFEM || mod == ModuleName.EfemRobot || ModuleHelper.IsAligner(mod) || ModuleHelper.IsCooling(mod) || arg.CommandType == EfemOperation.Map)
|
|
|
- {
|
|
|
- if (action.Type != EfemOperation.Light)
|
|
|
- {
|
|
|
- Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.ActionDone, arg.CommandType);
|
|
|
- }
|
|
|
- }
|
|
|
- else if (ModuleHelper.IsLoadPort(mod))
|
|
|
- {
|
|
|
- Singleton<RouteManager>.Instance.EFEM.NotifyLPError(mod );
|
|
|
- }
|
|
|
-
|
|
|
- LOG.Write(eEvent.EV_EFEM_COMMON_INFO, Module, $"efem action [{action.GetType().Name}] [{action.ID}][{action.Module}][{action.Type}] removed from queue");
|
|
|
- _actions.Remove(action);
|
|
|
- }
|
|
|
-
|
|
|
- EV.Notify(EFEMError);
|
|
|
- EV.PostAlarmLog(Module.ToString(), $"{arg.Description}, [{arg.Message}], [{arg.Factor}]");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-}
|