123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086 |
- using Aitex.Core.Common;
- using Aitex.Core.RT.Device;
- using Aitex.Core.RT.Device.Unit;
- using Aitex.Core.RT.IOCore;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using Aitex.Sorter.Common;
- using athosRT.tool;
- using Common.DataCenter;
- using Common.OP;
- using MECF.Framework.Common.Communications;
- using MECF.Framework.Common.Equipment;
- using MECF.Framework.Common.SubstrateTrackings;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
- using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots.RobotBase;
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO.Ports;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using System.Threading.Tasks;
- namespace athosRT.Devices.LP
- {
- //注意要与brooks的lp实现保持一致
- class HirataLoadPort : LoadPortBaseDevice
- {
- private string _lpname = string.Empty;
- private AsyncSerialPort _serial;
- private string _port = string.Empty;
- private object _locker = new object();
- private LinkedList<string> _lstAsciiMsgs = new LinkedList<string>();
- private string _newLine = "\r";//协议的CR
- private byte _newHeader = 0x01;//协议的头 此处为SOH 也可以是SOT等 对着表就OK
- private PeriodicJob lp_thread;//监听收到数据的线程
- private bool _isAsciiMode;
- private bool _isLoaded;
- private LoadPortStateEnum _current = LoadPortStateEnum.Init;
- private readonly int _timeout = 1*60*1000;
- private IoTrigger _lpIsEnable;
- //private DeviceTimer _device_timer;
-
- //关键变量
- /* _isPresent 是否Present
- * _isPlaced 是否Placed
- * _isLoaded load状态 load后置map后置true
- * IsReady() 是否busy
- * _isMapped map状态 map后置true
- * _isDocked dock状态 load后置map后置true
- * IsCarrierEnabled 看sc的厚薄设置*/
- public override bool IsHomed { get; set; }//是否home过 orgn
- public override bool IsLoaded => _isLoaded;
- public override bool IsIdle => fsm.State == (int)LoadPortStateEnum.Idle;
- public bool IsConnected => _serial != null && _serial.IsOpen();//是否建立连接
- public bool IsQueryComplete { get; set; }
- public string ProtrusionState { get; set; }
- public override bool IsReady() => fsm.State == (int)LoadPortStateEnum.Idle|| fsm.State == (int)LoadPortStateEnum.Init;
- private readonly Regex mov_interlock_error = new Regex(@".*MOV:.*\/");//MOV:.../...即是interlock错误发生
- private readonly Regex mov_abs_error = new Regex(@".*ABS:.*");//含有ABS即是MOV执行失败 成功是INF
- private readonly Regex catch_After_param = new Regex(@"(?<=\/)(.+?)(?=\;)");//提取错误
- private readonly Regex catch_command = new Regex(@"(?<=\:)(.+?)(?=[\/,\;])");//提取命令
- private readonly Regex catch_command_type = new Regex(@"(?<=0000)(.+?)(?=\:)");//提取命令类型
-
- public HirataLoadPort(string module, string lpname, string scRoot, RobotBaseDevice robot,IoTrigger[] LPTriggers) : base(module, lpname, robot)
- {
- base.Module = module;
- base.Name = lpname;
- _lpname = lpname;
- _isAsciiMode = true;
- _port = SC.GetStringValue($"LoadPort.{_lpname}.PortName");
- //LOG.Write();
- //_port = "COM12";//
- //参数类型string port, int baudRate, int dataBits, Parity parity, StopBits stopBits,
- _serial = new AsyncSerialPort(_port, 9600, 8, Parity.None, StopBits.One, _newLine, _isAsciiMode);
- _serial.OnDataChanged += OnAsciiDataReceived;//使用ascii类型时的数据变化处理
- _serial.OnBinaryDataChanged += OnBinaryDataChanged;//使用binary类型时的数据变化处理
- _serial.OnErrorHappened += onErrorHappend;
- DoorState = FoupDoorState.Close;
- if (_serial.Open())
- {
- LOG.Write($"{_lpname}连接成功");
- }
- else
- {
- LOG.Write($"{_lpname}连接失败");
- }
- lp_thread = new PeriodicJob(10, OnTimer, $"{_lpname}->OnTimer", true);
- Singleton<WaferManager>.Instance.SubscribeLocation($"{_lpname}", 25);
- Singleton<CarrierManager>.Instance.SubscribeLocation($"{_lpname}");
- for (int index = 0;index < 25;++index)
- {
- Singleton<WaferManager>.Instance.DeleteWafer(ModuleHelper.Converter(_lpname), index);
- }
- //_device_timer = new DeviceTimer();
- }
- protected override void SubscribeDataVariable()
- {
-
- }
- private void OnBinaryDataChanged(byte[] obj)
- {
- }
- /// <summary>
- /// 定时函数 用来监听最新收到的消息 并交给函数处理
- /// </summary>
- /// <returns></returns>
- private bool OnTimer()
- {
- //处理消息
- lock (_locker)
- {
- if (DoorState == FoupDoorState.Open)
- {
- if (Name == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(true, out _);
- if (Name == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(true, out _);
- }
- else
- {
- if (Name == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(false, out _);
- if (Name == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(false, out _);
- }
- switch (Name)
- {
- case "LP1":
- _isPlaced = DeviceModel.LP1Placement.Value;
- _isPresent = DeviceModel.LP1Presence.Value;
- break;
- case "LP2":
- _isPlaced = DeviceModel.LP2Placement.Value;
- _isPresent = DeviceModel.LP2Presence.Value;
- break;
- }
- //if (_device_timer.IsTimeout())
- //{
- // _device_timer.Stop();
- // LogObject.Error(_lpname,$"while {CurrentState} Timeout");
- // CheckToPostMessage(LoadPortMsg.Error);
- // return false;
- //}
- //Trace.WriteLine($"{_lpname} state: {CurrentState}");
- if (_isAsciiMode)//按照ascii码处理
- {
- while (_lstAsciiMsgs.Count > 0)
- {
- string value = _lstAsciiMsgs.First.Value;
- HandleAsciiData(value);
- _lstAsciiMsgs.RemoveFirst();
- }
- }
- else
- {
- //暂时用不上
- //while (_lstBinsMsgs.Count > 0)
- //{
- // byte[] value2 = _lstBinsMsgs.First.Value;
- // _port_HandleBinarayData(value2);
- // _lstBinsMsgs.RemoveFirst();
- //}
- }
- }
- return true;
- }
-
- private void HandleAsciiData(string ReceiveMsg)
- {
- if (string.IsNullOrEmpty(ReceiveMsg))
- return;
- Trace.WriteLine(_lpname+"收到的msg" +ReceiveMsg);
- LogObject.Info(_lpname, $"Communication {_port} Receive Message:" + ReceiveMsg.Replace("\r", ""));
- //LogObject.Info(_lpname,"======收到的msg======="+ReceiveMsg+"==============");
- //解析返回的数据
- //收到的数据的头是否为00 不是就按照错误代码打log
- if (ReceiveMsg.Substring(1, 2) != "00")
- {
- /*
- * 错误代码
- * Check sum error
- * Command error
- * Interlock
- * Alarm occurring
- * Command processing
- * Mode error
- * Mapping error
- */
- string reason = string.Empty;
- switch (ReceiveMsg.Substring(0, 2))
- {
- case "01":
- reason = "Check sum error";
- break;
- case "02":
- reason = "Command error";
- break;
- case "04":
- reason = "Interlock";
- break;
- case "05":
- reason = "Alarm occurring";
- break;
- case "06":
- reason = "Command processing";
- break;
- case "07":
- reason = "Mode error";
- break;
- case "08":
- reason = "Mapping error";
- break;
- default:
- reason = "Unknown Error";
- break;
- }
- //找到的原因
- LogObject.Error(_lpname, $"Received Error Message:{reason}");
- }
- //MOV不能执行的错误
- else if (mov_interlock_error.IsMatch(ReceiveMsg))
- {
- //MOV错误 获取/...;间的数据 Interlock code 表示错误代码
- LogObject.Error(_lpname, $"MOV:{catch_command.Match(ReceiveMsg).Value} received the error:{catch_After_param.Match(ReceiveMsg).Value}");
- }
- //MOV执行后 获取ABS错误
- else if (mov_abs_error.IsMatch(ReceiveMsg))
- {
- //获取/;之间的参数
- string param = string.Empty;
- if (!string.IsNullOrEmpty(catch_After_param.Match(ReceiveMsg).Value))
- param = catch_After_param.Match(ReceiveMsg).Value;
- if (string.IsNullOrEmpty(param))
- {
- LogObject.Error(_lpname, $"MOV:{catch_command.Match(ReceiveMsg).Value} failed for the Unknown error");
- }
- else
- {
- string reason = "";
- switch (param[0])
- {
- case '1':
- switch (param[1])
- {
- case '0': reason = "Clamp time over"; break;
- case '1': reason = "Unclamp time over"; break;
- case '2': reason = "Dock time over"; break;
- case '3': reason = "Undock time over"; break;
- case '4': reason = "Latch time over"; break;
- case '5': reason = "Unlatch time over"; break;
- case '6': reason = "Vacuum time over"; break;
- case '7': reason = "Vacuum release time over"; break;
- case '8': reason = "Door open time over"; break;
- case '9': reason = "Door close time over"; break;
- case 'A': reason = "Mapping forward time over"; break;
- case 'B': reason = "Mapping return time over"; break;
- case 'F': reason = "communication error(3 times of resending)"; break;
- }
- break;
- case '2':
- switch (param[1])
- {
- case '0': reason = "Home return time over"; break;
- case '1': reason = "Loading time over"; break;
- case '2': reason = "Unloading time over"; break;
- case '3': reason = "Positioning time over"; break;
- case '8': reason = "Door open/close position movement time over"; break;
- case '9': reason = "Mapping start position movement time over"; break;
- case 'A': reason = "Mapping end position movement time over"; break;
- case 'B': reason = "Load position movement time over"; break;
- }
- break;
- case '4':
- switch (param[1])
- {
- case '0': reason = "Mapping data error"; break;
- case '1': reason = "Mode select error"; break;
- }
- break;
- case '7':
- switch (param[1])
- {
- case '0': reason = "Clamp sensor error"; break;
- case '1': reason = "Dock sensor error"; break;
- case '2': reason = "Latch sensor error"; break;
- case '3': reason = "Door sensor error"; break;
- case '4': reason = "Mapping sensor error"; break;
- case '7': reason = "Elevator axis sensor error"; break;
- }
- break;
- case 'A':
- switch (param[1])
- {
- case '0': reason = "Wafer drop"; break;
- case '1': reason = "Wafer protrusion"; break;
- case '2': reason = "FOUP mount error"; break;
- case '3': reason = "FOUP mount error"; break;
- case '5': reason = "Air pressure drop"; break;
- }
- break;
- case 'B':
- switch (param[1])
- {
- case '0': reason = "Host error"; break;
- }
- break;
- case 'C':
- switch (param[1])
- {
- case '0': reason = "Parameter error"; break;
- }
- break;
- case 'E':
- switch (param[1])
- {
- case '0': reason = "FAN stop alarm"; break;
- case '3': reason = "Voltage drop"; break;
- }
- break;
- case 'F':
- switch (param[1])
- {
- case 'E': reason = "Dock hand pinch error"; break;
- }
- break;
- }
- if (string.IsNullOrEmpty(reason))
- {
- LogObject.Error(_lpname, $"MOV:{catch_command.Match(ReceiveMsg).Value} failed for the Unknown error {param}");
- }
- else
- {
- LogObject.Error(_lpname, $"MOV:{catch_command.Match(ReceiveMsg).Value} failed for the error {param}:{reason}");
- }
- }
-
- }
- else
- {
- //基本没有错误 若有遗漏 继续加else if(条件补充)
- //对事件进行分割 SET GET涉及到wafer mapping MOV涉及到home open clamp等
- OnEventHappend(ReceiveMsg);//接受信息 涉及状态机切换
- return;
-
- }
- //走到这里表示是错误走出 需要发送message给状态机
- CheckToPostMessage(LoadPortMsg.Error);
- IsError = true;
- }
- private void FindErrorReason(string param,out string reason)
- {
- reason = string.Empty;
- switch (param[0])
- {
- case '1':
- switch (param[1])
- {
- case '0': reason = "Clamp time over"; break;
- case '1': reason = "Unclamp time over"; break;
- case '2': reason = "Dock time over"; break;
- case '3': reason = "Undock time over"; break;
- case '4': reason = "Latch time over"; break;
- case '5': reason = "Unlatch time over"; break;
- case '6': reason = "Vacuum time over"; break;
- case '7': reason = "Vacuum release time over"; break;
- case '8': reason = "Door open time over"; break;
- case '9': reason = "Door close time over"; break;
- case 'A': reason = "Mapping forward time over"; break;
- case 'B': reason = "Mapping return time over"; break;
- case 'F': reason = "communication error(3 times of resending)"; break;
- }
- break;
- case '2':
- switch (param[1])
- {
- case '0': reason = "Home return time over"; break;
- case '1': reason = "Loading time over"; break;
- case '2': reason = "Unloading time over"; break;
- case '3': reason = "Positioning time over"; break;
- case '8': reason = "Door open/close position movement time over"; break;
- case '9': reason = "Mapping start position movement time over"; break;
- case 'A': reason = "Mapping end position movement time over"; break;
- case 'B': reason = "Load position movement time over"; break;
- }
- break;
- case '4':
- switch (param[1])
- {
- case '0': reason = "Mapping data error"; break;
- case '1': reason = "Mode select error"; break;
- }
- break;
- case '7':
- switch (param[1])
- {
- case '0': reason = "Clamp sensor error"; break;
- case '1': reason = "Dock sensor error"; break;
- case '2': reason = "Latch sensor error"; break;
- case '3': reason = "Door sensor error"; break;
- case '4': reason = "Mapping sensor error"; break;
- case '7': reason = "Elevator axis sensor error"; break;
- }
- break;
- case 'A':
- switch (param[1])
- {
- case '0': reason = "Wafer drop"; break;
- case '1': reason = "Wafer protrusion"; break;
- case '2': reason = "FOUP mount error"; break;
- case '3': reason = "FOUP mount error"; break;
- case '5': reason = "Air pressure drop"; break;
- }
- break;
- case 'B':
- switch (param[1])
- {
- case '0': reason = "Host error"; break;
- }
- break;
- case 'C':
- switch (param[1])
- {
- case '0': reason = "Parameter error"; break;
- }
- break;
- case 'E':
- switch (param[1])
- {
- case '0': reason = "FAN stop alarm"; break;
- case '3': reason = "Voltage drop"; break;
- }
- break;
- case 'F':
- switch (param[1])
- {
- case 'E': reason = "Dock hand pinch error"; break;
- }
- break;
- }
- }
- //按照返回数据处理 包括mov后的状态机切换 set反馈 get反馈
- private void OnEventHappend(string receiveMsg)
- {
- //首先按照收到的正确数据类型进行分类
- //收到的可能是1、set 2、get 3、mov 4、inf
- string command_type = catch_command_type.Match(receiveMsg).Value;//获取到操作的类型
- string command_name = catch_command.Match(receiveMsg).Value;//获取操作的名称
- switch (command_type)
- {
- case "SET":
- SetEndAnalysis(command_name);
- break;//主要是设置 没有太多内容
- case "GET"://涉及mapping state要对返回值序列进行处理
- string command_parameter = catch_After_param.Match(receiveMsg).Value;
- GetEndAnalysis(command_name, command_parameter);
- break;
- case "MOV"://设备回复收到MOV命令
- MovCanExcute(command_name);
- break;
- case "INF"://设备回复完成MOV命令 需要对该指令处理并下发msg给状态机
- MovOPEnd(command_name);
- break;
- default: break;
- }
- }
- private void SetEndAnalysis(string command_name)
- {
- switch (command_name)
- {
- case "RSET":
- CheckToPostMessage(LoadPortMsg.ResetComplete);
- break;
- default:
- break;
- }
- }
- private void MovCanExcute(string command_name)
- {
- }
- //设备回复完成MOV命令 需要对该指令处理并下发msg给状态机
- private void MovOPEnd(string command_name)
- {
- switch(command_name)
- {
- //home完成
- case "ORGN":
- CheckToPostMessage(LoadPortMsg.InitComplete);
- break;
- //Load完成
- case "FPML":
- SendMessage("GET:MAPR;");//获取扫片的结果
- break;
- //Unload完成
- case "FPMU":
- CheckToPostMessage(LoadPortMsg.UnloadComplete);
- break;
- //Unclamp
- case "FCOP":
- CheckToPostMessage(LoadPortMsg.MoveComplete, "Unclamp over");
- break;
- //Clamp
- case "FCCL":
- CheckToPostMessage(LoadPortMsg.MoveComplete, "Clamp over");
- break;
- }
- }
- private void GetEndAnalysis(string command_name, string command_parameter)
- {
- switch (command_name)
- {
- case "STAS"://此处涉及LP关键状态变量的获取 对efem中的判断有重要影响
- OnStasRead(command_parameter);
- break;
- case "MAPR"://此处涉及扫片的结果转化为wafermanager存储 efem上层会从wafermanager中读取转化 重要!
- //================判断
- OnSlotMapRead(command_parameter);
- if (CurrentState == LoadPortStateEnum.Loading)
- {
- CheckToPostMessage(LoadPortMsg.LoadComplete);
- }
- break;
- }
- }
- private void OnStasRead(string command_parameter)
- {
- _isLoaded = false;
- switch (command_parameter[6])//Continer Status
- {
- case '0':
- //_isPlaced = false;
- //_isPresent = false;
- break;
- case '1':
- //_isPlaced = true;
- //_isPresent = true;
- break;
- case '2':
- //_isPlaced = false;
- //_isPresent = true;
- break;
- }
- switch (command_parameter[7])//Clamp position
- {
- case '0':
- ClampState = FoupClampState.Open;
- break;
- case '1':
- ClampState = FoupClampState.Close;
- break;
- case '?':
- ClampState = FoupClampState.Unknown;
- break;
- }
- switch (command_parameter[10])//Door positon
- {
- case '0':
- DoorState = FoupDoorState.Open;
- if(Module == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(true,out _);
- if (Module == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(true, out _);
- break;
- case '1':
- DoorState = FoupDoorState.Close;
- if (Module == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(false, out _);
- if (Module == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(false, out _);
- break;
- case '?':
- DoorState = FoupDoorState.Unknown;
- if (Module == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(false, out _);
- if (Module == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(false, out _);
- break;
- }
- switch (command_parameter[11])//Wafer protrusion sensor(2025.4.18 +)
- {
- case '0':
- ProtrusionState = "Shading";
- break;
- case '1':
- ProtrusionState = "Lighting";
- break;
- }
- switch (command_parameter[13])//Dock positon
- {
- case '0':
- DockState = FoupDockState.Undocked;
- break;
- case '1':
- DockState = FoupDockState.Docked;
- break;
- case '?':
- DockState = FoupDockState.Unknown;
- break;
- }
- if (command_parameter[4]!='0')//状态不是normal
- {
- string reason;
- string param = "";
- param += command_parameter[4];
- param += command_parameter[5];
- FindErrorReason(param, out reason);
- LogObject.Error(_lpname,reason);
- CheckToPostMessage(LoadPortMsg.Error);
- }
- }
- //覆盖原SlotMap函数 slotMap是一串数字 代表wafer的状态
- public override void OnSlotMapRead(string slotMap)
- {
- lock (_locker)
- {
- int error_num = 0;
- //循环所有wafer
- for (int i = 0; i < slotMap.Length; i++)
- {
- WaferInfo waferInfo = null;
- LogObject.Info(_lpname,$"Slot:{i}:{slotMap[i]}");
- switch (slotMap[i])
- {
- case '0'://没有wafer delete
- Singleton<WaferManager>.Instance.DeleteWafer(base.LPModuleName, i);
- Singleton<CarrierManager>.Instance.UnregisterCarrierWafer(base.Name, i);
- break;
- case '1'://有wafer add
- waferInfo = Singleton<WaferManager>.Instance.CreateWafer(LPModuleName, i, WaferStatus.Normal, WaferSize.WS8);
- Singleton<CarrierManager>.Instance.RegisterCarrierWafer(base.Name, i, waferInfo);
- break;
- case '2'://错误
- waferInfo = Singleton<WaferManager>.Instance.CreateWafer(base.LPModuleName, i, WaferStatus.Normal, WaferSize.WS8);
- Singleton<CarrierManager>.Instance.RegisterCarrierWafer(base.Name, i, waferInfo);
- error_num++;
- LogObject.Error(base.Name, $"Slot {i + 1}: occur Crossed");
- break;
- case '3':
- waferInfo = Singleton<WaferManager>.Instance.CreateWafer(base.LPModuleName, i, WaferStatus.Normal, WaferSize.WS8);
- Singleton<CarrierManager>.Instance.RegisterCarrierWafer(base.Name, i, waferInfo);
- LogObject.Warning(base.Name, $"Slot {i + 1}: Thickness is too Thick");
- break;
- case '4':
- waferInfo = Singleton<WaferManager>.Instance.CreateWafer(base.LPModuleName, i, WaferStatus.Normal, WaferSize.WS8);
- Singleton<CarrierManager>.Instance.RegisterCarrierWafer(base.Name, i, waferInfo);
- LogObject.Warning(base.Name, $"Slot {i + 1}: Thickness is too Thin");
- break;
- case '5':
- waferInfo = Singleton<WaferManager>.Instance.CreateWafer(base.LPModuleName, i, WaferStatus.Normal, WaferSize.WS8);
- Singleton<CarrierManager>.Instance.RegisterCarrierWafer(base.Name, i, waferInfo);
- LogObject.Error(base.Name, $"Slot {i + 1}: Position error”");
- break;
- }
- }
- if (error_num == 0)
- {
- base.MapError = false;
- }
- else
- {
- base.MapError = true;
- }
- _isMapped = true;//十二分重要
- //无所谓的部分
- //SerializableDictionary<string, object> serializableDictionary = new SerializableDictionary<string, object>();
- //serializableDictionary["SlotMap"] = CurrentSlotMapResult;
- //serializableDictionary["PortID"] = base.PortID;
- //serializableDictionary["PORT_CTGRY"] = base.SpecPortName;
- //serializableDictionary["CarrierType"] = SpecCarrierType;
- //serializableDictionary["CarrierIndex"] = InfoPadCarrierIndex;
- //serializableDictionary["InfoPadSensorIndex"] = InfoPadSensorIndex;
- //serializableDictionary["CarrierID"] = base.CarrierId;
- //EV.Notify(EventSlotMapAvailable, serializableDictionary);
- //if (base.LPCallBack != null)
- //{
- // base.LPCallBack.MappingComplete(_carrierId, CurrentSlotMapResult);
- //}
- }
- }
- public override WaferSize GetCurrentWaferSize()
- {
- return WaferSize.WS8;
- }
- /// <summary>
- /// 用来将接受到的数据按照CR分散为一条 等待OnTimer解析
- /// </summary>
- /// <param name="oneLineMessage"></param>
- private void OnAsciiDataReceived(string oneLineMessage)
- {
- lock (_locker)
- {
- if (string.IsNullOrEmpty(_newLine))//没有CR
- {
- _lstAsciiMsgs.AddLast(oneLineMessage);//将消息添加到最后
- return;
- }
- string[] array = oneLineMessage.Split(_newLine.ToCharArray());//按照cr分开通讯数据
- foreach (string text in array)
- {
- if (!string.IsNullOrEmpty(text))
- {
- _lstAsciiMsgs.AddLast(text + _newLine);//存进list中等待处理
- }
- }
- }
- }
- public bool SendMessage(string message)
- {
- //专注数据的发送 此处对数据进行加校验位、加末位处理
- if (string.IsNullOrEmpty(message))
- {
- LogObject.Warning(_lpname,"试图发送空消息");
- return false;
- }
- if (IsConnected)
- {
- message = "0000" + message;//加上头
- int _hexsum = 0;
- foreach (var _schar in message.ToCharArray())
- {
- //获取到的是每一个字符 将其转为Hex存入buffers 并累加 用于最后的计算
- int num = Convert.ToInt32(_schar); // 将字符转换为 ASCII 数值
- string hex = num.ToString("X"); // 将 ASCII 数值转换为十六进制字符串
- _hexsum += int.Parse(hex, System.Globalization.NumberStyles.HexNumber); // 将十六进制字符串转换为整数
- }
- string _name = _hexsum.ToString("X");
- //00 + 00 + Message + CSH + CSI + _newLine
- message = message + _name[_name.Length - 2] + _name[_name.Length - 1] + _newLine;
- LogObject.Info(_lpname, $"Communication {_port} Send Message:" + message.Replace("\r", ""));
- int raw_length = Encoding.Default.GetBytes(message).Length;
- byte[] raw_buffer = Encoding.Default.GetBytes(message);
- byte[] send_buffer = new byte[raw_length + 1];
- send_buffer[0] = _newHeader;//加SOH
- raw_buffer.CopyTo(send_buffer, 1);//剩下的复制到send_buffer
- if (_serial.Write(send_buffer))
- {
- //_device_timer.Restart(_timeout);
- //通过串口发送
- //LogObject.Info(_lpname, "===========发送的msg============" + message);
- return true;
- }
- else
- {
- LogObject.Error(_lpname,"Send Message failed.");
- return false;
- }
- }
- else
- {
- LogObject.Error(_lpname, "尚未建立连接或初始化!");
- return false;
- }
- }
- private void onErrorHappend(string obj)
- {
- LogObject.Error($"{_lpname}", $"Connect Error for:{obj}");
- }
- protected override bool fStartExecute(object[] param)
- {
- //执行逻辑 超时报警 返回错误 返回带参STAS除外都是有错的 ABS执行错误
- try
- {
- switch (param[0].ToString())
- {
- case "Unclamp":
- lock (_locker)
- {
- SendMessage("MOV:FCOP;");
- }
- break;
- case "Clamp":
- lock (_locker)
- {
- SendMessage("MOV:FCCL;");
- }
- break;
- case "MapWafer":
- //_serial.Write("");
- break;
- case "QueryState":
- IsQueryComplete = false;
- lock (_locker)
- {
- SendMessage("GET:STAS;");
- }
- break;
- default:
- break;
- }
- return true;
- }
- catch (Exception ex)
- {
- return false;
- }
- }
- protected override bool fMonitorExecuting(object[] param)
- {
- base.IsBusy = false;
- LogObject.Info(_lpname,$"{param[0].ToString()} excuted over");
- return true;
- }
- protected override bool fStartInit(object[] param)
- {
- //收到消息进入initilizing状态 需要先下发
- //初始化逻辑MOV:ORGN
- IsHomed = false;
- SendMessage("MOV:ORGN;");
- return true;
- }
- protected override bool fCompleteInit(object[] param)
- {
- //一些状态要置为false
- IsHomed = true;
- lock (_locker)
- {
- SendMessage("GET:STAS;");
- }
- return true;
- }
- protected override bool fStartReset(object[] param)
- {
- //SET:RSET
- lock (_locker)
- {
- SendMessage("SET:RSET;");
- }
- return true;
- }
- protected override bool fMonitorReset(object[] param)
- {
- MapError = false;
- IsError = false;
- base.IsBusy = false;
- return true;
- }
-
- protected override bool fStartLoad(object[] param)
- {
- //load操作
- lock (_locker)
- {
- SendMessage("MOV:FPML;");
- }
- return true;
- }
- protected override bool fCompleteLoad(object[] param)
- {
- base.IsBusy = false;
- _isLoaded = true;
- base.DockState = FoupDockState.Docked;
- base.ClampState = FoupClampState.Close;
- base.DoorState = FoupDoorState.Open;
- if (Name == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(true, out _);
- if (Name == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(true, out _);
- return true;
- }
- protected override bool fStartUnload(object[] param)
- {
- lock (_locker)
- {
- SendMessage("MOV:FPMU;");
- }
- return true;
- }
- protected override bool fMonitorUnload(object[] param)
- {
- base.IsBusy = false;
- _isLoaded = false;
- base.DockState = FoupDockState.Undocked;
- base.ClampState = FoupClampState.Close;
- base.DoorState = FoupDoorState.Close;
- if (Name == "LP1")
- DeviceModel.TrigSafetytoSMIF1.SetTrigger(false, out _);
- if (Name == "LP2")
- DeviceModel.TrigSafetytoSMIF2.SetTrigger(false, out _);
- return true;
- }
- protected override bool fStartWrite(object[] param)
- {
- //_serial.Write("");
- return true;
- }
- protected override bool fStartRead(object[] param)
- {
- //MOV:MAPR
- //_serial.Write("MOV:MAPR")
- return true ;
- }
- public override bool IsEnableTransferWafer(out string reason)
- {
- reason = "";
- //Trace.WriteLine("=============================================================");
- //Trace.WriteLine($"时间:{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}");
- //Trace.WriteLine($" LP:{_lpname} State:{State}");
- //Trace.WriteLine($"The state of Present is {_isPresent}.");
- //Trace.WriteLine($"The state of Placed is {_isPlaced }.");
- //Trace.WriteLine($"The state of Ready is {IsReady() }.");
- //Trace.WriteLine($"The state of Mapped is {_isMapped }.");
- //Trace.WriteLine("=============================================================");
- if (_isPresent && _isPlaced && _isLoaded && IsReady() && _isMapped)
- {
- return true;
- }
- else
- {
- reason += $"The State of {_lpname} is {State}. ";
- reason += _isPresent ? $"The state of Present is {_isPresent}." : "";
- reason += _isPlaced ? $"The state of Placed is {_isPlaced }." : "";
- reason += _isLoaded ? $"The state of Loaded is {_isLoaded }." : "";
- reason += IsReady() ? $"The state of Ready is {IsReady() }." : "";
- reason += _isMapped ? $"The state of Mapped is {_isMapped }." : "";
- }
- return false;
- }
- public override bool IsEnableLoad(out string reason)
- {
- if (!_isPlaced)
- {
- reason = "No carrier placed";
- return false;
- }
- if (_isDocked)
- {
- reason = "Carrier is docked";
- return false;
- }
- if (!IsReady())
- {
- reason = "Not Ready";
- return false;
- }
- //SC的内容 建议直接
- //if (!IsCarrierEnabled)
- //{
- // reason = "CarrierNotEnabled";
- // return false;
- //}
- reason = "";
- return true;
- }
-
- }
- public enum HirataCommandType
- {
- SET,
- MOD,
- GET,
- MOV,
- TCH
- }
- public enum HirataCommand
- {
- //SET
- RSET,
- RTRY,
- STPP,
- PASE,
- ABOT,
- RESM,
- TYP1,
- TYP2,
- TYP3,
- TYP4,
- TYP5,
- MAPP,
- MAP1,
- MAP2,
- POSO,
- //GET,
- STAS,
- STA1,
- STA2,
- MDAT,
- MAPR,
- VERN,
- //MAPP,
- //MAP1,
- //MAP2,
- //POSO,
- POSD,
- MDAH,
- MDAP,
- MDTC,
- MDHS,
- MDPS,
- LEST,
- //MOV
- ORGN,
- ABGN,
- FPLD,
- FPML,
- FDOC,
- FDLD,
- FDML,
- FCLD,
- FCML,
- FPUL,
- FPMU,
- FVOF,
- FVUL,
- FUDC,
- FUMD,
- //MAPP,
- RMAP,
- Z_MP ,
- }
- }
|