using System; using System.Diagnostics; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Collections; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.SubstrateTrackings; using Aitex.Sorter.Common; using Aitex.Core.Common; using Aitex.Core.RT.SCCore; using Aitex.Core.RT.Log; using Aitex.Core.Util; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot; using System.Collections.Concurrent; using CyberX8_Core; using CyberX8_RT.Devices.YASKAWA; using CyberX8_RT.Devices; using CyberX8_RT.Modules; using CyberX8_RT; namespace CyberX8_RT.Devices.EFEM { public class JetEfem : EfemBase { private RState _status; private bool _IsHomed; private string _waferPresence; private bool _bIsUnloadClamp; private RobotMoveInfo _robotMoveInfo = new RobotMoveInfo(); private readonly Loadport[] _LPMs = new Loadport[3]; private readonly SignalTower _signalT = new SignalTower(); private readonly AsyncSocket _socket; private EfemMessage _currentMsg; private EfemMessage _backroundMsg; private EfemMessage _revMsg; private bool _LiftIsUp = false; private bool _LiftIsDown = false; private R_TRIG _busyTrig = new R_TRIG(); private Stopwatch _busyWatch = new Stopwatch(); public override RState Status { get { _busyTrig.CLK = _status == RState.Running; if (_busyTrig.Q) { _busyWatch.Restart(); } else if (_busyTrig.M) { if (_busyWatch.ElapsedMilliseconds > 30000) { _busyWatch.Stop(); _status = RState.Timeout; } } return _status; } } public override bool IsHomed { get { return _IsHomed; } } public override RobotMoveInfo TMRobotMoveInfo { get { return _robotMoveInfo; } } public override ILoadport this[ModuleName mod] { get { if (!ModuleHelper.IsLoadPort(mod)) throw new ApplicationException($"{mod} is NOT Loadport"); return _LPMs[mod - ModuleName.LP1]; } } public override bool LiftIsUp { get { return _LiftIsUp; } } public override bool LiftIsDown { get { return _LiftIsDown; } } private BlockingCollection blockingCollection = new BlockingCollection(); public JetEfem() { _socket = new AsyncSocket(""); _socket.Connect(SC.GetStringValue($"EFEM.IPAddress")); _socket.OnDataChanged += OnReceiveMessage; _socket.OnErrorHappened += OnErrorHappen; _status = RState.Init; _IsHomed = false; _busyTrig.RST = true; _LPMs[0] = new Loadport(ModuleName.LP1, this); _LPMs[1] = new Loadport(ModuleName.LP2, this); _LPMs[2] = new Loadport(ModuleName.LP3, this); CarrierManager.Instance.SubscribeLocation(ModuleName.LP1.ToString(), 1); CarrierManager.Instance.SubscribeLocation(ModuleName.LP2.ToString(), 1); CarrierManager.Instance.SubscribeLocation(ModuleName.LP3.ToString(), 1); WaferManager.Instance.SubscribeLocation(ModuleName.EfemRobot, 2); WaferManager.Instance.SubscribeLocation(ModuleName.Aligner1, 1); // _subscribeLoc(ModuleName.EfemRobot, 2); SubscribeLocation(ModuleName.Aligner1, 1); SubscribeLocation(ModuleName.LP1, SC.GetValue("EFEM.LoadPort.SlotNumber")); SubscribeLocation(ModuleName.LP2, SC.GetValue("EFEM.LoadPort.SlotNumber")); SubscribeLocation(ModuleName.LP3, SC.GetValue("EFEM.LoadPort.SlotNumber")); Task.Run(() => { foreach (var data in blockingCollection.GetConsumingEnumerable()) { _robotMoveInfo.Action = data.Action; _robotMoveInfo.ArmTarget = data.Hand == Hand.Blade1 ? RobotArm.ArmA : (data.Hand == Hand.Both ? RobotArm.Both : RobotArm.ArmB); _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{data.Target}"; System.Threading.Thread.Sleep(600); } }); } private void SubscribeLocation(ModuleName module,int waferCount) { if (ModuleHelper.IsInstalled(module)) { WaferManager.Instance.SubscribeLocation(module, waferCount); } } public override void Monitor() { } public override void Terminate() { } public override bool SetRobotSpeed(ModuleName mod, int speed) { return false; } public override bool SetWaferSize(ModuleName mod, int size) { return false; } public override bool RobotPowerOn(ModuleName mod, bool status) { return false; } public override bool Vacuum(ModuleName mod, bool state) { return false; } public override void Reset() { _status = RState.End; } public override void SetOnline(bool online) { } public override void SetOnline(ModuleName mod, bool online) { } public override void SetBusy(ModuleName mod, bool online) { _status = RState.Running; } public override bool HomeAll() { if (_status == RState.Running) _backroundMsg = _currentMsg; _currentMsg = new EfemMessage { Module = ModuleName.EFEM, Operation = EfemOperation.Home, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[ModuleName.EFEM] } }; _status = RState.Running; string data = _currentMsg.ToString(); SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM); return _socket.Write(data); } public override bool Home(ModuleName mod) { if (_status == RState.Running) _backroundMsg = _currentMsg; if (ModuleHelper.IsLoadPort(mod)) { _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Home, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } else { _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Home, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } } public override bool OriginalSearch(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = ModuleName.EFEM, Operation = EfemOperation.Orgsh, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool CheckWaferPresence() { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = ModuleName.EFEM, Operation = EfemOperation.StateTrack, Head = EfemMessage.MsgHead.GET, Parameters = new List { "TRACK" } }; _waferPresence = string.Empty; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override string GetWaferPresence() { return _waferPresence; } public override bool Halt() { if (_status == RState.Running) _backroundMsg = _currentMsg; _currentMsg = new EfemMessage { Module = ModuleName.EFEM, Operation = EfemOperation.EmsStop, Head = EfemMessage.MsgHead.MOV, }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool ClearError() { _currentMsg = new EfemMessage { Module = ModuleName.EFEM, Operation = EfemOperation.ClearError, Head = EfemMessage.MsgHead.SET, Parameters = new List { "CLEAR" } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool CloseBuzzer() { return false; } public override bool PickExtend(ModuleName chamber, int slot, Hand hand) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Extend, Head = EfemMessage.MsgHead.MOV, Parameters = new List { chamber.ToHWString(), ExtendPos.GB.ToString(), Constant.ArmString[hand], } }; SetRobotMovingInfo(RobotAction.Extending, hand, chamber); _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool PickRetract(ModuleName chamber, int slot, Hand hand) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Extend, Head = EfemMessage.MsgHead.MOV, Parameters = new List { chamber.ToHWString(), ExtendPos.G4.ToString(), Constant.ArmString[hand], } }; _status = RState.Running; SetRobotMovingInfo(RobotAction.Retracting, hand, chamber); return _socket.Write(_currentMsg.ToString()); } public override bool PlaceExtend(ModuleName chamber, int slot, Hand hand) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Extend, Head = EfemMessage.MsgHead.MOV, Parameters = new List { chamber.ToHWString(), ExtendPos.PB.ToString(), Constant.ArmString[hand], } }; _status = RState.Running; SetRobotMovingInfo(RobotAction.Extending, hand, chamber); return _socket.Write(_currentMsg.ToString()); } public override bool PlaceRetract(ModuleName chamber, int slot, Hand hand) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Extend, Head = EfemMessage.MsgHead.MOV, Parameters = new List { chamber.ToHWString(), ExtendPos.P4.ToString(), Constant.ArmString[hand], } }; _status = RState.Running; SetRobotMovingInfo(RobotAction.Retracting, hand, chamber); return _socket.Write(_currentMsg.ToString()); } public override bool Pick(ModuleName station, int slot, Hand hand) { if (!CheckEfemStatus()) return false; Position SrcPos = new Position { Module = station, Slot = (byte)slot }; _currentMsg = new EfemMessage { Operation = EfemOperation.Pick, Head = EfemMessage.MsgHead.MOV, Parameters = new List { SrcPos.ToHWString(), Constant.ArmString[hand], //WaferSize.WS12.ToString() } }; _status = RState.Running; SetRobotMovingInfo(RobotAction.Picking, hand, station); return _socket.Write(_currentMsg.ToString()); } public override bool Place(ModuleName station, int slot, Hand hand) { if (!CheckEfemStatus()) return false; Position DestPos = new Position { Module = station, Slot = (byte)slot }; _currentMsg = new EfemMessage { Operation = EfemOperation.Place, Head = EfemMessage.MsgHead.MOV, Parameters = new List { DestPos.ToHWString(), Constant.ArmString[hand], //WaferSize.WS12.ToString() } }; _status = RState.Running; SetRobotMovingInfo(RobotAction.Placing, hand, station); return _socket.Write(_currentMsg.ToString()); } public override bool Goto(ModuleName station, Hand hand, string updown = "UP") { if (!CheckEfemStatus()) return false; Position DestPos = new Position { Module = station, Slot = (byte)0 }; _currentMsg = new EfemMessage { Operation = EfemOperation.Goto, Head = EfemMessage.MsgHead.MOV, Parameters = new List { DestPos.ToHWString(), Constant.ArmString[hand], WaferSize.WS12.ToString() } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Grip(Hand blade, bool isGrip) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Grip, Head = EfemMessage.MsgHead.SET, Parameters = new List { isGrip ? "ON":"OFF", Constant.ArmString[blade] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool GotoMap(ModuleName mod, Hand hand, string extend = "EX") { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support GotoMap"); return false; } public override bool RequestMapResult(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support RequestMapResult"); return false; } public override bool Map(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Map, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool GetWaferSize(ModuleName mod) { return true; } public override bool SetPinUp(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Lift, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod], "UP" } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool SetPinDown(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Lift, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod], "DOWN" } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool SetAlignAngle(ModuleName mod, double angle) { _status = RState.End; return true; } public override bool Align(ModuleName mod, double angle, float delayTime, WaferSize size) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Align, Head = EfemMessage.MsgHead.MOV, Parameters = new List { $"A{angle.ToString("000.00")}" } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool SetLamp(LightType light, LightStatus status) { if (Status == RState.Running) { LOG.Write(eEvent.ERR_EFEM_ROBOT, ModuleName.EFEM, "EFEM is busy, please wait a minute"); return false; } _currentMsg = new EfemMessage { Module = ModuleName.EFEM, Operation = EfemOperation.Light, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.STOWER, light.ToString(), status.ToString() } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Load(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Load, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Unload(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Unload, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool ReadCarrierId(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.GET, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool WriteCarrierId(ModuleName mod, string id) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[mod], id } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool ReadTagData(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.GET, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool WriteTagData(ModuleName mod, string tagData) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[mod], tagData } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Dock(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Dock, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Undock(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Undock, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Clamp(ModuleName mod, bool isUnloadClamp) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Clamp, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; _bIsUnloadClamp = isUnloadClamp; return _socket.Write(_currentMsg.ToString()); } public override bool Unclamp(ModuleName mod) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.Unclamp, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool SetThickness(ModuleName mod, string thickness) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Module = mod, Operation = EfemOperation.SetThickness, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[mod], thickness.ToUpper() } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target) { blockingCollection.Add(new RobotAnimationData(action, hand, target)); } private void OnReceiveMessage(string RevMsg) { string[] msgs = RevMsg.Split('\r'); foreach (var msg in msgs) { if (string.IsNullOrWhiteSpace(msg)) continue; EfemMessage rec_msg = JetMessageHandler.Instance.ToMessage(msg); switch (rec_msg.Head) { case EfemMessage.MsgHead.ACK: if (msg.Contains("ERROR")) { _revMsg = rec_msg; } break; case EfemMessage.MsgHead.INF: // 收到INF之后发送ACK确认 string strACK = rec_msg.RawString.Replace("INF", "ACK"); SendBack(strACK); EfemMessage ack_msg = strACK.ToMessage(); ack_msg.Direct = MsgDirection.To; _revMsg = rec_msg; OnCommandUpdated(rec_msg); SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot); break; case EfemMessage.MsgHead.EVT: OnEventUpdated(new EfemEventArgs { EvtStr = rec_msg.ToParamString(), Module = rec_msg.Module, CommandType = rec_msg.Operation, DataList = rec_msg.Data }); if (rec_msg.Operation == EfemOperation.Home) { SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM); } break; case EfemMessage.MsgHead.NAK: case EfemMessage.MsgHead.CAN: case EfemMessage.MsgHead.ABS: OnErrorOccurred(rec_msg); break; } } } private void OnErrorHappen(ErrorEventArgs args) { _status = RState.Failed; Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } private void OnErrorOccurred(EfemMessage message) { string description = string.Empty; switch (message.Head) { case EfemMessage.MsgHead.NAK: description = Constant.FactorString[message.Factor]; break; case EfemMessage.MsgHead.CAN: description = Constant.FactorString.ContainsKey(message.Factor) ? Constant.FactorString[message.Factor] : message.Factor; break; case EfemMessage.MsgHead.ABS: description = $"{message.Data[0]}, {message.Data[1]}"; break; } _status = RState.Failed; Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,description); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, $"{description}, [{message.Data[0]}], [{message.Factor}]"); } private void OnEventUpdated(EfemEventArgs eArg) { 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 // Post warning and alarm if (!baData1[0]) // Bit[0] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMVacuumPressureError); string error = "EFEM System vacuum source pressure low"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,error); } if (!baData1[1]) // Bit[1] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMIonizerAlarm); string error = "EFEM Ionizer compressed air error"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,error); } if (!baData1[2]) // Bit[2] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMCDAError); string error = "EFEM System compressed air pressure low"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error, error); } if (!baData1[4]) // Bit[4] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMFlowGaugeSensorError); string error = "EFEM Flow gauge sensor error"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,error); } if (!baData1[5]) // Bit[5] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMLeakageAlarm); string error = "EFEM Leakage alarm"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,error); } if (!baData1[10]) // Bit[10] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMIonizerAlarm); string error = "EFEM Ionizer alarm"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,error); } if (!baData1[11]) // Bit[11] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMFFUAlarm); string error = "FFU alarm"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error,error); } if (!baData1[13]) // Bit[13] ON=RUN, OFF=Maintain { //EV.Notify(EFEMOffline); string error = "EFEM switch to Maintain mode, HomeAll to recover"; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, error); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error, error); } // 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 OnCommandUpdated(EfemMessage message) { if (message.Operation != EfemOperation.Ready) { if (_currentMsg.Operation != message.Operation && (_backroundMsg == null || _backroundMsg.Operation != message.Operation)) { LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EfemRobot, $"OnCommandUpdated() unexpected return: {message.Operation}, expect: {_currentMsg.Operation}"); return; } } switch (message.Operation) { case EfemOperation.ClearError: case EfemOperation.Align: case EfemOperation.Map: case EfemOperation.Pick: case EfemOperation.Place: case EfemOperation.Extend: case EfemOperation.Goto: case EfemOperation.Orgsh: case EfemOperation.EmsStop: case EfemOperation.Light: _status = RState.End; break; case EfemOperation.StateTrack: { _waferPresence = message.Data.Count >= 1 ? message.Data.First() : string.Empty; //upper arm if (_waferPresence[0] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1)) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 1, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 1)) { LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.EfemRobot} upper arm has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //lower arm if (_waferPresence[1] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.EfemRobot} lower arm has wafer information, while EFEM return empty, manually delete if really no wafer"); } } //aligner1 if (_waferPresence[2] == '1') { if (WaferManager.Instance.CheckNoWafer(ModuleName.Aligner1, 0)) { WaferManager.Instance.CreateWafer(ModuleName.Aligner1, 0, WaferStatus.Normal); } } else { if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner1, 0)) { LOG.Write(eEvent.ERR_EFEM_ROBOT, Module, $" {ModuleName.Aligner1} has wafer information, while EFEM return empty, manually delete if really no wafer"); } } _IsHomed = true; _status = RState.End; } break; case EfemOperation.Home: { if (_currentMsg.Module == ModuleName.EFEM) { _LPMs[0].OnHomed(); _LPMs[1].OnHomed(); _LPMs[2].OnHomed(); } else if (ModuleHelper.IsLoadPort(_currentMsg.Module)) { _LPMs[_currentMsg.Module - ModuleName.LP1].OnHomed(); } _status = RState.End; } break; case EfemOperation.Load: { _LPMs[message.Module - ModuleName.LP1].OnLoaded(); _status = RState.End; } break; case EfemOperation.Unload: { _LPMs[message.Module - ModuleName.LP1].OnUnloaded(); _status = RState.End; } break; case EfemOperation.CarrierId: { if (message.Head == EfemMessage.MsgHead.GET) { _LPMs[message.Module - ModuleName.LP1].OnCarrierIDRead(message.Data.First()); } else { _LPMs[message.Module - ModuleName.LP1].OnCarrierIDWrite(message.Data.First()); } _status = RState.End; } break; case EfemOperation.Clamp: { _LPMs[message.Module - ModuleName.LP1].OnClamped(_bIsUnloadClamp); _status = RState.End; } break; case EfemOperation.Unclamp: { _LPMs[message.Module - ModuleName.LP1].OnUnclamped(); _status = RState.End; } break; case EfemOperation.Grip: { if (_currentMsg.Parameters[1] == "ARM2") { GripStateBlade1 = _currentMsg.Parameters[0]; } else { GripStateBlade2 = _currentMsg.Parameters[0]; } _status = RState.End; } break; case EfemOperation.Ready: { Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.CommReady); } break; case EfemOperation.Lift: { if (_currentMsg.Parameters[1] == "UP") { _LiftIsUp = true; _LiftIsDown = false; } else if (_currentMsg.Parameters[1] == "DOWN") { _LiftIsUp = false; _LiftIsDown = true; } _status = RState.End; } break; } } void SendBack(string data) { _socket.Write(data + '\r'); } } }