StaticTransfer.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. using System;
  2. using System.Collections.Generic;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.Routine;
  6. using Aitex.Core.Util;
  7. using EFEM.RT.Devices;
  8. using EFEM.RT.Routines;
  9. using Aitex.Sorter.Common;
  10. using MECF.Framework.Common.Equipment;
  11. using MECF.Framework.Common.SubstrateTrackings;
  12. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  13. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.LoadPortBase;
  14. namespace EFEM.RT.Modules
  15. {
  16. public class StaticTransfer
  17. {
  18. public int Notch1 { get; set; }
  19. public int Notch2 { get; set; }
  20. public ModuleName SourceStation => _sourceStation;
  21. public ModuleName TargetStation => _targetStation;
  22. private Queue<IRoutine> steps = null;
  23. private IRoutine curStep = null;
  24. private PickRoutine[] pickRoutine = null;
  25. private PlaceRoutine[] placeRoutine = null;
  26. private AlignRoutine[] alignRoutine = null;
  27. private ModuleName _sourceStation;
  28. private ModuleName _targetStation;
  29. public bool Initialize()
  30. {
  31. steps = new Queue<IRoutine>();
  32. pickRoutine = new PickRoutine[5];
  33. for (int i = 0; i < 5; i++)
  34. {
  35. pickRoutine[i] = new PickRoutine("System", "PickWafer");
  36. pickRoutine[i].Initalize();
  37. }
  38. placeRoutine = new PlaceRoutine[5];
  39. for (int i = 0; i < 5; i++)
  40. {
  41. placeRoutine[i] = new PlaceRoutine("System", "PlaceWafer");
  42. placeRoutine[i].Initalize();
  43. }
  44. alignRoutine = new AlignRoutine[2];
  45. for (int i = 0; i < 2; i++)
  46. {
  47. alignRoutine[i] = new AlignRoutine("System", "Alignment");
  48. alignRoutine[i].Initalize();
  49. }
  50. return true;
  51. }
  52. public bool Start(object[] objs)
  53. {
  54. MoveType type = (MoveType)objs[0];
  55. MoveOption option = (MoveOption)objs[1];
  56. bool bAlign = ((option & MoveOption.Align) == MoveOption.Align) ||
  57. ((option & MoveOption.ReadID) == MoveOption.ReadID) ||
  58. ((option & MoveOption.ReadID2) == MoveOption.ReadID2);
  59. Hand hand = (Hand)objs[2];
  60. ModuleName st1 = (ModuleName)objs[3];
  61. _sourceStation = st1;
  62. int ss1 = (int)objs[4];
  63. ModuleName dt1 = (ModuleName)objs[5];
  64. _targetStation = dt1;
  65. int ds1 = (int)objs[6];
  66. steps.Clear();
  67. // if (st1 == ModuleName.Robot)
  68. // hand = (Hand)ss1;
  69. if (type == MoveType.Move) //单片传输
  70. {
  71. if (st1 != ModuleName.Robot)
  72. {
  73. pickRoutine[0].Source = st1;
  74. pickRoutine[0].Slot = ss1;
  75. pickRoutine[0].Blade = hand;
  76. steps.Enqueue(pickRoutine[0]);
  77. }
  78. if (bAlign)
  79. {
  80. placeRoutine[0].Station = ModuleName.Aligner;
  81. placeRoutine[0].Slot = 0;
  82. placeRoutine[0].Blade = hand;
  83. steps.Enqueue(placeRoutine[0]);
  84. alignRoutine[0].Option = option;
  85. alignRoutine[0].Notch = Notch1;
  86. steps.Enqueue(alignRoutine[0]);
  87. if (dt1 != ModuleName.Aligner)
  88. {
  89. if (dt1 == ModuleName.Robot)
  90. {
  91. pickRoutine[1].Source = ModuleName.Aligner;
  92. pickRoutine[1].Slot = 0;
  93. pickRoutine[1].Blade = (Hand)ds1;
  94. steps.Enqueue(pickRoutine[1]);
  95. }
  96. else
  97. {
  98. pickRoutine[1].Source = ModuleName.Aligner;
  99. pickRoutine[1].Slot = 0;
  100. pickRoutine[1].Blade = hand;
  101. steps.Enqueue(pickRoutine[1]);
  102. placeRoutine[1].Station = dt1;
  103. placeRoutine[1].Slot = ds1;
  104. placeRoutine[1].Blade = hand;
  105. steps.Enqueue(placeRoutine[1]);
  106. }
  107. }
  108. }
  109. else
  110. {
  111. if (dt1 != ModuleName.Robot)
  112. {
  113. placeRoutine[1].Station = dt1;
  114. placeRoutine[1].Slot = ds1;
  115. placeRoutine[1].Blade = hand;
  116. steps.Enqueue(placeRoutine[1]);
  117. }
  118. }
  119. }
  120. else if (type == MoveType.Swap) //交换
  121. {
  122. //do nothing
  123. }
  124. else //双片传盘
  125. {
  126. ModuleName st2 = (ModuleName)objs[7];
  127. int ss2 = (int)objs[8];
  128. ModuleName dt2 = (ModuleName)objs[9];
  129. int ds2 = (int)objs[10];
  130. if (type == MoveType.SPSP || type == MoveType.SPDP) //seperate pick
  131. {
  132. if (st1 != ModuleName.Robot && st2 != ModuleName.Robot)
  133. {
  134. pickRoutine[0].Source = st1;
  135. pickRoutine[0].Slot = ss1;
  136. pickRoutine[0].Blade = Hand.Blade1;
  137. steps.Enqueue(pickRoutine[0]);
  138. pickRoutine[1].Source = st2;
  139. pickRoutine[1].Slot = ss2;
  140. pickRoutine[1].Blade = Hand.Blade2;
  141. steps.Enqueue(pickRoutine[1]);
  142. }
  143. else
  144. {
  145. if (st1 == ModuleName.Robot)
  146. {
  147. pickRoutine[1].Source = st2;
  148. pickRoutine[1].Slot = ss2;
  149. if (ss1 == (int)Hand.Blade1)
  150. pickRoutine[1].Blade = Hand.Blade2;
  151. else
  152. pickRoutine[1].Blade = Hand.Blade1;
  153. steps.Enqueue(pickRoutine[1]);
  154. }
  155. else
  156. {
  157. pickRoutine[0].Source = st1;
  158. pickRoutine[0].Slot = ss1;
  159. if (ss2 == (int)Hand.Blade1)
  160. pickRoutine[0].Blade = Hand.Blade2;
  161. else
  162. pickRoutine[0].Blade = Hand.Blade1;
  163. steps.Enqueue(pickRoutine[0]);
  164. }
  165. }
  166. }
  167. else
  168. {
  169. if (st1 != ModuleName.Robot)
  170. {
  171. pickRoutine[0].Source = st1;
  172. pickRoutine[0].Slot = ss1;
  173. pickRoutine[0].Blade = Hand.Both;
  174. steps.Enqueue(pickRoutine[0]);
  175. }
  176. }
  177. if (type == MoveType.SPSP || type == MoveType.DPSP) //serpate place
  178. {
  179. if (dt1 != ModuleName.Robot && dt1 != ModuleName.Robot)
  180. {
  181. placeRoutine[1].Station = dt1;
  182. placeRoutine[1].Slot = ds1;
  183. placeRoutine[1].Blade = Hand.Blade1;
  184. steps.Enqueue(placeRoutine[1]);
  185. placeRoutine[2].Station = dt2;
  186. placeRoutine[2].Slot = ds2;
  187. placeRoutine[2].Blade = Hand.Blade2;
  188. steps.Enqueue(placeRoutine[2]);
  189. }
  190. else
  191. {
  192. if (dt1 == ModuleName.Robot)
  193. {
  194. placeRoutine[2].Station = dt2;
  195. placeRoutine[2].Slot = ds2;
  196. if (ss2 == (int)Hand.Blade1)
  197. placeRoutine[2].Blade = Hand.Blade2;
  198. else
  199. placeRoutine[2].Blade = Hand.Blade1;
  200. steps.Enqueue(placeRoutine[2]);
  201. }
  202. else
  203. {
  204. placeRoutine[1].Station = dt1;
  205. placeRoutine[1].Slot = ds1;
  206. if (ss1 == (int)Hand.Blade1)
  207. placeRoutine[1].Blade = Hand.Blade2;
  208. else
  209. placeRoutine[1].Blade = Hand.Blade1;
  210. steps.Enqueue(placeRoutine[1]);
  211. }
  212. }
  213. }
  214. else
  215. {
  216. if (dt1 != ModuleName.Robot)
  217. {
  218. placeRoutine[1].Station = dt1;
  219. placeRoutine[1].Slot = ds1;
  220. placeRoutine[1].Blade = Hand.Both;
  221. steps.Enqueue(placeRoutine[1]);
  222. }
  223. }
  224. }
  225. if (steps.Count == 0)
  226. {
  227. string reason = string.Format("Unsupport transfer path {0} {1:D2} to {2} {3:D2}", st1.ToString(), ss1, dt1.ToString(), ds1);
  228. EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, reason);
  229. return false;
  230. }
  231. curStep = steps.Dequeue();
  232. if (curStep.Start(objs) == Result.FAIL)
  233. {
  234. EV.PostWarningLog(ModuleName.System.ToString(), "Failed start transfer");
  235. return false;
  236. }
  237. return true;
  238. }
  239. public bool Return(object[] objs)
  240. {
  241. steps.Clear();
  242. ModuleName chamber = ModuleName.LP1;
  243. int slot = 0;
  244. if (WaferManager.Instance.CheckHasWafer(ModuleName.Robot, (int)Hand.Blade1))
  245. {
  246. if(!FindEmptySlot(ref chamber, ref slot))
  247. {
  248. EV.PostMessage(ModuleName.System.ToString(),EventEnum.DefaultWarning,"No empty slot for return wafers");
  249. steps.Clear();
  250. return false;
  251. }
  252. placeRoutine[0].Station = chamber;
  253. placeRoutine[0].Slot = slot;
  254. placeRoutine[0].Blade = Hand.Blade1;
  255. steps.Enqueue(placeRoutine[0]);
  256. }
  257. if ( WaferManager.Instance.CheckHasWafer(ModuleName.Robot, (int)Hand.Blade2)
  258. || WaferManager.Instance.CheckHasWafer(ModuleName.Robot, (int)Hand.Blade2 + 1)
  259. || WaferManager.Instance.CheckHasWafer(ModuleName.Robot, (int)Hand.Blade2 + 2)
  260. )
  261. {
  262. slot++;
  263. if(!FindEmptySlotForMultiBlade(ref chamber, ref slot))
  264. {
  265. EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, "No empty slot for return wafers");
  266. steps.Clear();
  267. return false;
  268. }
  269. placeRoutine[1].Station = chamber;
  270. placeRoutine[1].Slot = slot;
  271. placeRoutine[1].Blade = Hand.Blade2;
  272. steps.Enqueue(placeRoutine[1]);
  273. }
  274. if (WaferManager.Instance.CheckHasWafer(ModuleName.Aligner, 0))
  275. {
  276. slot++;
  277. if(!FindEmptySlot(ref chamber, ref slot))
  278. {
  279. EV.PostMessage(ModuleName.System.ToString(), EventEnum.DefaultWarning, "No empty slot for return wafers");
  280. steps.Clear();
  281. return false;
  282. }
  283. pickRoutine[0].Source = ModuleName.Aligner;
  284. pickRoutine[0].Slot = 0;
  285. pickRoutine[0].Blade = Hand.Blade1;
  286. steps.Enqueue(pickRoutine[0]);
  287. placeRoutine[2].Station = chamber;
  288. placeRoutine[2].Slot = slot;
  289. placeRoutine[2].Blade = Hand.Blade1;
  290. steps.Enqueue(placeRoutine[2]);
  291. }
  292. if (steps.Count == 0)
  293. {
  294. return false;
  295. }
  296. curStep = steps.Dequeue();
  297. if (curStep.Start(objs) == Result.FAIL)
  298. {
  299. EV.PostWarningLog(ModuleName.System.ToString(), "Failed start return");
  300. return false;
  301. }
  302. return true;
  303. }
  304. private bool FindEmptySlot(ref ModuleName lpModule, ref int slot)
  305. {
  306. LoadPortBaseDevice lp = DEVICE.GetDevice<LoadPortBaseDevice>(lpModule.ToString());
  307. if (lp.IsEnableTransferWafer(out _))
  308. {
  309. for (int index = slot; index < 25; index++)
  310. {
  311. if (WaferManager.Instance.CheckNoWafer(lp.Name, index))
  312. {
  313. slot = index;
  314. return true;
  315. }
  316. }
  317. }
  318. LoadPortBaseDevice[] lps = Singleton<DeviceManager>.Instance.GetAllLoadPorts();
  319. foreach (var loadPort in lps)
  320. {
  321. if (loadPort.Name == lpModule.ToString())
  322. continue;
  323. if (loadPort.IsEnableTransferWafer(out _))
  324. {
  325. for (int index = 0; index < 25; index++)
  326. {
  327. if (WaferManager.Instance.CheckNoWafer(loadPort.Name, index))
  328. {
  329. lpModule = (ModuleName) Enum.Parse(typeof(ModuleName), loadPort.Name);
  330. slot = index;
  331. return true;
  332. }
  333. }
  334. }
  335. }
  336. return false;
  337. }
  338. private bool FindEmptySlotForMultiBlade( ref ModuleName lpModule, ref int slot)
  339. {
  340. LoadPortBaseDevice lp = DEVICE.GetDevice<LoadPortBaseDevice>(lpModule.ToString());
  341. if (lp.IsEnableTransferWafer(out _))
  342. {
  343. for (int index = slot; index < 23; index++)
  344. {
  345. if ( WaferManager.Instance.CheckNoWafer(lp.Name, index)
  346. && WaferManager.Instance.CheckNoWafer(lp.Name, index + 1)
  347. && WaferManager.Instance.CheckNoWafer(lp.Name, index + 2)
  348. )
  349. {
  350. slot = index;
  351. return true;
  352. }
  353. }
  354. }
  355. LoadPortBaseDevice[] lps = Singleton<DeviceManager>.Instance.GetAllLoadPorts();
  356. foreach (var loadPort in lps)
  357. {
  358. if (loadPort.Name == lpModule.ToString())
  359. continue;
  360. if (loadPort.IsEnableTransferWafer(out _))
  361. {
  362. for (int index = 0; index < 23; index++)
  363. {
  364. if(WaferManager.Instance.CheckNoWafer(loadPort.Name, index)
  365. && WaferManager.Instance.CheckNoWafer(loadPort.Name, index + 1)
  366. && WaferManager.Instance.CheckNoWafer(loadPort.Name, index + 2)
  367. )
  368. {
  369. lpModule = (ModuleName)Enum.Parse(typeof(ModuleName), loadPort.Name);
  370. slot = index;
  371. return true;
  372. }
  373. }
  374. }
  375. }
  376. return false;
  377. }
  378. public bool Monitor(object[] objs)
  379. {
  380. Result ret = Result.FAIL;
  381. if (curStep != null)
  382. {
  383. ret = curStep.Monitor();
  384. }
  385. if (ret == Result.DONE)
  386. {
  387. if (steps.Count > 0)
  388. {
  389. curStep = steps.Dequeue();
  390. }
  391. else
  392. {
  393. curStep = null;
  394. }
  395. if (curStep != null)
  396. {
  397. ret = curStep.Start();
  398. if (ret == Result.FAIL)
  399. {
  400. PostMsg(RouteManager.MSG.ERROR);
  401. return true; //transition
  402. }
  403. }
  404. else
  405. {
  406. return true; //transition
  407. }
  408. return false;
  409. }
  410. else if (ret == Result.FAIL)
  411. {
  412. PostMsg(RouteManager.MSG.ERROR);
  413. return true; //transition
  414. }
  415. return false;
  416. }
  417. public void Clear()
  418. {
  419. steps.Clear();
  420. curStep = null;
  421. }
  422. private void PostMsg(RouteManager.MSG msg, params object[] objs)
  423. {
  424. Singleton<RouteManager>.Instance.PostMsg(msg, objs);
  425. }
  426. }
  427. }