using Aitex.Core.Common; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Communications; using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Aligners.HwAligner { public class HwAlignerGuide : BaseDevice, IConnection, IDevice { private HwAlignerGuideConnection _connection; private bool _activeMonitorStatus; private R_TRIG _trigCommunicationError = new R_TRIG(); private R_TRIG _trigRetryConnect = new R_TRIG(); private bool bIsDisconnect = false; private PeriodicJob _thread; private LinkedList _lstHandler = new LinkedList(); private object _locker = new object(); private bool _enableLog = true; private string _scRoot; public bool HaveWafer { get; set; } public string Address { get; set; } public bool IsConnected { get { return _connection != null && _connection.IsConnected; } } private bool isBusy; public bool IsBusy { get { return isBusy || _lstHandler.Count > 0; } } public string WaferSize { get; set; } public string WaferType { get; set; } public string WaferMaterial { get; set; } public string WaferOrientation { get; set; } public bool Connect() { return true; } public bool Disconnect() { return true; } public HwAlignerGuide(string module, string scRoot, string name) : base(module, name, name, name) { _scRoot = scRoot; _activeMonitorStatus = true; } public bool Initialize() { string portName = SC.GetStringValue($"{Name}.Address"); Address = portName; _enableLog = SC.GetValue($"{Name}.EnableLogMessage"); _connection = new HwAlignerGuideConnection(portName); _connection.EnableLog(_enableLog); if (_connection.Connect()) { EV.PostInfoLog(Module, $"{Module}.{Name} connected"); } isBusy = false; _thread = new PeriodicJob(500, OnTimer, $"{Name} MonitorHandler", true); // SetData(); SetOP(); IniUIData(); // ConnectionManager.Instance.Subscribe($"{Name}", this); return true; } private void IniUIData() { WaferSize = SC.GetStringValue("HiWinAligner.WaferSize"); WaferType = SC.GetStringValue("HiWinAligner.WaferType"); WaferMaterial = SC.GetStringValue("HiWinAligner.WaferMaterial"); WaferOrientation = SC.GetStringValue("HiWinAligner.WaferOrientation"); } private void SetData() { //DATA.Subscribe($"{Module}.{Name}.HwisBusy", () => isBusy); DATA.Subscribe($"{Module}.{Name}.HwHaveWafer", () => HaveWafer); DATA.Subscribe($"{Module}.{Name}.WaferSize", () => WaferSize); DATA.Subscribe($"{Module}.{Name}.WaferType", () => WaferType); DATA.Subscribe($"{Module}.{Name}.WaferMaterial", () => WaferMaterial); DATA.Subscribe($"{Module}.{Name}.WaferOrientation", () => WaferOrientation); } /// /// 设置操作 /// private void SetOP() { //------------------------------------------------------------ //参数保存 OP.Subscribe($"{Module}.{Name}.HwSaveParameters", (cmd, param) => { Set("SPS", "SPS"); return true; }); //读取/设定晶圆尺寸 OP.Subscribe($"{Module}.{Name}.HwWaferSize", (cmd, param) => { Set("WSZ","WSZ" + " " + param[0]); GetParameterForUI("WaferSize", param[0].ToString()); return true; }); //晶圆种类 OP.Subscribe($"{Module}.{Name}.HwWaferType", (cmd, param) => { Set("_WT","_WT" + " " + param[0]); GetParameterForUI("WaferType", param[0].ToString()); return true; }); //寻边材质 OP.Subscribe($"{Module}.{Name}.HwWaferMaterial", (cmd, param) => { Set("GLM", "GLM" + " " + param[0]); GetParameterForUI("WaferMaterial", param[0].ToString()); return true; }); //晶圆方向 OP.Subscribe($"{Module}.{Name}.HwWaferOrientation", (cmd, param) => { Set("FWO", "FWO" + " " + param[0]); GetParameterForUI("WaferOrientation", param[0].ToString()); return true; }); //------------------------------------------------------------ //原点复归 OP.Subscribe($"{Module}.{Name}.HwHome", (cmd, param) => { Set("HOM", "HOM"); return true; }); //晶圆确认 OP.Subscribe($"{Module}.{Name}.HwCheckWafer", (cmd, param) => { this.HaveWafer = false; Set("DOC", "DOC"); return true; }); //开启真空 OP.Subscribe($"{Module}.{Name}.HwVacuumOn", (cmd, param) => { Set("CVN", "CVN"); return true; }); //寻边补正 OP.Subscribe($"{Module}.{Name}.HwAlign", (cmd, param) => { Set("BAL", "BAL"); return true; }); //关闭真空 OP.Subscribe($"{Module}.{Name}.HwVacuumOff", (cmd, param) => { Set("CVF", "CVF"); return true; }); //读取真空值 OP.Subscribe($"{Module}.{Name}.HwCVD", (cmd, param) => { Set("CVD", "CVD"); return true; }); //移至测量中心点 OP.Subscribe($"{Module}.{Name}.HwMoveToMeasurement", (cmd, param) => { Set("MTM", "MTM"); return true; }); //读取最后错误信息 OP.Subscribe($"{Module}.{Name}.HwPER", (cmd, param) => { Set("PER", "PER"); return true; }); //清除报警 OP.Subscribe($"{Module}.{Name}.HwClearError", (cmd, param) => { Set("ERS", "ERS"); return true; }); //马达激磁 OP.Subscribe($"{Module}.{Name}.HwSetMagnetizerEnable", (cmd, param) => { Set("SME11","SME11"); return true; }); //Not Used------------------------------------------------------------ //相对位移 OP.Subscribe($"{Module}.{Name}.HwMVR", (cmd, param) => { Set("MVR","MVR"); return true; }); // OP.Subscribe($"{Module}.{Name}.HwAbort", (cmd, param) => { Abort(); return true; }); } public void Abort() { } public void GetParameterForUI(string _name , string data) { switch (_name) { case "WaferSize": WaferSize = data; break; case "WaferType": WaferType = data; break; case "WaferMaterial": WaferMaterial = data; break; case "WaferOrientation": WaferOrientation = data; break; } SC.SetItemValue($"{Name}.{_name}" , data); } //-------------------------------------------------------- public void Set(string sName, string sCmd, int iTimeOut = 30) { _lstHandler.Clear(); lock (_locker) { _lstHandler.AddLast(new HwAlignerGuideSetAHandler(this, sName, sCmd, iTimeOut)); } } private void NotifyError(string errorInfo) { string _errorInfo = $"Hiwin Aligner Command :" + errorInfo; EV.PostAlarmLog(Module, _errorInfo); LOG.Write($"{Module}.{Name} " + _errorInfo); } private void NotifyWarning(string warningInfo) { string _warningInfo = $"Hiwin Aligner Command :" + warningInfo; EV.PostWarningLog(Module, _warningInfo); LOG.Write($"{Module}.{Name} " + _warningInfo); } //-------------------------------------------------------- public int _connecteTimes { get; set; } private bool OnTimer() { try { _connection.MonitorTimeout(); //若断,重连 if ((!_connection.IsConnected) || _connection.IsCommunicationError || this.bIsDisconnect) { _trigRetryConnect.CLK = this.bIsDisconnect; // if (_connection.Connect()) { this.bIsDisconnect = false; // EV.PostInfoLog(Module, $"{Module}.{Name} connected"); LOG.Write($"{Module}.{Name} connected"); } else { if (_trigRetryConnect.Q) { EV.PostInfoLog(Module, $"Trying to connect {Module}.{Name} with address: {_connection.Address}"); LOG.Write($"Trying to connect {Module}.{Name} with address: {_connection.Address}"); } } } //处理命令队列 HandlerBase handler = null; if (!_connection.IsBusy) { lock (_locker) { if (_lstHandler.Count == 0 && _activeMonitorStatus && !isBusy) { //Query(); } if (_lstHandler.Count > 0) { handler = _lstHandler.First.Value; _lstHandler.RemoveFirst(); } } if (handler != null) { if (!this.isBusy) { this.isBusy = true; _connection.Execute(handler); } } } // return true; } catch (Exception ex) { LOG.Write(ex); } return true; } internal void NoteError() { } public void Monitor() { try { _connection.EnableLog(_enableLog); //if (_connecteTimes < 4) return; _trigCommunicationError.CLK = _connection.IsCommunicationError; if (_trigCommunicationError.Q) { EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}"); } } catch (Exception ex) { LOG.Write(ex); } } public void Terminate() { try { if (_connection != null) { _connection.Disconnect(); _connection = null; } } catch (Exception ex) { LOG.Write(ex); } } public void Reset() { this.bIsDisconnect = _connection.IsCommunicationError; _connecteTimes = 0; _connection.SetCommunicationError(false, ""); _enableLog = SC.GetValue($"{Name}.EnableLogMessage"); _trigCommunicationError.RST = true; _trigRetryConnect.RST = true; _lstHandler.Clear(); this.isBusy = false; this.HaveWafer = false; //需要重新检测wafer } public bool PraseDataA(string name, byte[] buffer,out bool bResult) { bResult = true; string sAnswer = Encoding.ASCII.GetString(buffer); if (sAnswer.Contains("END")) { if(name.Contains("DOC")) { if ( sAnswer.Contains("1\r\nEND")) { this.HaveWafer = true; } else { this.HaveWafer = false; } } if(name.Contains("CVD")) { if(sAnswer != null) { string vacValue = sAnswer.Replace("\r\nEND\r\n", ""); NotifyWarning($"the aligner vacuum value is {vacValue}"); } } if (name.Contains("PER")) { if (sAnswer != null) { string errCode = sAnswer.Replace("\r\nEND\r\n", ""); NotifyWarning($"the aligner lastest err code is {errCode}"); } } this.isBusy = false; return true; } else if (sAnswer.Contains("ERR")) { lock (_locker) { _lstHandler.Clear(); } //可以根据命令名称分类错误类型,也可以直接处理错误编码 if(name.Contains("HOM")) { //do nothing } //这里直接处理错误编码 if(sAnswer.Contains("0101")) { NotifyError("原点复归动作异常。"); } if (sAnswer.Contains("0301")) { NotifyError("发生开启真空后,压力感测器侦测负压状态低于-50kPa。"); } if (sAnswer.Contains("0401")) { NotifyError("执行寻边指令(BAL)前,X轴马达位置不在测量中心点。"); } if (sAnswer.Contains("0402")) { NotifyError("执行寻边指令(BAL)前,Y轴马达位置不在测量中心点。"); } if (sAnswer.Contains("0403")) { NotifyError("在执行一次搜寻过程中,动作失败,θ轴马达超过控制位置。"); } if (sAnswer.Contains("0412")) { NotifyError("寻边指令中,负压(真空)异常."); } isBusy = false; return true; } else { isBusy = true; return false; } } } }