Sic.Framework/MECF.Framework.RT.Equipment.../HardwareUnits/Aligners/HiWinAligner/HwAlignerGuide.cs

527 lines
16 KiB
C#
Raw Normal View History

2023-04-13 11:51:03 +08:00
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<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
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<bool>($"{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);
}
/// <summary>
/// 设置操作
/// </summary>
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<bool>($"{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;
}
}
}
}