123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402 |
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Log;
- using Aitex.Core.Util;
- using Aitex.Sorter.Common;
- using MECF.Framework.Common.Equipment;
- using CyberX8_Core;
- using CyberX8_RT.Devices.YASKAWA;
- using SecsGem.Core.Variables;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Runtime.Remoting.Contexts;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace CyberX8_RT.Devices.EFEM
- {
- public class SunWayMessageHandler : Singleton<SunWayMessageHandler>, IEfemMessageHander
- {
- private const string ERROR_MSG = "hardware message invalid";
- /// <summary>
- /// TagId数据前缀
- /// </summary>
- private const string TAG_DATA_PRE = "INF:CSTID/LP1/";
- public EfemMessage ToMessage(string context)
- {
- if (string.IsNullOrEmpty(context) || context.Length < 3)
- throw new ArgumentNullException(ERROR_MSG);
- EfemMessage msg = new EfemMessage { RawString = context, Direct = MsgDirection.From, Data = new List<string>() };
- // remove EOT
- string messageBody = context.Substring(0, context.IndexOf(EfemMessage.EOF) + 1);
- try
- {
- // split up the string
- string[] sBodies = messageBody.Split(Constant.delimiters);
-
- string sHead = sBodies[0];
- string sBasic = sBodies[1];
- // Head
- if (Enum.TryParse(sHead, true, out EfemMessage.MsgHead msgHead))
- {
- msg.Head = msgHead;
- }
- switch (msg.Head)
- {
- case EfemMessage.MsgHead.ACK:
- case EfemMessage.MsgHead.MOV:
- case EfemMessage.MsgHead.INF:
- case EfemMessage.MsgHead.EVT:
- // Basic
- msg.Operation = EfemConstant.ToOperation(sBasic);
- string sPort = sBodies[2];
-
- // Port
- msg.Module = GetModule(sPort);
- // Data
- switch (msg.Operation)
- {
- case EfemOperation.StateTrack:
- for (int i = 2; i < sBodies.Length; i++)
- {
- msg.Data.Add(sBodies[i]);
- }
- break;
- case EfemOperation.GetWaferInfo:
- for(int i=3;i<sBodies.Length;i++)
- {
- msg.Data.Add(sBodies[i]);
- }
- break;
- case EfemOperation.CarrierId:
- if (msg.Head == EfemMessage.MsgHead.INF)
- {
- string carrierId = msg.RawString.Substring(TAG_DATA_PRE.Length);
- carrierId = carrierId.Remove(carrierId.Length - 1);
- msg.Data.Add(carrierId);
- }
- break;
- case EfemOperation.SigStatus:
- for(int i=2;i<sBodies.Length; i++)
- {
- msg.Data.Add(sBodies[i]);
- }
- break;
- case EfemOperation.Ready:
- msg.Data.Add(sBodies[2]);
- break;
- case EfemOperation.Size:
- for (int i = 3; i < sBodies.Length; i++)
- {
- msg.Data.Add(sBodies[i]);
- }
- break;
- case EfemOperation.Align:
- msg.Data.Add(sBodies[3]);
- break;
- default:
- break;
- }
- //EVT:ERROR/Param1/Param2
- if(msg.Head == EfemMessage.MsgHead.EVT&&sBasic.ToLower()=="error")
- {
- msg.Operation = EfemOperation.Error;
- msg.Data.Add(sBodies[3]);
- }
- break;
- case EfemMessage.MsgHead.NAK:
- //NAK:Factor|Message*
- if (sBodies.Length > 1)
- {
- msg.Factor = sBodies[1];
- }
- else
- {
- msg.Factor = "NAK 格式错误";
- }
- break;
- case EfemMessage.MsgHead.CAN:
- //CAN:Message*|Factor/Place
- if (sBodies.Length >= 4)
- {
- string[] canFactor = messageBody.Split('|');
- string[] factorandData = canFactor[1].Split(Constant.delimiters);
- string factor = factorandData[0];
- string data = canFactor[1].Replace(factor,"");
-
- msg.Data.Add(data);
- msg.Factor = factor;
- //msg.Factor = sBodies[sBodies.Length - 2];
- //msg.Data.Add(sBodies[sBodies.Length - 1]);
-
- }
- else
- {
- msg.Factor = "CAN 格式错误";
- }
- break;
- case EfemMessage.MsgHead.ABS:
- //ABS:Message*|Error|Parameter1/Parameter2
- if (sBodies.Length >= 5)
- {
- msg.Factor = sBodies[sBodies.Length - 3];
- string errorCode = sBodies[sBodies.Length - 2];
- if (EfemHWErrorCode2Msg.ContainsKey(errorCode))
- {
- msg.Data.Add(EfemHWErrorCode2Msg[errorCode]);
- }
- else
- {
- msg.Data.Add(errorCode);
- }
- msg.Data.Add(sBodies[sBodies.Length - 1]);
- }
- else
- {
- msg.Factor = "ABS 格式错误";
- }
- break;
- }
- }
- catch (Exception ex)
- {
- EV.PostAlarmLog(ModuleName.EFEM.ToString(), $"收到[{context}],解析出错[{ex.Message}]");
- }
- return msg;
- }
- private ModuleName GetModule(string sPort)
- {
- ModuleName module = ModuleName.EFEM;
- if (Regex.IsMatch(sPort, @"LP[123]$"))
- {
- if (sPort.Length > 3)
- {
- sPort = sPort.Remove(sPort.Length - 2);
- }
- module = StringModule[sPort];
- }
- else if (Regex.IsMatch(sPort, @"ALN\d?", RegexOptions.IgnoreCase))
- {
- if (sPort.Length > 4)
- {
- sPort = sPort.Remove(sPort.Length - 2);
- }
- module = StringModule[sPort];
- }
- else if (Regex.IsMatch(sPort, @"BF\d?", RegexOptions.IgnoreCase))
- {
- if (sPort.Length > 3)
- {
- sPort = sPort.Remove(sPort.Length - 2);
- }
- module = StringModule[sPort];
- }
- else
- {
- module = ModuleName.EFEM;
- }
- return module;
- }
- public Dictionary<ModuleName, string> ModuleString = new Dictionary<ModuleName, string>
- {
- [ModuleName.EFEM] = "ALL",
- [ModuleName.EfemRobot] = "ROB",
- [ModuleName.LP1] = "LP1",
- [ModuleName.LP2] = "LP2",
- [ModuleName.LP3] = "LP3",
- [ModuleName.Aligner1] = "ALN1",
- [ModuleName.PUF1]="PUF1",
- [ModuleName.PUF2]="PUF2",
- [ModuleName.SRD1]="SRD1",
- [ModuleName.SRD2]="SRD2",
- [ModuleName.Dummy1]="BF1",
- [ModuleName.Dummy2]="BF2"
- };
- public readonly Dictionary<string, ModuleName> StringModule = new Dictionary<string, ModuleName>
- {
- ["ALL"] = ModuleName.EFEM,
- ["System"] = ModuleName.EFEM,
- ["LP1"] = ModuleName.LP1,
- ["LP2"] = ModuleName.LP2,
- ["LP3"] = ModuleName.LP3,
- ["ALN1"] = ModuleName.Aligner1,
- ["BF1"]=ModuleName.Dummy1,
- ["BF2"]=ModuleName.Dummy2
- };
- public Dictionary<Hand, string> ArmString = new Dictionary<Hand, string>
- {
- [Hand.Blade1] = "ARM1"
- };
- public string ToHWString(Position pos)
- {
- string res = string.Empty;
- string sMod = ModuleString[pos.Module];
- int num = pos.Slot + 1;
- string sSlot = num.ToString("D2");
- //EFEM中PUF只固定一个slot
- if (ModuleHelper.IsPUF(pos.Module))
- {
- res = $"{sMod}01";
- }
- else {
- res = $"{sMod}{sSlot}";
- }
- return res;
- }
- public readonly Dictionary<string, string> EfemHWErrorCode2Msg = new Dictionary<string, string>()
- {
- {"NOREADY","通信握手未完成" },
- {"SORC_NOWAF","Robot 手指无片无法执行取片" },
- {"SORC_WAFER","Robot 手指有片,无法执行取片" },
- {"DEST_WAFER","目标位有片,无法执行取片" },
- {"VAC","真空不足" },
- {"AIR","大气不足" },
- {"MAPPARAM_NG","执行扫片失败" },
- {"WAFERUPDATEFAIL","晶圆状态异常" },
- {"NOLOCATION","未找到工位配置信息" },
- {"NOARM","未找到 ARM 配置信息" },
- {"REMOVE","未找到设备或设备已断开链接" },
- {"NOMAPPINGDATA","没有找到相对应的 Mapping 结果" },
- {"ALARM","触发 Alarm 报警" },
- {"NOCST","OC 上未发现 Cassette" },
- {"NOCLAMP","OC 未执行 Clamp" },
- {"NOPOD","OC 上未发现 POD" },
- {"PODNOTCLOSED","POD 门未关" },
- {"AREASENSOR","触发安全光栅" },
- {"EMS","触发 EMS 急停" },
- {"WAFERPROTRUSION","晶圆突出检测触发" },
- {"DOOR","安全门开启" },
- {"COMM","设备通信异常" },
- {"EXCEPTION","系统抛出异常" },
- {"BUSY","系统繁忙" },
- {"CKSUM","校验和验证失败" },
- {"MAINTENANCE","当前系统为维护模式" },
- {"MSG_NG","指令错误" },
- {"PARAM_NG","参数错误" },
- {"NODEVICEMODEL","未找到该设备型号" },
- {"SLOT_NG","SLOT 超出范围" },
- {"UNDEFINITION","未知错误" },
- {"NOIOSET","未找到 IO 设置信息" },
- {"SETFAIL","设置失败" },
- {"TIMEOUT","设备通信超时" },
- {"DEST_NOWAF","目标位无片无法执行取片" },
- {"CSTSIZEMISMATCH","Cassette 尺寸不匹配" },
- {"ROBEXEND","机械手伸手报警" },
- {"FUNC_ERROR","函数错误" },
- {"233","伸缩信号未使能" },
- {"304","未识别的错误码" },
- {"305","未识别的指令" },
- {"309","不支持的指令" },
- {"401","ZWAFER 参数错误" },
- {"402","非法的 slot 参数" },
- {"403","运动指令 RX 参数错误" },
- {"404","晶圆夹取失败" },
- {"405","晶圆释放失败" },
- {"406","气缸压力表检测错误" },
- {"407","Mapping 传感器伸出失败" },
- {"408","Mapping 传感器缩回失败" },
- {"409","Mapping 传感器位置数据不正确" },
- {"411","Mapping 传感器高度不一致" },
- {"412","工位 VIA 参数未使能" },
- {"413","不是有效的 Mapping 工位" },
- {"414","手指有晶圆无法 mapping" },
- {"415","采集的数据个数错误" },
- {"416","采集的晶圆厚度过小" },
- {"417","晶圆位置超出有效范围" },
- {"418","晶圆上下沿槽数错误" },
- {"550","工位号超范围" },
- {"552","VIA 参数错误" },
- {"553","MAPVIA 参数错误" },
- {"600","系统未上电" },
- {"602","指令正在执行中" },
- {"603","系统上电失败" },
- {"604","示教器控制中" },
- {"605","机械手运动中停止" },
- {"609","系统存在错误" },
- {"610","示教盒急停启动" },
- {"611","驱动器报警" },
- {"629","驱动器存在报警" },
- {"705","LOAD 状态未知" },
- {"712","真空吸附动作失败" },
- {"730","PLACE 前 LOAD 状态错误" },
- {"731","PLACE 后 LOAD 状态错误" },
- {"734","PLACE 执行 Extend 过程中未检测到晶圆" },
- {"736","PLACE 执行 Retract 过程中检测到晶圆" },
- {"740","PICK 前 LOAD 状态错误" },
- {"741","PICK 后 LOAD 状态错误" },
- {"744","PICK 执行 Extend 过程中检测到晶圆" },
- {"745","PICK 执行 Retract 过程中未检测到晶圆" },
- {"800","当前有动作暂停中" },
- {"801","改变运动状态发生错误" },
- {"802","无法获取下一个状态" },
- {"803","没有正在运行的指令" },
- {"804","没有暂停的动作" },
- {"805","没有可跳过的动作" },
- {"1006","非法的 IO 端口号" },
- {"1314","PITCH 轴超界" },
- {"1315","关节位置超界" },
- {"1316","关节位置超硬限" },
- {"1320","机械手跟踪差超限错误" },
- {"1321","机械手发生碰撞" },
- {"1322","机械手超出工作区" },
- {"1323","关节速度超限" },
- {"1400","打开 pod 失败" },
- {"1401","当前位置不正确" },
- {"1402","关闭 pod 失败" },
- {"1403","pod 上锁失败" },
- {"1404","pod 解锁失败" },
- {"1407","气压错误" },
- {"1408","pod 盒状态错误" },
- {"1409","当前位置不在旋转轴动作位置" },
- {"1410","晶圆尺寸设置错误" },
- {"1411","旋转轴状态错误不能伸出" },
- {"1412","晶圆已滑出" },
- {"1413","与 R3 extend 互锁" },
- {"1414","光栅被触发" },
- {"1415","Cassette 状态错误" },
- {"1500","打开门失败" },
- {"1501","关闭门失败" },
- {"1502","门开关状态不对" },
- {"1503","门松开失败" },
- {"1504","门夹紧失败" },
- {"1505","门夹紧松开状态错误" },
- {"1510","安全检测触发" },
- {"1511","R 轴未运动到位" },
- {"1512","使能开关未使能" },
- {"1514","气缸 1 状态错误" },
- {"1515","LATCH 失败" },
- {"1516","UNLATCH 失败" },
- {"1517","LATCH 状态错误" },
- {"1518","DOCK 状态错误" },
- {"1519","气缸 2 状态错误" },
- {"1520","DOCK 到位传感器状态错误" },
- {"1521","吸附状态错误" },
- {"1522","MAP 轴状态错误" },
- {"1523","PLACE 状态错误" },
- {"1524","气缸 1 伸出错误" },
- {"1525","气缸 1 缩回错误" },
- {"1527","关门时 LATCH 状态错误" },
- {"1528","真空吸附失败" },
- {"1529","真空吸附关闭失败" },
- {"13033","伺服驱动器初始化失败" },
- };
- }
- }
|