using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Collections; using PunkHPX8_Core; using PunkHPX8_RT.Modules; 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 PunkHPX8_RT.Devices.YASKAWA; using System.Collections.Concurrent; using System.Diagnostics; using System.Data.SqlTypes; using System.Windows.Media.Media3D; using System.ComponentModel; using MECF.Framework.Common.Beckhoff.Station; using System.Runtime.Remoting.Contexts; using System.Windows.Markup; using PunkHPX8_RT.Modules.LPs; using MECF.Framework.Common.ToolLayout; namespace PunkHPX8_RT.Devices.EFEM { public class SunWayRobot : EfemBase { #region 常量 private const string NONE = "None"; #endregion private RState _status; private bool _IsHomed; private bool _bIsUnloadClamp; private RobotMoveInfo _robotMoveInfo = new RobotMoveInfo(); private readonly SignalTower _signalT = new SignalTower(); private readonly AsyncSocket _socket; private EfemMessage _currentMessage; private string _error; private bool _LiftIsUp = false; private bool _LiftIsDown = false; private R_TRIG _busyTrig = new R_TRIG(); private Stopwatch _busyWatch = new Stopwatch(); private Dictionary _moduleStationNumberDictionary = new Dictionary(); private Dictionary _armString = new Dictionary { [Hand.Blade1] = "B", [Hand.Blade2] = "A" }; public override RState Status { get { _busyTrig.CLK = _status == RState.Running; if (_busyTrig.Q) { _busyWatch.Restart(); } else if (_busyTrig.M) { int timeOut = 5000; if ( _currentMessage.Operation == EfemOperation.Home || _currentMessage.Operation == EfemOperation.Map || _currentMessage.Operation == EfemOperation.Pick || _currentMessage.Operation == EfemOperation.Place) { timeOut = 30000; } if (_busyWatch.ElapsedMilliseconds > timeOut) { _busyWatch.Stop(); _status = RState.Timeout; } } return _status; } } public override bool IsHomed { get { return _IsHomed; } } public override RobotMoveInfo TMRobotMoveInfo { get { return _robotMoveInfo; } } public override bool LiftIsUp { get { return _LiftIsUp; } } public override bool LiftIsDown { get { return _LiftIsDown; } } private BlockingCollection blockingCollection = new BlockingCollection(); private string _address = ""; private bool _isResumeRDYReceived = false; private bool _isPauseRDYReceived = false; private bool _isActionRDYReceived = false; private bool _isInPauseStatus = false; public override bool IsResumeRDYReceived { get { return _isResumeRDYReceived; } } public override bool IsPauseRDYReceived { get { return _isPauseRDYReceived; } } public override bool IsActionRDYReceived { get { return _isActionRDYReceived; } } public override bool IsInPauseStatus { get { return _isInPauseStatus; } } public SunWayRobot() { _socket = new AsyncSocket("","",DataType.Ascii,true); try { _address = SC.GetStringValue($"EFEM.IPAddress"); _socket.Connect(_address); _socket.OnConnect += Socket_OnConnect; _socket.OnDataChanged += OnReceiveMessage; _socket.OnErrorHappened += OnErrorHappen; } catch(Exception ex) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, "EFEM", ex.Message); } _status = RState.End; _IsHomed = false; _busyTrig.RST = true; InitializeModuleStation(ModuleName.LP1); InitializeModuleStation(ModuleName.LP2); InitializeModuleStation(ModuleName.LP3); InitializeModuleStation(ModuleName.Dummy1); InitializeModuleStation(ModuleName.Dummy2); InitializeModuleStation(ModuleName.Aligner1); InitializeModuleStation(ModuleName.SRD1); InitializeModuleStation(ModuleName.SRD2); InitializeVPWModuleStation(ModuleName.VPW1); InitializeVPWModuleStation(ModuleName.VPW2); InitializePlatingCellModuleStation(ModuleName.PlatingCell1); InitializePlatingCellModuleStation(ModuleName.PlatingCell2); InitializePlatingCellModuleStation(ModuleName.PlatingCell3); InitializePlatingCellModuleStation(ModuleName.PlatingCell4); 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); WaferManager.Instance.SubscribeLocation(ModuleName.LP1, SC.GetValue("EFEM.LoadPort.SlotNumber")); WaferManager.Instance.SubscribeLocation(ModuleName.LP2, SC.GetValue("EFEM.LoadPort.SlotNumber")); WaferManager.Instance.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.BladeDirection = data.Flip; _robotMoveInfo.BladeTarget = $"{_robotMoveInfo.ArmTarget}.{data.Target}.{data.Flip}"; System.Threading.Thread.Sleep(600); } }); } /// /// 初始化Module Station /// /// private void InitializeModuleStation(ModuleName module) { int cassete200Station = SC.GetValue($"EFEM.{module}.Cassete200Station_Blade1_Upper"); _moduleStationNumberDictionary[$"{module}_200_Blade1_Upper"] = cassete200Station; int cassete150Station = SC.GetValue($"EFEM.{module}.Cassete150Station_Blade1_Upper"); _moduleStationNumberDictionary[$"{module}_150_Blade1_Upper"] = cassete150Station; int cassete100Station = SC.GetValue($"EFEM.{module}.Cassete100Station_Blade1_Upper"); _moduleStationNumberDictionary[$"{module}_100_Blade1_Upper"]=cassete100Station; } /// /// 初始化vpw module Station /// /// private void InitializeVPWModuleStation(ModuleName module) { int cassete200Station_Blade1_Upper = SC.GetValue($"EFEM.{module}.Cassete200Station_Blade1_Upper"); _moduleStationNumberDictionary[$"{module}_200_Blade1_Upper"] = cassete200Station_Blade1_Upper; int cassete200Station_Blade2_Upper = SC.GetValue($"EFEM.{module}.Cassete200Station_Blade2_Upper"); _moduleStationNumberDictionary[$"{module}_200_Blade2_Upper"] = cassete200Station_Blade2_Upper; int cassete200Station_Blade2_Down = SC.GetValue($"EFEM.{module}.Cassete200Station_Blade2_Down"); _moduleStationNumberDictionary[$"{module}_200_Blade2_Down"] = cassete200Station_Blade2_Down; int cassete150Station_Blade1_Upper = SC.GetValue($"EFEM.{module}.Cassete150Station_Blade1_Upper"); _moduleStationNumberDictionary[$"{module}_150_Blade1_Upper"] = cassete150Station_Blade1_Upper; int cassete150Station_Blade2_Upper = SC.GetValue($"EFEM.{module}.Cassete150Station_Blade2_Upper"); _moduleStationNumberDictionary[$"{module}_150_Blade2_Upper"] = cassete150Station_Blade2_Upper; int cassete150Station_Blade2_Down = SC.GetValue($"EFEM.{module}.Cassete150Station_Blade2_Down"); _moduleStationNumberDictionary[$"{module}_150_Blade2_Down"] = cassete150Station_Blade2_Down; int cassete100Station_Blade1_Upper = SC.GetValue($"EFEM.{module}.Cassete100Station_Blade1_Upper"); _moduleStationNumberDictionary[$"{module}_100_Blade1_Upper"] = cassete100Station_Blade1_Upper; int cassete100Station_Blade2_Upper = SC.GetValue($"EFEM.{module}.Cassete100Station_Blade2_Upper"); _moduleStationNumberDictionary[$"{module}_100_Blade2_Upper"] = cassete100Station_Blade2_Upper; int cassete100Station_Blade2_Down = SC.GetValue($"EFEM.{module}.Cassete100Station_Blade2_Down"); _moduleStationNumberDictionary[$"{module}_100_Blade2_Down"] = cassete100Station_Blade2_Down; } /// /// 初始化Platingcell Module Station /// /// private void InitializePlatingCellModuleStation(ModuleName module) { int cassete200Station = SC.GetValue($"EFEM.{module}.Cassete200Station_Blade2_Down"); _moduleStationNumberDictionary[$"{module}_200_Blade2_Down"] = cassete200Station; int cassete150Station = SC.GetValue($"EFEM.{module}.Cassete150Station_Blade2_Down"); _moduleStationNumberDictionary[$"{module}_150_Blade2_Down"] = cassete150Station; int cassete100Station = SC.GetValue($"EFEM.{module}.Cassete100Station_Blade2_Down"); _moduleStationNumberDictionary[$"{module}_100_Blade2_Down"] = cassete100Station; } private void Socket_OnConnect() { Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.CommReady); LOG.WriteLog(eEvent.EV_EFEM_COMMON_INFO, Module.ToString(), $"connect {_address} success"); } private void OnErrorHappen(ErrorEventArgs args) { _status = RState.Failed; if (_error != args.Reason) { _error = args.Reason; LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, Module, $"{Module} {_error}"); } Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error); } public override void Monitor() { } public override void Terminate() { } public override void Reset() { _status = RState.End; _currentMessage = null; } 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&&_currentMessage!=null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot home All"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false ; } _status = RState.Running; string data = "HOME ALL\r"; _currentMessage =new EfemMessage(){ Operation= EfemOperation.Home, Module=ModuleName.EFEM }; //SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM); return WriteCommand(data); } public override bool Home(ModuleName mod) { if (_status == RState.Running && _currentMessage!= null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot home {mod}"); return false; } if (mod != ModuleName.Aligner1&&mod!=ModuleName.EfemRobot) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{mod} can not support home method"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if(mod == ModuleName.EfemRobot) SetRobotMovingInfo(RobotAction.Homing, Hand.Blade1, ModuleName.EfemRobot,Flip.Upper); _status = RState.Running; string cmd = "Home ALL\r"; if (mod == ModuleName.Aligner1) { cmd = "ALIGNER HOME\r"; } _currentMessage = new EfemMessage() { Operation = EfemOperation.Home, Module = ModuleName.Aligner1 }; return WriteCommand(cmd); } public override bool OriginalSearch(ModuleName mod) { return true; } public override bool CheckWaferPresence() { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot check wafer"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if (!CheckEfemStatus()) return false; _currentMessage = new EfemMessage() { Operation = EfemOperation.StateTrack, Module = ModuleName.EfemRobot }; _status = RState.Running; string cmd = $"RQ LOAD {_armString[Hand.Blade1]}\r"; return WriteCommand(cmd); } public override string GetWaferPresence() { return ""; } public override bool Halt() { //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.Abort, Module = ModuleName.EfemRobot }; SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EFEM,Flip.Upper); string cmd = "HALT\r"; return WriteCommand(cmd); } public override bool Pause() { //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } string cmd = "PAUSE\r"; bool result = WriteCommand(cmd); if (result) { _isInPauseStatus = true; //进入pause状态 } else { _isInPauseStatus = false; LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Send pause message error"); } return result; } public override bool Resume() { _isActionRDYReceived = false; //把收到resume信号后执行resume动作成功的变量置false //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } string cmd = "RESUME\r"; return WriteCommand(cmd); } public override bool ClearError() { return true; } public override bool CloseBuzzer() { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.TurnOffBuzzer]}"); return false; } public override bool PickExtend(ModuleName chamber, int slot, Hand hand) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Extend]}"); return false; } public override bool PickRetract(ModuleName chamber, int slot, Hand hand) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Extend]}"); return false; } public override bool PlaceExtend(ModuleName chamber, int slot, Hand hand) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Extend]}"); return false; } public override bool PlaceRetract(ModuleName chamber, int slot, Hand hand) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Extend]}"); return false; } public override bool Pick(ModuleName station, int slot, Hand hand, Flip flip) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot pick"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } //判断Loadport的门是否打开 //if (ModuleHelper.IsLoadPort(station) && !GetLoadPort(station).IsDoorOpened) //{ // LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{station}'s Door is Closed, Cannot Execute Pick Action"); // return false; //} if (!CheckEfemStatus()) return false; int waferSize = GetModuleSlotWaferSize(station,slot); if (waferSize == 0) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{station} slot {slot} wafer size is 0, Cannot Execute Pick Action"); return false; } string strModuleWaferSize = $"{station}_{waferSize}_{hand}_{flip}"; if (!_moduleStationNumberDictionary.ContainsKey(strModuleWaferSize)) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{station}'s number is not exist, Cannot Execute Pick Action"); return false; } int stationNumber= _moduleStationNumberDictionary[strModuleWaferSize]; string strFlip = flip == Flip.Down ? " FLIP" : ""; string cmd = $"PICK {stationNumber} SLOT {slot+1} ARM {_armString[hand]}{strFlip}\r"; if(ModuleHelper.IsAligner(station)||ModuleHelper.IsSRD(station)||ModuleHelper.IsVPWCell(station) || ModuleHelper.IsPlatingCell(station)) { cmd = $"PICK {stationNumber} SLOT 1 ARM {_armString[hand]}{strFlip}\r"; } _currentMessage = new EfemMessage() { Operation=EfemOperation.Pick, Flip = flip }; _status = RState.Running; SetRobotMovingInfo(RobotAction.Picking, hand, station, flip); return WriteCommand(cmd); } private Loadport GetLoadPort(ModuleName station) { LoadPortModule loadPortModule = Singleton.Instance.EFEM.GetLoadportModule(station - ModuleName.LP1); return loadPortModule.LPDevice; } public override bool Place(ModuleName station, int slot, Hand hand,Flip flip) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot place"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } //判断Loadport的门是否打开 //if (ModuleHelper.IsLoadPort(station) && !GetLoadPort(station).IsDoorOpened) //{ // LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{station}'s Door is Closed, Cannot Execute Pick Action"); // return false; //} if (!CheckEfemStatus()) return false; int waferSize = GetModuleSlotWaferSize(ModuleName.EfemRobot, (int)hand); if (waferSize == 0) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{station} slot {slot} wafer size is 0, Cannot Execute Place Action"); return false; } string strModuleWaferSize = $"{station}_{waferSize}_{hand}_{flip}"; _currentMessage = new EfemMessage() { Operation = EfemOperation.Place, Flip = flip }; _status = RState.Running; int stationNumber = _moduleStationNumberDictionary[strModuleWaferSize]; string strFlip = flip == Flip.Down ? " FLIP" : ""; string cmd = $"PLACE {stationNumber} SLOT {slot+1} ARM {_armString[hand]}{strFlip}\r"; if (ModuleHelper.IsSRD(station) || ModuleHelper.IsVPWCell(station) || ModuleHelper.IsPlatingCell(station)) { cmd = $"PLACE {stationNumber} SLOT 1 ARM {_armString[hand]}{strFlip}\r"; } if (ModuleHelper.IsAligner(station)) { cmd = $"PLACE {stationNumber} PHOME\r"; } SetRobotMovingInfo(RobotAction.Placing, hand, station, flip); return WriteCommand(cmd); } public override bool Goto(ModuleName station, Hand hand, string updown = "Upper") { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot goto"); return false; } if (!CheckEfemStatus()) return false; //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.Goto }; int waferSize = GetModuleNameWaferSize(station); if (waferSize == 0) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"wafersize is 0"); return false; } string strModuleWaferSize = $"{station}_{waferSize}"; int stationNumber = _moduleStationNumberDictionary[strModuleWaferSize]; string cmd = $"GOTO N {stationNumber} R EX Z {updown} ARM SLOT 1 {_armString[hand]}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool Grip(Hand blade, bool isGrip) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Grip]}"); return false; } public override bool GotoMap(ModuleName mod,Hand hand,string extend="EX") { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot goto map"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if (!CheckEfemStatus()) return false; int waferSize = GetModuleNameWaferSize(mod); if (waferSize == 0) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"wafersize is 0"); return false; } string strModuleWaferSize = $"{mod}_{waferSize}_{hand}_Upper"; int stationNumber = _moduleStationNumberDictionary[strModuleWaferSize]; string cmd = $"GOTO N {stationNumber} MAP {extend} ARM {_armString[hand]}\r"; _currentMessage = new EfemMessage() { Operation = EfemOperation.Goto, Module= mod }; _status = RState.Running; return WriteCommand(cmd); } public override bool Map(ModuleName mod) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot map"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if (!CheckEfemStatus()) return false; int waferSize = GetModuleNameWaferSize(mod); if (waferSize == 0) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"wafersize is 0"); return false; } string strModuleWaferSize = $"{mod}_{waferSize}_Blade1_Upper"; int stationNumber = _moduleStationNumberDictionary[strModuleWaferSize]; _currentMessage = new EfemMessage() { Operation = EfemOperation.Map, Module = mod }; string cmd = $"MAP {stationNumber} ARM {_armString[Hand.Blade1]}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool RequestMapResult(ModuleName mod) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot request map"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if (!CheckEfemStatus()) return false; int waferSize = GetModuleNameWaferSize(mod); if (waferSize == 0) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"wafersize is 0"); return false; } string strModuleWaferSize = $"{mod}_{waferSize}_Blade1_Upper"; int stationNumber = _moduleStationNumberDictionary[strModuleWaferSize]; _currentMessage = new EfemMessage() { Operation = EfemOperation.RequestMapResult, Module = mod }; string cmd = $"RSR {stationNumber} ARM {_armString[Hand.Blade1]}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool Vacuum(ModuleName mod,bool VacuumState) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot vacuum"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.Vacuum, Module = mod }; _status = RState.Running; string strVacuum = VacuumState ? "ON" : "OFF"; string cmd = ""; if (ModuleName.Aligner1 == mod) { cmd = $"ALIGNER VAC {strVacuum}\r"; } else { cmd = $"VAC {strVacuum} ARM {_armString[Hand.Blade1]}\r"; } return WriteCommand(cmd); } public override bool GetWaferSize(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support GetWaferSize"); return false; } public override bool SetWaferSize(ModuleName mod, int WaferSize) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support SetWaferSize"); return false; } public override bool SetPinUp(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Lift]}"); return false; } public override bool SetPinDown(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.Lift]}"); return false; } public override bool SetAlignWaferSize() { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot Align Wafer Size"); return false; } if (!CheckEfemStatus()) return false; if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{ModuleName.EfemRobot} has no wafer, Cannot Execute Set aligner wafersize"); return false; } int waferSize = GetModuleSlotWaferSize(ModuleName.EfemRobot, 0); if (waferSize == 0) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{ModuleName.EfemRobot} wafer size is 0, Cannot Execute Set aligner wafersize"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.AlignWaferSize }; string cmd = $"SET ALIGNER WAFERSIZE {waferSize}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool SetAlignFlatType(int flatType) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot Align flat type"); return false; } if (!CheckEfemStatus()) return false; //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.AlignFlatType }; string cmd = $"SET ALIGNER WAFERTYPE {flatType}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool SetAlignDistance() { int distance200 = SC.GetValue("EFEM.Aligner1.Aligner200Distance"); int distance150 = SC.GetValue("EFEM.Aligner1.Aligner150Distance"); int distance100 = SC.GetValue("EFEM.Aligner1.Aligner100Distance"); if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot Align flat type"); return false; } if (!CheckEfemStatus()) return false; //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if (!WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot, 0)) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{ModuleName.EfemRobot} has no wafer, Cannot Execute Set aligner wafersize"); return false; } int waferSize = GetModuleSlotWaferSize(ModuleName.EfemRobot, 0); if (waferSize == 0) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{ModuleName.EfemRobot} wafer size is 0, Cannot Execute Set aligner wafersize"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.AlignDistance }; int distance = distance200; if (waferSize == (int)WaferSize.WS6) { distance = distance150; } else if (waferSize == (int)WaferSize.WS4) { distance = distance100; } string cmd = $"SET ALIGNER WAFERDISTANCE {distance}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool SetAlignAngle(ModuleName mod, double angle) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot Align Angle"); return false; } if (!CheckEfemStatus()) return false; //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.Align, }; string cmd = $"SET ALIGNER POSTPOS 1 POS {angle*1000}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool SetRobotSpeed(ModuleName mod, int speed) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot Speed"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } _currentMessage = new EfemMessage() { Operation = EfemOperation.Speed }; string cmd = $"SET ACTION SPEEDS {speed}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool RobotPowerOn(ModuleName mod, bool Status) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot PowerOn"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } string status = Status? "ON":"OFF"; _currentMessage = new EfemMessage() { Operation = EfemOperation.PowerOn }; string cmd = $"SET SERVOS {status}\r"; _status = RState.Running; return WriteCommand(cmd); } public override bool Align(ModuleName mod, double angle, float delayTime, WaferSize size) { if (_status == RState.Running && _currentMessage != null) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"Current Msg {_currentMessage.Operation} is Running,cannot Align"); return false; } //判断socket是否链接 if (!_socket.IsConnected) { LOG.WriteLog(eEvent.ERROR_EFEM_COMMUNICATION, Module.ToString(), $"Socket is not Conntected"); return false; } if (!CheckEfemStatus()) return false; _currentMessage = new EfemMessage() { Operation = EfemOperation.Align }; _status = RState.Running; string cmd = "ALIGNER ALGN\r"; return WriteCommand(cmd); } public override bool SetLamp(LightType light, LightStatus status) { return false; } public override bool Load(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support Load"); return false; } public override bool Unload(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support Unload"); return false; } public override bool ReadCarrierId(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support ReadCarrierId"); return false; } public override bool WriteCarrierId(ModuleName mod, string id) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support WriteCarrierId"); return false; } public override bool ReadTagData(ModuleName mod) { return ReadCarrierId(mod); } public override bool WriteTagData(ModuleName mod, string tagData) { return WriteCarrierId(mod, tagData); } public override bool Dock(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support Dock"); return false; } public override bool Undock(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support Undock"); return false; } public override bool Clamp(ModuleName mod, bool isUnloadClamp) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support Clamp"); return false; } public override bool Unclamp(ModuleName mod) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support Unclamp"); return false; } public override bool SetThickness(ModuleName mod, string thickness) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"System cannot support {EfemConstant.OperationString[EfemOperation.SetThickness]}"); return false; } public override void SetRobotMovingInfo(RobotAction action, Hand hand, ModuleName target,Flip flip) { blockingCollection.Add(new RobotAnimationData(action, hand, target,flip)); } private void OnReceiveMessage(string msg) { LOG.WriteLog(eEvent.EV_EFEM_COMMON_INFO, Module.ToString(), msg.Replace("\r","")); if (_currentMessage == null) { return; } if(msg.Contains("_ERR")) { string error = msg.Replace("_ERR", "").Trim(); OnErrorOccurred(error); _currentMessage = null; SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EFEM, Flip.Upper); return; } else if (msg.StartsWith("ACTION _RDY")) { _status = RState.End; _isResumeRDYReceived = false; _isPauseRDYReceived = false; _isActionRDYReceived = true; } else if (msg.StartsWith("_RDY")) { _status = RState.End; switch (_currentMessage.Operation) { case EfemOperation.Home: SetRobotMovingInfo(RobotAction.Homing, Hand.Both, ModuleName.EFEM, Flip.Upper); break; case EfemOperation.Map: case EfemOperation.GotoMap: if (ModuleHelper.IsLoadPort(_currentMessage.Module)) { GetLoadPort(_currentMessage.Module).OnMaped(); } break; case EfemOperation.Pick: case EfemOperation.Place: if(_currentMessage.Flip == Flip.Down) { SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot, Flip.Down); } else { SetRobotMovingInfo(RobotAction.None, Hand.Both, ModuleName.EfemRobot, Flip.Upper); } break; } } else if (msg.Contains("PAUSE _RDY")) { _isPauseRDYReceived = true; _isResumeRDYReceived = false; //收到pause把收到resume的信号置false LOG.WriteLog(eEvent.INFO_TM_ROBOT, Module.ToString(), $"PAUSE_RDY was received, robot pause status is true"); } else if (msg.Contains("RESUME _RDY")) { _isResumeRDYReceived = true; _isPauseRDYReceived = false; //收到Resume把收到pause的信号置false _isInPauseStatus = false; //取消pause状态 LOG.WriteLog(eEvent.INFO_TM_ROBOT, Module.ToString(), $"RESUME _RDY was received, robot pause status is false"); } else { switch (_currentMessage.Operation) { case EfemOperation.StateTrack: DealStateTrack(msg); break; case EfemOperation.RequestMapResult: DealMapResult(msg); break; } _status = RState.End; _currentMessage = null; } } /// /// 处理StateTrack结果 /// /// private void DealStateTrack(string msg) { if (msg.StartsWith("LOAD")) { string[] strAry = msg.Trim().Split(' '); if (strAry.Length >= 2) { bool hasWafer = strAry[2] == "ON" ? true : false; if (strAry[1] == _armString[Hand.Blade1]) { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 0)&& hasWafer) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 0, WaferStatus.Normal); } } else if (strAry[1] == _armString[Hand.Blade2]) { if (WaferManager.Instance.CheckNoWafer(ModuleName.EfemRobot, 1) && hasWafer) { WaferManager.Instance.CreateWafer(ModuleName.EfemRobot, 1, WaferStatus.Normal); } } } } } /// /// 处理Map结果 /// /// private void DealMapResult(string msg) { if (_currentMessage.Operation != EfemOperation.RequestMapResult) { return; } if(!msg.StartsWith("MAP")) { return; } string[] sWaferInfo = msg.Split(new char[] { ' ', '\r', '\n' }); if (sWaferInfo.Length <= 2) { return; } int slotMap = SC.GetValue("EFEM.LoadPort.SlotNumber"); WaferType waferType = WaferType.Production; if (ModuleHelper.IsDummy(_currentMessage.Module)) { DummyCassetteItem item = DummyCasseteItemManager.Instance.GetDummyCassetteItem(_currentMessage.Module.ToString()); if (item != null) { slotMap = item.MaxNumberOfSlots; } waferType = WaferType.Assit; } int waferSize = GetModuleNameWaferSize(_currentMessage.Module); //Map 结果(1 1 1 1 1 1 1 ...0) int startIndex = 1; int count = slotMap >= sWaferInfo.Length-startIndex? sWaferInfo.Length-startIndex : slotMap; bool result = true; for (int index = startIndex; index <= count; index++) { string strState = sWaferInfo[index]; int waferState = 0; //合理的映射到内部支持的叠片/交叉片 if (strState == "1") waferState = (int)WaferStatus.Normal; else if (strState == "2") waferState = (int)WaferStatus.Double; else if (strState == "3") waferState = (int)WaferStatus.Crossed; else if (strState == "5") waferState = (int)WaferStatus.Thin; else if(strState=="?") waferState=(int)WaferStatus.Unknown; WaferStatus st = (WaferStatus)waferState; if (st != WaferStatus.Empty) { WaferManager.Instance.CreateWafer(_currentMessage.Module, index-startIndex, st,(WaferSize)waferSize,waferType); if (st != WaferStatus.Normal) { result = false; } } else { WaferManager.Instance.DeleteWafer(_currentMessage.Module, index-startIndex); } } if (!result) { LOG.WriteLog(eEvent.ERROR_EFEM_ERROR_WAFER, Module.ToString(), $"{_currentMessage.Module} slot map failed {msg}"); } if (ModuleHelper.IsLoadPort(_currentMessage.Module)) { GetLoadPort(_currentMessage.Module).UpdateMapResult(result); } } private void OnErrorOccurred(string errorCode) { _status = RState.Failed; string description = errorCode; if (SumWayRobotErrorCode.ErrorCodeDescription.ContainsKey(errorCode)) { description=SumWayRobotErrorCode.ErrorCodeDescription[errorCode]; } Singleton.Instance.EFEM.PostMsg(EfemEntity.MSG.Error, description); if (_currentMessage != null) { LOG.Write(eEvent.ERR_EFEM_COMMON_FAILED, ModuleName.EFEM, $"current operation {_currentMessage.Operation} failed,{description}"); } _currentMessage=null; } private bool WriteCommand(string cmd) { LOG.WriteLog(eEvent.EV_EFEM_COMMON_INFO, Module.ToString(), cmd.Replace("\r", "")); return _socket.Write(cmd); } /// /// 获取模块Wafer尺寸 /// /// /// private int GetModuleNameWaferSize(ModuleName moduleName) { if (ModuleHelper.IsLoadPort(moduleName)) { Loadport loadport = GetLoadPort(moduleName); if (!loadport.HasCassette) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{moduleName} does not have cassete."); return 0; } return (int)loadport.WaferSize; } else if (ModuleHelper.IsDummy(moduleName)) { DummyDevice dummyDevice = Singleton.Instance.EFEM.GetDummyDevice(moduleName - ModuleName.Dummy1); if (!dummyDevice.HasCassette) { LOG.WriteLog(eEvent.ERR_EFEM_COMMON_FAILED, Module.ToString(), $"{moduleName} does not have cassete."); return 0; } return (int)dummyDevice.WaferSize; } return 0; } /// /// 获取模块尺寸 /// /// /// private int GetModuleSlotWaferSize(ModuleName moduleName,int slotNumber) { if(WaferManager.Instance.CheckHasWafer(moduleName,slotNumber)) { WaferInfo waferInfo=WaferManager.Instance.GetWafer(moduleName, slotNumber); return (int)waferInfo.Size; } else { return 0; } } } }