using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; using Venus_Core; using Venus_RT.Modules; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.Equipment; 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 Venus_RT.Devices.YASKAWA; namespace Venus_RT.Devices.EFEM { class JetEfem :EfemBase { private RState _status; private bool _IsHomed; private RobotMoveInfo _robotMoveInfo = new RobotMoveInfo(); private readonly Loadport[] _LPMs = new Loadport[2]; private readonly SignalTower _signalT = new SignalTower(); private readonly AsyncSocket _socket; private EfemMessage _currentMsg; private EfemMessage _backroundMsg; private EfemMessage _revMsg; public override RState Status { get { 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 JetEfem() { _socket = new AsyncSocket(""); _socket.Connect(SC.GetStringValue($"EFEM.IPAddress")); _socket.OnDataChanged += OnReceiveMessage; _socket.OnErrorHappened += OnErrorHappen; _status = RState.Init; _IsHomed = false; } public override void Monitor() { } public override void Terminate() { } 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() { _currentMsg = new EfemMessage { Operation = EfemOperation.Home, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[ModuleName.EFEM] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool Home(ModuleName mod) { if(ModuleHelper.IsLoadPort(mod)) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Home, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } else { _currentMsg = new EfemMessage { Operation = EfemOperation.Home, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } } public override bool Halt() { return true; } public override bool ClearError() { _backroundMsg = new EfemMessage { Operation = EfemOperation.ClearError, Head = EfemMessage.MsgHead.SET, Parameters = new List { "CLEAR" } }; return _socket.Write(_backroundMsg.ToString()); } 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], } }; _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; 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; 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; 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; 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; return _socket.Write(_currentMsg.ToString()); } public override bool Goto(ModuleName station, Hand hand) { 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 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 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 Align(ModuleName mod, float delayTime, WaferSize size) { if (!CheckEfemStatus()) return false; _currentMsg = new EfemMessage { Operation = EfemOperation.Align, Head = EfemMessage.MsgHead.MOV, Parameters = new List { mod.ToHWString(), size.ToString() } }; _status = RState.Running; return _socket.Write(_currentMsg.ToString()); } public override bool SetLamp(LightType light, LightStatus status) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Light, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.STOWER, light.ToString(), status.ToString() } }; return _socket.Write(_backroundMsg.ToString()); } public override bool Load(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Load, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } public override bool Unload(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Unload, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } public override bool ReadCarrierId(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.GET, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } public override bool WriteCarrierId(ModuleName mod, string id) { _backroundMsg = new EfemMessage { Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[mod], id } }; return _socket.Write(_backroundMsg.ToString()); } public override bool ReadTagData(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.GET, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } public override bool WriteTagData(ModuleName mod, string tagData) { _backroundMsg = new EfemMessage { Operation = EfemOperation.CarrierId, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[mod], tagData } }; return _socket.Write(_backroundMsg.ToString()); } public override bool Dock(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Dock, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod]} }; return _socket.Write(_backroundMsg.ToString()); } public override bool Undock(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Undock, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod]} }; return _socket.Write(_backroundMsg.ToString()); } public override bool Clamp(ModuleName mod, bool isUnloadClamp) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Clamp, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } public override bool Unclamp(ModuleName mod) { _backroundMsg = new EfemMessage { Operation = EfemOperation.Unclamp, Head = EfemMessage.MsgHead.MOV, Parameters = new List { Constant.ModuleString[mod] } }; return _socket.Write(_backroundMsg.ToString()); } public override bool SetThickness(ModuleName mod, string thickness) { _backroundMsg = new EfemMessage { Operation = EfemOperation.SetThickness, Head = EfemMessage.MsgHead.SET, Parameters = new List { Constant.ModuleString[mod], thickness.ToUpper() } }; return _socket.Write(_backroundMsg.ToString()); } public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target) { } private void OnReceiveMessage(string RevMsg) { string[] msgs = RevMsg.Split('\r'); foreach (var msg in msgs) { if (string.IsNullOrWhiteSpace(msg)) continue; EfemMessage rec_msg = msg.ToMessage(); switch (rec_msg.Head) { case EfemMessage.MsgHead.ACK: _revMsg = rec_msg; break; case EfemMessage.MsgHead.INF: // 收到INF之后发送ACK确认 string strACK = rec_msg.RawString.Replace("INF", "ACK"); _socket.Write(strACK); EfemMessage ack_msg = strACK.ToMessage(); ack_msg.Direct = MsgDirection.To; _revMsg = rec_msg; OnCommandUpdated(rec_msg); break; case EfemMessage.MsgHead.EVT: OnEventUpdated(new EfemEventArgs { EvtStr = rec_msg.ToParamString(), Module = rec_msg.Port, CommandType = rec_msg.Operation, DataList = rec_msg.Data }); break; case EfemMessage.MsgHead.NAK: case EfemMessage.MsgHead.CAN: case EfemMessage.MsgHead.ABS: OnErrorOccurred(rec_msg); break; } } } private void OnErrorHappen(ErrorEventArgs args) { } 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; } 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); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM System vacuum source pressure low"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[1]) // Bit[1] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMIonizerAlarm); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM Ionizer compressed air error"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[2]) // Bit[2] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMCDAError); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM System compressed air pressure low"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[4]) // Bit[4] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMFlowGaugeSensorError); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM Flow gauge sensor error"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[5]) // Bit[5] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMLeakageAlarm); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM Leakage alarm"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[10]) // Bit[10] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMIonizerAlarm); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM Ionizer alarm"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[11]) // Bit[11] ON=Normal, OFF=Abnormal { //EV.Notify(EFEMFFUAlarm); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "FFU alarm"); Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } if (!baData1[13]) // Bit[13] ON=RUN, OFF=Maintain { //EV.Notify(EFEMOffline); LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, "EFEM switch to Maintain mode, HomeAll to recover"); } // 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(_currentMsg.Operation != message.Operation) { return; } switch(message.Operation) { case EfemOperation.ClearError: case EfemOperation.Pick: case EfemOperation.Place: case EfemOperation.Extend: case EfemOperation.Goto: _status = RState.End; break; } } } }