Loadport.cs 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219
  1. using Aitex.Core.Common;
  2. using Aitex.Core.RT.DataCenter;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.OperationCenter;
  5. using Aitex.Core.RT.SCCore;
  6. using Aitex.Core.Util;
  7. using Aitex.Sorter.Common;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.SubstrateTrackings;
  10. using System;
  11. using System.Collections;
  12. using System.Collections.Generic;
  13. using System.Diagnostics;
  14. using System.Linq;
  15. using VirgoCommon;
  16. using VirgoRT.Device;
  17. using VirgoRT.Device.YASKAWA;
  18. using VirgoRT.Devices.YASKAWA;
  19. using VirgoRT.HostWrapper;
  20. using VirgoRT.Modules;
  21. namespace VirgoRT.Devices.EFEM
  22. {
  23. sealed class Loadport : ILoadport
  24. {
  25. private readonly Efem _controller;
  26. //---------------------------------Properties------------------------------------
  27. //
  28. public OnlineFlag OnlineFlag { get; set; }
  29. public ModuleName Module { get; set; }
  30. public DeviceState Status { get; set; }
  31. public WaferSize WaferSize { get; set; }
  32. public WaferStatus[] WaferInfo { get; set; }
  33. public bool HasCassette { get; set; }
  34. public bool Protrusion { get; set; }
  35. public bool IsMapped { get; set; }
  36. public bool JobDone { get; set; }
  37. public Stopwatch TimerNotifyJobDone { get; set; }
  38. public bool IsThicknessValid
  39. {
  40. get
  41. {
  42. return !_enableThickness || !string.IsNullOrEmpty(_waferThicknessType);
  43. }
  44. }
  45. public string ThicknessType
  46. {
  47. get
  48. {
  49. return _waferThicknessType;
  50. }
  51. }
  52. public bool IsClamped { get; set; }
  53. public bool IsLoaded { get; set; }
  54. public string CarrierId { get; set; }
  55. public string SmartTag { get; set; }
  56. public string LotId { get; set; }
  57. public bool IsBusy { get; set; }
  58. public bool IsError { get; set; }
  59. private string[] _slotMap = new string[25];
  60. public string SlotMap
  61. {
  62. get
  63. {
  64. for (int i = 0; i < 25; i++)
  65. {
  66. _slotMap[i] = ((int)WaferManager.Instance.GetWafer(Module, i).Status).ToString();
  67. }
  68. return string.Join("", _slotMap);
  69. }
  70. }
  71. private string Port1CassetteArrive = "Port1CassetteArrive";
  72. private string Port1CassetteRemoved = "Port1CassetteRemoved";
  73. private string Port1MappingComplete = "Port1MappingComplete";
  74. private string Port1MappingFailed = "Port1MappingFailed";
  75. private string Port2CassetteArrive = "Port2CassetteArrive";
  76. private string Port2CassetteRemoved = "Port2CassetteRemoved";
  77. private string Port2MappingComplete = "Port2MappingComplete";
  78. private string Port2MappingFailed = "Port2MappingFailed";
  79. private string _waferThicknessType;
  80. private bool _enableThickness;
  81. private string AlarmWaferProtrude = "WaferProtrude";
  82. private LoadPortFACallback _faCallback = new LoadPortFACallback();
  83. // Constructor
  84. //
  85. public Loadport(ModuleName mod, Efem efem)
  86. {
  87. Module = mod;
  88. _controller = efem;
  89. TimerNotifyJobDone = new Stopwatch();
  90. _enableThickness = SC.GetValue<bool>("System.WaferThickness.EnableThickness");
  91. EV.Subscribe(new EventItem("Event", Port1CassetteArrive, "Port1CassetteArrive"));
  92. EV.Subscribe(new EventItem("Event", Port1CassetteRemoved, "Port1CassetteRemoved"));
  93. EV.Subscribe(new EventItem("Event", Port1MappingComplete, "Port1MappingComplete"));
  94. EV.Subscribe(new EventItem("Event", Port1MappingFailed, "Port1MappingFailed"));
  95. EV.Subscribe(new EventItem("Event", Port2CassetteArrive, "Port2CassetteArrive"));
  96. EV.Subscribe(new EventItem("Event", Port2CassetteRemoved, "Port2CassetteRemoved"));
  97. EV.Subscribe(new EventItem("Event", Port2MappingComplete, "Port2MappingComplete"));
  98. EV.Subscribe(new EventItem("Event", Port2MappingFailed, "Port2MappingFailed"));
  99. EV.Subscribe(new EventItem("Event", AlarmWaferProtrude, "Wafer protrude", EventLevel.Alarm, EventType.HostNotification));
  100. DATA.Subscribe($"{mod}.WaferSize", () => WaferSize.ToString());
  101. DATA.Subscribe($"{mod}.CassetteState", () => HasCassette ? LoadportCassetteState.Normal : LoadportCassetteState.Absent);
  102. DATA.Subscribe($"{mod}.CassettePresent", () => HasCassette ? 1 : 0);
  103. DATA.Subscribe($"{mod}.SlotMap", () => SlotMap);
  104. DATA.Subscribe($"{mod}.IsWaferProtrude", () => Protrusion ? 1 : 0);
  105. DATA.Subscribe($"{mod}.JobDone", () =>
  106. {
  107. return JobDone;
  108. });
  109. DATA.Subscribe($"{mod}.NotifyJobDone", () =>
  110. {
  111. if (! JobDone || ! HasCassette)
  112. return false;
  113. if (SC.GetValue<int>("System.Job.BuzzerTimeWhenJobDone") >= 0
  114. && TimerNotifyJobDone.ElapsedMilliseconds > SC.GetValue<int>("System.Job.BuzzerTimeWhenJobDone") * 1000)
  115. return false;
  116. return JobDone;
  117. });
  118. DATA.Subscribe($"{mod}.IsMapped", () => IsMapped);
  119. DATA.Subscribe($"{mod}.IsLoaded", () => IsLoaded);
  120. DATA.Subscribe($"{mod}.IsClamped", () => IsClamped);
  121. DATA.Subscribe($"{mod}.CarrierId", () => CarrierId);
  122. DATA.Subscribe($"{mod}.SmartTag", () => SmartTag);
  123. DATA.Subscribe($"{Module}.WaferThicknessType", () => _waferThicknessType);
  124. OP.Subscribe($"{Module}.SetThick", (cmd, args) => { SetThick(); return true; });
  125. OP.Subscribe($"{Module}.SetThin", (cmd, args) => { SetThin(); return true; });
  126. }
  127. // Methods
  128. //
  129. public void OnError()
  130. {
  131. IsError = true;
  132. IsBusy = false;
  133. }
  134. public void SetThick()
  135. {
  136. _waferThicknessType = "Thick";
  137. SC.SetItemValue($"System.WaferThickness.{Module}WaferThicknessType", _waferThicknessType);
  138. _controller.SetThick(Module);
  139. }
  140. public void SetThin()
  141. {
  142. _waferThicknessType = "Thin";
  143. SC.SetItemValue($"System.WaferThickness.{Module}WaferThicknessType", _waferThicknessType);
  144. _controller.SetThin(Module);
  145. }
  146. #region Home
  147. public void Home()
  148. {
  149. if (IsBusy)
  150. {
  151. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not home");
  152. return;
  153. }
  154. IsBusy = true;
  155. _controller.Home(Module);
  156. }
  157. public void NoteJobStart()
  158. {
  159. JobDone = false;
  160. }
  161. public void NoteJobComplete()
  162. {
  163. TimerNotifyJobDone.Restart();
  164. JobDone = true;
  165. }
  166. public void OnHomeFailed(string data)
  167. {
  168. IsError = true;
  169. IsBusy = false;
  170. }
  171. public void OnHomed()
  172. {
  173. IsError = false;
  174. IsBusy = false;
  175. IsClamped = false;
  176. IsLoaded = false;
  177. IsMapped = false;
  178. }
  179. #endregion
  180. #region Load
  181. public void Load()
  182. {
  183. if (IsLoaded)
  184. {
  185. EV.PostWarningLog(Module.ToString(), $"{Module} is loaded, can not load");
  186. return;
  187. }
  188. if (IsBusy)
  189. {
  190. EV.PostInfoLog(Module.ToString(), $"{Module} is busy, can not load");
  191. return;
  192. }
  193. if (IsError)
  194. {
  195. EV.PostInfoLog(Module.ToString(), $"{Module} is error, can not load");
  196. return;
  197. }
  198. IsBusy = true;
  199. _controller.Load(Module);
  200. }
  201. public void LPReset()
  202. {
  203. EV.PostWarningLog(Module.ToString(), $"{Module} begin reset");
  204. _controller.LPReset(Module);
  205. }
  206. public void OnLoadFailed(string data)
  207. {
  208. IsError = true;
  209. IsBusy = false;
  210. _faCallback.LoadFailed(this);
  211. }
  212. public void OnLoaded()
  213. {
  214. IsError = false;
  215. IsBusy = false;
  216. IsLoaded = true;
  217. IsMapped = true;
  218. _faCallback.LoadComplete(this);
  219. }
  220. #endregion
  221. #region unload
  222. public void Unload()
  223. {
  224. if (!IsLoaded)
  225. {
  226. EV.PostWarningLog(Module.ToString(), $"{Module} is not loaded, can not unload");
  227. return;
  228. }
  229. if (IsBusy)
  230. {
  231. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not unload");
  232. return;
  233. }
  234. if (IsError)
  235. {
  236. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not unload");
  237. return;
  238. }
  239. IsBusy = true;
  240. _controller.Unload(Module);
  241. }
  242. public void OnUnloadFailed(string data)
  243. {
  244. IsError = true;
  245. IsBusy = false;
  246. _faCallback.UnloadFailed(this);
  247. }
  248. public void OnUnloaded()
  249. {
  250. IsBusy = false;
  251. IsError = false;
  252. IsLoaded = false;
  253. IsMapped = false;
  254. if (SC.GetValue<bool>("EFEM.AutoUnlockAfterUnload"))
  255. {
  256. _faCallback.UnloadComplete(this);
  257. }
  258. else
  259. {
  260. }
  261. }
  262. #endregion
  263. #region Dock
  264. public void Dock()
  265. {
  266. if (IsBusy)
  267. {
  268. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not dock");
  269. return;
  270. }
  271. if (IsError)
  272. {
  273. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not dock");
  274. return;
  275. }
  276. IsBusy = true;
  277. _controller.Dock(Module);
  278. }
  279. public void OnDocked()
  280. {
  281. IsBusy = false;
  282. IsError = false;
  283. }
  284. public void OnDockFailed(string data)
  285. {
  286. IsError = true;
  287. IsBusy = false;
  288. }
  289. #endregion
  290. #region Undock
  291. public void Undock()
  292. {
  293. if (IsBusy)
  294. {
  295. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not undock");
  296. return;
  297. }
  298. if (IsError)
  299. {
  300. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not undock");
  301. return;
  302. }
  303. IsBusy = true;
  304. _controller.Undock(Module);
  305. }
  306. public void OnUndocked()
  307. {
  308. IsBusy = false;
  309. IsError = false;
  310. }
  311. public void OnUndockFailed(string data)
  312. {
  313. IsError = true;
  314. IsBusy = false;
  315. }
  316. #endregion
  317. #region Clamp
  318. public void Clamp(bool isUnloadClamp)
  319. {
  320. if (IsBusy)
  321. {
  322. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not clamp");
  323. return;
  324. }
  325. if (IsError)
  326. {
  327. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not clamp");
  328. return;
  329. }
  330. IsBusy = true;
  331. _controller.Clamp(Module, isUnloadClamp);
  332. }
  333. public void OnClamped(bool isUnloadClamp)
  334. {
  335. IsBusy = false;
  336. IsError = false;
  337. IsClamped = true;
  338. if (isUnloadClamp)
  339. {
  340. _faCallback.UnloadComplete(this);
  341. }
  342. else
  343. {
  344. _faCallback.Clamped(this);
  345. }
  346. }
  347. public void OnClampFailed(string data)
  348. {
  349. IsError = true;
  350. IsBusy = false;
  351. }
  352. #endregion
  353. #region Unclamp
  354. public void Unclamp()
  355. {
  356. if (IsBusy)
  357. {
  358. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not unclamp");
  359. return;
  360. }
  361. if (IsError)
  362. {
  363. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not unclamp");
  364. return;
  365. }
  366. IsBusy = true;
  367. _controller.Unclamp(Module);
  368. }
  369. public void OnUnclamped()
  370. {
  371. IsBusy = false;
  372. IsError = false;
  373. IsClamped = false;
  374. _faCallback.Unclamped(this);
  375. }
  376. public void OnUnclampFailed(string data)
  377. {
  378. }
  379. #endregion
  380. #region map
  381. public void Map()
  382. {
  383. _controller.AddAction(new MapAction(_controller, Module));
  384. }
  385. #endregion
  386. #region carrierID
  387. public void ReadCarrierID()
  388. {
  389. if (IsBusy)
  390. {
  391. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not read carrier ID");
  392. return;
  393. }
  394. if (IsError)
  395. {
  396. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not read carrier ID");
  397. return;
  398. }
  399. IsBusy = true;
  400. _controller.ReadCarrierId(Module);
  401. }
  402. public void OnCarrierIDRead(string data)
  403. {
  404. IsBusy = false;
  405. IsError = false;
  406. //Regex rg = new Regex("(?<=(" + "LOT :" + "))[.\\s\\S]*?(?=(" + "QTY :" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  407. //string carrierID = rg.Match(data).Value.Replace(":", "").Trim();
  408. //data =
  409. // "CST:C082259 TYPE:CST25_AU LOT:AF2403 QTY:24 FLOW:033000 STATUS:HOLD PRI:3-1 PD:0418A CSRLOT: CLEAN:2021/11/14 19:57:50 EQPGRP:DUMMY STAGE:CP-TEST1 RECIPE:DUMMY EMP:N ";
  410. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  411. CarrierId = "";
  412. foreach (var item in items)
  413. {
  414. if (item.StartsWith("CST:") && item.Length > 4)
  415. CarrierId = item.Substring(4).Trim();
  416. if (item.StartsWith("LOT:") && item.Length > 4)
  417. LotId = item.Substring(4).Trim();
  418. }
  419. if (string.IsNullOrEmpty(CarrierId))
  420. {
  421. CarrierId = data;
  422. }
  423. SmartTag = data;
  424. _faCallback.IDRead(this);
  425. }
  426. public void OnCarrierIDReadFailed(string data)
  427. {
  428. IsError = true;
  429. IsBusy = false;
  430. _faCallback.ReadIDFailed(this);
  431. }
  432. public void WriteCarrierID(string id)
  433. {
  434. if (IsBusy)
  435. {
  436. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not write carrier ID");
  437. return;
  438. }
  439. if (IsError)
  440. {
  441. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not write carrier ID");
  442. return;
  443. }
  444. IsBusy = true;
  445. _controller.WriteCarrierId(Module, id);
  446. }
  447. public void OnCarrierIDWrite(string data)
  448. {
  449. IsBusy = false;
  450. IsError = false;
  451. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  452. CarrierId = "";
  453. foreach (var item in items)
  454. {
  455. if (item.StartsWith("CST:") && item.Length > 4)
  456. CarrierId = item.Substring(4);
  457. }
  458. if (string.IsNullOrEmpty(CarrierId))
  459. {
  460. CarrierId = data;
  461. }
  462. SmartTag = data;
  463. _faCallback.IDWrite(this);
  464. }
  465. public void OnCarrierIDWriteFailed(string data)
  466. {
  467. IsError = true;
  468. IsBusy = false;
  469. _faCallback.WriteIDFailed(this);
  470. }
  471. #endregion
  472. #region event
  473. public void HandleEvent(EfemEventArgs eArg)
  474. {
  475. switch (eArg.CommandType)
  476. {
  477. case EfemOperation.GetWaferInfo:
  478. string sWaferInfo = eArg.DataList[0];
  479. bool resultNormal = true;
  480. for (byte index = 0; index < sWaferInfo.Length; index++)
  481. {
  482. int waferState = int.Parse(sWaferInfo.Substring(index, 1));
  483. //合理的映射到内部支持的叠片/交叉片
  484. if (waferState >= 7) waferState = 7;
  485. else if (waferState >= 2) waferState = 3;
  486. WaferStatus st = (WaferStatus)waferState;
  487. WaferManager.Instance.UpdateWaferSize(this.Module, index, WaferSize);
  488. if (st != WaferStatus.Empty)
  489. {
  490. var _slot1UnSupportWaferSize = SC.GetStringValue($"System.LPSlot1UnSupportedWaferSize");
  491. if (index == 0 && !string.IsNullOrWhiteSpace(_slot1UnSupportWaferSize) && _slot1UnSupportWaferSize.Split(',').Select(p => "WS" + p).Contains(WaferSize.ToString()))
  492. {
  493. EV.PostWarningLog(this.Module.ToString(), $"Wafer on Slot {index + 1} {WaferSize} is not supported.");
  494. st = WaferStatus.Unknown;
  495. }
  496. WaferManager.Instance.CreateWafer(this.Module, index, st);
  497. if (st == WaferStatus.Normal)
  498. {
  499. EV.PostInfoLog(this.Module.ToString(), $"Found Wafer on Slot {index + 1} {WaferSize}");
  500. }
  501. else
  502. {
  503. resultNormal = false;
  504. EV.PostWarningLog(this.Module.ToString(), $"Found {st} Wafer on Slot {index + 1} {WaferSize}");
  505. }
  506. }
  507. else
  508. {
  509. WaferManager.Instance.DeleteWafer(this.Module, index);
  510. }
  511. }
  512. var dvidMap = new SerializableDictionary<string, string>();
  513. dvidMap[DVIDName.SlotMap] = sWaferInfo;
  514. dvidMap[DVIDName.PortID] = Module == ModuleName.LP1 ? "1" : "2";
  515. if (resultNormal)
  516. {
  517. EV.Notify(Module == ModuleName.LP1 ? Port1MappingComplete : Port2MappingComplete, dvidMap);
  518. }
  519. else
  520. {
  521. EV.Notify(Module == ModuleName.LP1 ? Port1MappingFailed : Port2MappingFailed, dvidMap);
  522. }
  523. this.IsMapped = true;
  524. break;
  525. case EfemOperation.SigStatus:
  526. // EVT: SIGSTAT/P2/00000381/00000000;
  527. string sParam = eArg.DataList[0];
  528. ModuleName mod = sParam.ToModule();
  529. if (!ModuleHelper.IsLoadPort(mod))
  530. return;
  531. // DATA1 & DATA2
  532. int nData1 = Convert.ToInt32(eArg.DataList[1], 16);
  533. int nData2 = Convert.ToInt32(eArg.DataList[2], 16);
  534. BitArray baData1 = new BitArray(new int[] { nData1 });
  535. BitArray baData2 = new BitArray(new int[] { nData2 });
  536. // wafer size
  537. // 代指小中大尺寸,不是指的实际尺寸
  538. this.WaferSize = !baData1[6] ? WaferSize.WS3 :
  539. !baData1[7] ? WaferSize.WS4 :
  540. !baData1[8] ? WaferSize.WS6 : WaferSize.WS0;
  541. //bool sizecheck1 = (nData1 & 0x00000040u) == 0x00000040u;
  542. //bool sizecheck2 = (nData1 & 0x00000080u) == 0x00000080u;
  543. //bool sizecheck3 = (nData1 & 0x00000100u) == 0x00000100u;
  544. //if (sizecheck1 && sizecheck2 && sizecheck3)
  545. //{
  546. // WaferSize = WaferSize.WS8;
  547. //}
  548. //else if (!sizecheck1 && sizecheck2 && sizecheck3)
  549. //{
  550. // WaferSize = WaferSize.WS3;
  551. //}
  552. //else if (sizecheck1 && sizecheck2 && !sizecheck3)
  553. //{
  554. // WaferSize = WaferSize.WS6;
  555. //}
  556. //else if (sizecheck1 && !sizecheck2 && sizecheck3)
  557. //{
  558. // WaferSize = WaferSize.WS4;
  559. //}
  560. // placement & present
  561. bool bPlacement = baData1[0]; // bit 0
  562. bool bPresence = !baData1[1]; // bit 1
  563. bool bArrived = bPlacement && bPresence;
  564. if (HasCassette)
  565. {
  566. if (!bArrived)
  567. {
  568. this.HasCassette = false;
  569. this.IsMapped = false;
  570. EV.PostInfoLog(mod.ToString(), "Cassette removed");
  571. OP.DoOperation("System.CassetteLeave"); //For unload light control off afer job done
  572. CarrierManager.Instance.DeleteCarrier(Module.ToString());
  573. WaferManager.Instance.DeleteWafer(this.Module, 0, 25);
  574. SerializableDictionary<string, string> dvid = new SerializableDictionary<string, string>();
  575. dvid["PortID"] = mod == ModuleName.LP1 ? "1" : "2";
  576. EV.Notify(mod == ModuleName.LP1 ? Port1CassetteRemoved : Port2CassetteRemoved, dvid);
  577. JobDone = false;
  578. _waferThicknessType = "";
  579. }
  580. }
  581. else
  582. {
  583. if (bArrived)
  584. {
  585. this.HasCassette = true;
  586. CarrierManager.Instance.CreateCarrier(Module.ToString());
  587. EV.PostInfoLog(mod.ToString(), $"Cassette {WaferSize} arrived");
  588. var dvid1 = new SerializableDictionary<string, string>();
  589. dvid1["PortID"] = mod == ModuleName.LP1 ? "1" : "2";
  590. EV.Notify(mod == ModuleName.LP1 ? Port1CassetteArrive : Port2CassetteArrive, dvid1);
  591. JobDone = false;
  592. _waferThicknessType = "";
  593. }
  594. }
  595. this.Protrusion = !((nData1 & 0x00000200u) == 0x00000200u);
  596. if (Protrusion)
  597. {
  598. EV.PostAlarmLog(Module.ToString(), "发现 wafer 突出");
  599. EV.Notify(AlarmWaferProtrude);
  600. Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
  601. }
  602. bool hasError = (nData1 & 0x00000400u) == 0x00000400u;
  603. if (hasError)
  604. {
  605. EV.PostAlarmLog(Module.ToString(), $"{Module} has error, check EFEM software getting detail or home to recover");
  606. Singleton<RouteManager>.Instance.EFEM.PostMsg(EfemEntity.MSG.Error);
  607. }
  608. // DATA2, loadport上面的LED 灯, 暂时不需要用到
  609. break;
  610. default:
  611. break;
  612. }
  613. }
  614. #endregion
  615. #region TagData
  616. public void ReadTagData()
  617. {
  618. if (IsBusy)
  619. {
  620. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not read tag data");
  621. return;
  622. }
  623. if (IsError)
  624. {
  625. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not read tag data");
  626. return;
  627. }
  628. IsBusy = true;
  629. _controller.ReadTagData(Module);
  630. }
  631. public void OnTagDataRead(string data)
  632. {
  633. IsBusy = false;
  634. IsError = false;
  635. //Regex rg = new Regex("(?<=(" + "LOT :" + "))[.\\s\\S]*?(?=(" + "QTY :" + "))", RegexOptions.Multiline | RegexOptions.Singleline);
  636. //string carrierID = rg.Match(data).Value.Replace(":", "").Trim();
  637. //data =
  638. // "CST:C082259 TYPE:CST25_AU LOT:AF2403 QTY:24 FLOW:033000 STATUS:HOLD PRI:3-1 PD:0418A CSRLOT: CLEAN:2021/11/14 19:57:50 EQPGRP:DUMMY STAGE:CP-TEST1 RECIPE:DUMMY EMP:N ";
  639. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  640. CarrierId = "";
  641. foreach (var item in items)
  642. {
  643. if (item.StartsWith("CST:") && item.Length > 4)
  644. CarrierId = item.Substring(4);
  645. if (item.StartsWith("LOT:") && item.Length > 4)
  646. LotId = item.Substring(4).Trim();
  647. }
  648. if (string.IsNullOrEmpty(CarrierId))
  649. {
  650. CarrierId = data;
  651. }
  652. SmartTag = data;
  653. _faCallback.TagDataRead(this);
  654. }
  655. public void OnTagDataReadFailed(string data)
  656. {
  657. IsError = true;
  658. IsBusy = false;
  659. _faCallback.ReadTagDataFailed(this);
  660. }
  661. public void WriteTagData(string tagData)
  662. {
  663. if (IsBusy)
  664. {
  665. EV.PostInfoLog(Module.ToString(), $"{Module} is busy can not write tag data");
  666. return;
  667. }
  668. if (IsError)
  669. {
  670. EV.PostInfoLog(Module.ToString(), $"{Module} is error can not write tag data");
  671. return;
  672. }
  673. IsBusy = true;
  674. _controller.WriteTagData(Module, tagData);
  675. }
  676. public void OnTagDataWrite(string data)
  677. {
  678. IsBusy = false;
  679. IsError = false;
  680. var items = data.Split(new string[] { " ", "\t", "\r", "\n" }, StringSplitOptions.RemoveEmptyEntries);
  681. CarrierId = "";
  682. foreach (var item in items)
  683. {
  684. if (item.StartsWith("CST:") && item.Length > 4)
  685. CarrierId = item.Substring(4);
  686. }
  687. if (string.IsNullOrEmpty(CarrierId))
  688. {
  689. CarrierId = data;
  690. }
  691. SmartTag = data;
  692. _faCallback.TagDataWrite(this);
  693. }
  694. public void OnTagDataWriteFailed(string data)
  695. {
  696. IsError = true;
  697. IsBusy = false;
  698. _faCallback.WriteTagDataFailed( this);
  699. }
  700. #endregion
  701. public void SetOnline(bool online)
  702. {
  703. OnlineFlag = online ? OnlineFlag.Online : OnlineFlag.Offline;
  704. }
  705. sealed class LoadPortFACallback
  706. {
  707. private const string Port1LoadComplete = "Port1LoadComplete";
  708. private const string Port1LoadFailed = "Port1LoadFailed";
  709. private const string Port1UnloadComplete = "Port1UnloadComplete";
  710. private const string Port1UnloadFailed = "Port1UnloadFailed";
  711. private const string Port1Clamped = "Port1Clamped";
  712. private const string Port1Unclamped = "Port1Unclamped";
  713. private const string Port1IDRead = "Port1IDRead";
  714. private const string Port1ReadIDFailed = "Port1ReadIDFailed";
  715. private const string Port1IDWrite = "Port1IDWrite";
  716. private const string Port1WriteIDFailed = "Port1WriteIDFailed";
  717. private const string Port1TagDataRead = "Port1TagDataRead";
  718. private const string Port1ReadTagDataFailed = "Port1ReadTagDataFailed";
  719. private const string Port1TagDataWrite = "Port1TagDataWrite";
  720. private const string Port1WriteTagDataFailed = "Port1WriteTagDataFailed";
  721. private const string Port2LoadComplete = "Port2LoadComplete";
  722. private const string Port2LoadFailed = "Port2LoadFailed";
  723. private const string Port2UnloadComplete = "Port2UnloadComplete";
  724. private const string Port2UnloadFailed = "Port2UnloadFailed";
  725. private const string Port2Clamped = "Port2Clamped";
  726. private const string Port2Unclamped = "Port2Unclamped";
  727. private const string Port2IDRead = "Port2IDRead";
  728. private const string Port2ReadIDFailed = "Port2ReadIDFailed";
  729. private const string Port2IDWrite = "Port2IDWrite";
  730. private const string Port2WriteIDFailed = "Port2WriteIDFailed";
  731. private const string Port2TagDataRead = "Port2TagDataRead";
  732. private const string Port2ReadTagDataFailed = "Port2ReadTagDataFailed";
  733. private const string Port2TagDataWrite = "Port2TagDataWrite";
  734. private const string Port2WriteTagDataFailed = "Port2WriteTagDataFailed";
  735. private Dictionary<ModuleName, string> PortLoadComplete = new Dictionary<ModuleName, string>()
  736. {
  737. {ModuleName.LP1, Port1LoadComplete},
  738. {ModuleName.LP2, Port2LoadComplete},
  739. };
  740. private Dictionary<ModuleName, string> PortLoadFailed = new Dictionary<ModuleName, string>()
  741. {
  742. {ModuleName.LP1, Port1LoadFailed},
  743. {ModuleName.LP2, Port2LoadFailed},
  744. };
  745. private Dictionary<ModuleName, string> PortUnloadComplete = new Dictionary<ModuleName, string>()
  746. {
  747. {ModuleName.LP1, Port1UnloadComplete},
  748. {ModuleName.LP2, Port2UnloadComplete},
  749. };
  750. private Dictionary<ModuleName, string> PortUnloadFailed = new Dictionary<ModuleName, string>()
  751. {
  752. {ModuleName.LP1, Port1UnloadFailed},
  753. {ModuleName.LP2, Port2UnloadFailed},
  754. };
  755. private Dictionary<ModuleName, string> PortClamped = new Dictionary<ModuleName, string>()
  756. {
  757. {ModuleName.LP1, Port1Clamped},
  758. {ModuleName.LP2, Port2Clamped},
  759. };
  760. private Dictionary<ModuleName, string> PortUnclamped = new Dictionary<ModuleName, string>()
  761. {
  762. {ModuleName.LP1, Port1Unclamped},
  763. {ModuleName.LP2, Port2Unclamped},
  764. };
  765. private Dictionary<ModuleName, string> PortIDRead = new Dictionary<ModuleName, string>()
  766. {
  767. {ModuleName.LP1, Port1IDRead},
  768. {ModuleName.LP2, Port2IDRead},
  769. };
  770. private Dictionary<ModuleName, string> PortReadIDFailed = new Dictionary<ModuleName, string>()
  771. {
  772. {ModuleName.LP1, Port1ReadIDFailed},
  773. {ModuleName.LP2, Port2ReadIDFailed},
  774. };
  775. private Dictionary<ModuleName, string> PortIDWrite = new Dictionary<ModuleName, string>()
  776. {
  777. {ModuleName.LP1, Port1IDWrite},
  778. {ModuleName.LP2, Port2IDWrite},
  779. };
  780. private Dictionary<ModuleName, string> PortWriteIDFailed = new Dictionary<ModuleName, string>()
  781. {
  782. {ModuleName.LP1, Port1WriteIDFailed},
  783. {ModuleName.LP2, Port2WriteIDFailed},
  784. };
  785. private Dictionary<ModuleName, string> PortTagDataRead = new Dictionary<ModuleName, string>()
  786. {
  787. {ModuleName.LP1, Port1TagDataRead},
  788. {ModuleName.LP2, Port2TagDataRead},
  789. };
  790. private Dictionary<ModuleName, string> PortReadTagDataFailed = new Dictionary<ModuleName, string>()
  791. {
  792. {ModuleName.LP1, Port1ReadTagDataFailed},
  793. {ModuleName.LP2, Port2ReadTagDataFailed},
  794. };
  795. private Dictionary<ModuleName, string> PortTagDataWrite = new Dictionary<ModuleName, string>()
  796. {
  797. {ModuleName.LP1, Port1TagDataWrite},
  798. {ModuleName.LP2, Port2TagDataWrite},
  799. };
  800. private Dictionary<ModuleName, string> PortWriteTagDataFailed = new Dictionary<ModuleName, string>()
  801. {
  802. {ModuleName.LP1, Port1WriteTagDataFailed},
  803. {ModuleName.LP2, Port2WriteTagDataFailed},
  804. };
  805. private Dictionary<ModuleName, string> PortId = new Dictionary<ModuleName, string>()
  806. {
  807. {ModuleName.LP1, "1"},
  808. {ModuleName.LP2, "2"},
  809. };
  810. public LoadPortFACallback()
  811. {
  812. EV.Subscribe(new EventItem("Event", Port1LoadComplete, Port1LoadComplete));
  813. EV.Subscribe(new EventItem("Event", Port1LoadFailed, Port1LoadFailed));
  814. EV.Subscribe(new EventItem("Event", Port1UnloadComplete, Port1UnloadComplete));
  815. EV.Subscribe(new EventItem("Event", Port1UnloadFailed, Port1UnloadFailed));
  816. EV.Subscribe(new EventItem("Event", Port1Clamped, Port1Clamped));
  817. EV.Subscribe(new EventItem("Event", Port1Unclamped, Port1Unclamped));
  818. EV.Subscribe(new EventItem("Event", Port1IDRead, Port1IDRead));
  819. EV.Subscribe(new EventItem("Event", Port1ReadIDFailed, Port1ReadIDFailed));
  820. EV.Subscribe(new EventItem("Event", Port1IDWrite, Port1IDWrite));
  821. EV.Subscribe(new EventItem("Event", Port1WriteIDFailed, Port1WriteIDFailed));
  822. EV.Subscribe(new EventItem("Event", Port1TagDataRead, Port1TagDataRead));
  823. EV.Subscribe(new EventItem("Event", Port1ReadTagDataFailed, Port1ReadTagDataFailed));
  824. EV.Subscribe(new EventItem("Event", Port1TagDataWrite, Port1TagDataWrite));
  825. EV.Subscribe(new EventItem("Event", Port1WriteTagDataFailed, Port1WriteTagDataFailed));
  826. EV.Subscribe(new EventItem("Event", Port2LoadComplete, Port2LoadComplete));
  827. EV.Subscribe(new EventItem("Event", Port2LoadFailed, Port2LoadFailed));
  828. EV.Subscribe(new EventItem("Event", Port2UnloadComplete, Port2UnloadComplete));
  829. EV.Subscribe(new EventItem("Event", Port2UnloadFailed, Port2UnloadFailed));
  830. EV.Subscribe(new EventItem("Event", Port2Clamped, Port2Clamped));
  831. EV.Subscribe(new EventItem("Event", Port2Unclamped, Port2Unclamped));
  832. EV.Subscribe(new EventItem("Event", Port2IDRead, Port2IDRead));
  833. EV.Subscribe(new EventItem("Event", Port2ReadIDFailed, Port2ReadIDFailed));
  834. EV.Subscribe(new EventItem("Event", Port2IDWrite, Port2IDWrite));
  835. EV.Subscribe(new EventItem("Event", Port2WriteIDFailed, Port2WriteIDFailed));
  836. EV.Subscribe(new EventItem("Event", Port2TagDataRead, Port2TagDataRead));
  837. EV.Subscribe(new EventItem("Event", Port2ReadTagDataFailed, Port2ReadTagDataFailed));
  838. EV.Subscribe(new EventItem("Event", Port2TagDataWrite, Port2TagDataWrite));
  839. EV.Subscribe(new EventItem("Event", Port2WriteTagDataFailed, Port2WriteTagDataFailed));
  840. }
  841. public void LoadComplete(Loadport lp)
  842. {
  843. ModuleName moduleName = lp.Module;
  844. EV.Notify(PortLoadComplete[moduleName], new SerializableDictionary<string, string>()
  845. {
  846. {DVIDName.PortID, PortId[lp.Module] },
  847. });
  848. }
  849. public void LoadFailed(Loadport lp)
  850. {
  851. ModuleName moduleName = lp.Module;
  852. EV.Notify(PortLoadFailed[moduleName], new SerializableDictionary<string, string>()
  853. {
  854. {DVIDName.PortID, PortId[lp.Module] },
  855. });
  856. }
  857. public void UnloadComplete(Loadport lp)
  858. {
  859. ModuleName moduleName = lp.Module;
  860. EV.Notify(PortUnloadComplete[moduleName], new SerializableDictionary<string, string>()
  861. {
  862. {DVIDName.PortID, PortId[lp.Module] },
  863. });
  864. }
  865. public void UnloadFailed(Loadport lp)
  866. {
  867. ModuleName moduleName = lp.Module;
  868. EV.Notify(PortUnloadFailed[moduleName], new SerializableDictionary<string, string>()
  869. {
  870. {DVIDName.PortID, PortId[lp.Module] },
  871. });
  872. }
  873. public void Clamped(Loadport lp)
  874. {
  875. ModuleName moduleName = lp.Module;
  876. EV.Notify(PortClamped[moduleName], new SerializableDictionary<string, string>()
  877. {
  878. {DVIDName.PortID, PortId[lp.Module] },
  879. });
  880. }
  881. public void Unclamped(Loadport lp)
  882. {
  883. ModuleName moduleName = lp.Module;
  884. EV.Notify(PortUnclamped[moduleName], new SerializableDictionary<string, string>()
  885. {
  886. {DVIDName.PortID, PortId[lp.Module] },
  887. });
  888. }
  889. public void IDRead(Loadport lp)
  890. {
  891. ModuleName moduleName = lp.Module;
  892. EV.Notify(PortIDRead[moduleName], new SerializableDictionary<string, string>()
  893. {
  894. {DVIDName.PortID, PortId[lp.Module] },
  895. {DVIDName.CarrierID, lp.CarrierId },
  896. {DVIDName.LotID, lp.LotId },
  897. });
  898. }
  899. public void ReadIDFailed(Loadport lp)
  900. {
  901. ModuleName moduleName = lp.Module;
  902. EV.Notify(PortReadIDFailed[moduleName], new SerializableDictionary<string, string>()
  903. {
  904. {DVIDName.PortID, PortId[lp.Module] },
  905. });
  906. }
  907. public void IDWrite(Loadport lp)
  908. {
  909. ModuleName moduleName = lp.Module;
  910. EV.Notify(PortIDWrite[moduleName], new SerializableDictionary<string, string>()
  911. {
  912. {DVIDName.PortID, PortId[lp.Module] },
  913. {DVIDName.CarrierID, lp.CarrierId },
  914. });
  915. }
  916. public void WriteIDFailed(Loadport lp)
  917. {
  918. ModuleName moduleName = lp.Module;
  919. EV.Notify(PortWriteIDFailed[moduleName], new SerializableDictionary<string, string>()
  920. {
  921. {DVIDName.PortID, PortId[lp.Module] },
  922. });
  923. }
  924. public void TagDataRead(Loadport lp)
  925. {
  926. ModuleName moduleName = lp.Module;
  927. EV.Notify(PortTagDataRead[moduleName], new SerializableDictionary<string, string>()
  928. {
  929. {DVIDName.PortID, PortId[lp.Module] },
  930. {DVIDName.TagData, lp.SmartTag },
  931. {DVIDName.CarrierID, lp.CarrierId },
  932. {DVIDName.LotID, lp.LotId },
  933. });
  934. }
  935. public void ReadTagDataFailed(Loadport lp)
  936. {
  937. ModuleName moduleName = lp.Module;
  938. EV.Notify(PortReadTagDataFailed[moduleName], new SerializableDictionary<string, string>()
  939. {
  940. {DVIDName.PortID, PortId[lp.Module] },
  941. });
  942. }
  943. public void TagDataWrite(Loadport lp)
  944. {
  945. ModuleName moduleName = lp.Module;
  946. EV.Notify(PortTagDataWrite[moduleName], new SerializableDictionary<string, string>()
  947. {
  948. {DVIDName.PortID, PortId[lp.Module] },
  949. {DVIDName.CarrierID, lp.CarrierId },
  950. {DVIDName.TagData, lp.SmartTag },
  951. });
  952. }
  953. public void WriteTagDataFailed(Loadport lp)
  954. {
  955. ModuleName moduleName = lp.Module;
  956. EV.Notify(PortWriteTagDataFailed[moduleName], new SerializableDictionary<string, string>()
  957. {
  958. {DVIDName.PortID, PortId[lp.Module] },
  959. });
  960. }
  961. }
  962. }
  963. }