LoadPortLoadRoutine.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. using System;
  2. using Aitex.Core.Common;
  3. using Aitex.Core.RT.Device;
  4. using Aitex.Core.RT.Event;
  5. using Aitex.Core.RT.Log;
  6. using Aitex.Core.RT.Routine;
  7. using Aitex.Core.RT.SCCore;
  8. using FutureEfemLib.Efems;
  9. using MECF.Framework.Common.Equipment;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  12. using MECF.Framework.RT.ModuleLibrary.SystemModules;
  13. namespace FutureEfemLib.LPs
  14. {
  15. class LoadPortLoadRoutine : ModuleRoutine, IRoutine
  16. {
  17. enum RoutineStep
  18. {
  19. Clamp,
  20. Dock,
  21. OpenDoor,
  22. QueryStatus1,
  23. WaitRobotIdle,
  24. Map,
  25. GetWaferInfo,
  26. QueryStatus2,
  27. }
  28. private int _timeout = 0;
  29. LoadPort _lp = null;
  30. private LoadPortModule _lpModule;
  31. private EfemModule _efem;
  32. public LoadPortLoadRoutine(LoadPortModule lpModule)
  33. {
  34. _lpModule = lpModule;
  35. _efem = EquipmentManager.Modules[ModuleName.EFEM] as EfemModule;
  36. Module = lpModule.Module;
  37. Name = "Load";
  38. _lp = DEVICE.GetDevice<LoadPort>($"{Module}");
  39. }
  40. public bool Initalize()
  41. {
  42. return true;
  43. }
  44. public Result Start(params object[] objs)
  45. {
  46. Reset();
  47. _timeout = SC.GetValue<int>("EFEM.LoadPort.HomeTimeout");
  48. var waferSize = _lp.GetCurrentWaferSize();
  49. if (waferSize != WaferSize.WS8 && waferSize != WaferSize.WS12)
  50. {
  51. EV.PostWarningLog(Module, $"{Module} get wafer size abnormal, can not load");
  52. return Result.FAIL;
  53. }
  54. if (!_lp.IsPresent || !_lp.IsPlacement)
  55. {
  56. EV.PostWarningLog(Module, $"{Module} not found carrier, can not load");
  57. return Result.FAIL;
  58. }
  59. Notify($"Start");
  60. return Result.RUN;
  61. }
  62. public Result Monitor()
  63. {
  64. try
  65. {
  66. Clamp((int)RoutineStep.Clamp, _lp, _timeout);
  67. //Dock((int)RoutineStep.Dock, _lp, _timeout);
  68. OpenDoor((int)RoutineStep.OpenDoor, _lp, _timeout);
  69. //if (_lp.GetCurrentWaferSize()!=WaferSize.WS12)
  70. //{
  71. // QueryStatus((int)RoutineStep.QueryStatus1, _lp, _timeout);
  72. // WaitRobotIdle((int)RoutineStep.WaitRobotIdle, _lp, _timeout);
  73. // Map((int)RoutineStep.Map, _lp, _timeout);
  74. //}
  75. if (_lp.GetCurrentWaferSize() == WaferSize.WS12)
  76. {
  77. QueryMapInfo((int)RoutineStep.GetWaferInfo, _lp, _timeout);
  78. }
  79. QueryStatus((int)RoutineStep.QueryStatus2, _lp, _timeout);
  80. }
  81. catch (RoutineBreakException)
  82. {
  83. return Result.RUN;
  84. }
  85. catch (RoutineFaildException ex)
  86. {
  87. LOG.Write(ex);
  88. return Result.FAIL;
  89. }
  90. Notify("Finished");
  91. return Result.DONE;
  92. }
  93. public void OpenDoor(int id, LoadPort lp, int timeout)
  94. {
  95. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  96. {
  97. Notify($"Start OpenDoorAndMap {lp.Name}");
  98. string reason;
  99. if (!lp.OpenDoor(out reason))
  100. {
  101. Stop(reason);
  102. return false;
  103. }
  104. return true;
  105. }, () =>
  106. {
  107. if (_lp.Error)
  108. return false;
  109. if (_lp.IsBusy)
  110. return false;
  111. return true;
  112. }, timeout * 1000);
  113. if (ret.Item1)
  114. {
  115. if (ret.Item2 == Result.FAIL)
  116. {
  117. Stop(string.Format("failed."));
  118. throw (new RoutineFaildException());
  119. }
  120. else if (ret.Item2 == Result.TIMEOUT) //timeout
  121. {
  122. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  123. throw (new RoutineFaildException());
  124. }
  125. else
  126. throw (new RoutineBreakException());
  127. }
  128. }
  129. public void Dock(int id, LoadPort lp, int timeout)
  130. {
  131. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  132. {
  133. Notify($"Start Dock {lp.Name}");
  134. string reason;
  135. if (!lp.Dock(out reason))
  136. {
  137. Stop(reason);
  138. return false;
  139. }
  140. return true;
  141. }, () =>
  142. {
  143. if (_lp.Error)
  144. return false;
  145. if (_lp.IsBusy)
  146. return false;
  147. return true;
  148. }, timeout * 1000);
  149. if (ret.Item1)
  150. {
  151. if (ret.Item2 == Result.FAIL)
  152. {
  153. Stop(string.Format("failed."));
  154. throw (new RoutineFaildException());
  155. }
  156. else if (ret.Item2 == Result.TIMEOUT) //timeout
  157. {
  158. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  159. throw (new RoutineFaildException());
  160. }
  161. else
  162. throw (new RoutineBreakException());
  163. }
  164. }
  165. public void WaitRobotIdle(int id, LoadPort lp, int timeout)
  166. {
  167. Tuple<bool, Result> ret = Wait(id, () =>
  168. {
  169. if(WaferManager.Instance.CheckHasWafer(ModuleName.EfemRobot,0))
  170. return false;
  171. if(_efem.IsBusy)
  172. return false;
  173. if (_lp.Error)
  174. return false;
  175. if (_lp.IsBusy)
  176. return false;
  177. if (_efem.RobotDevice.IsError)
  178. return null;
  179. if (_efem.RobotDevice.IsIdle)
  180. return true;
  181. return false;
  182. }, timeout * 1000);
  183. if (ret.Item1)
  184. {
  185. if (ret.Item2 == Result.FAIL)
  186. {
  187. Stop(string.Format("failed."));
  188. throw (new RoutineFaildException());
  189. }
  190. else if (ret.Item2 == Result.TIMEOUT) //timeout
  191. {
  192. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  193. throw (new RoutineFaildException());
  194. }
  195. else
  196. throw (new RoutineBreakException());
  197. }
  198. }
  199. public void Map(int id, LoadPort lp, int timeout)
  200. {
  201. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  202. {
  203. Notify($"Start map {lp.Name}");
  204. string reason;
  205. if (!_efem.RobotDevice.Map(ModuleHelper.Converter(_lp.Module), 0, out reason))
  206. {
  207. Stop(reason);
  208. return false;
  209. }
  210. return true;
  211. }, () =>
  212. {
  213. if (_efem.RobotDevice.IsError)
  214. return false;
  215. if (_efem.RobotDevice.IsIdle)
  216. return true;
  217. return false;
  218. }, timeout * 1000);
  219. if (ret.Item1)
  220. {
  221. if (ret.Item2 == Result.FAIL)
  222. {
  223. Stop(string.Format("failed."));
  224. throw (new RoutineFaildException());
  225. }
  226. else if (ret.Item2 == Result.TIMEOUT) //timeout
  227. {
  228. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  229. throw (new RoutineFaildException());
  230. }
  231. else
  232. throw (new RoutineBreakException());
  233. }
  234. }
  235. public void Clamp(int id, LoadPort lp, int timeout)
  236. {
  237. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  238. {
  239. Notify($"Start clamp {lp.Name}");
  240. string reason;
  241. if (!lp.Clamp(out reason))
  242. {
  243. Stop(reason);
  244. return false;
  245. }
  246. return true;
  247. }, () =>
  248. {
  249. if (_lp.Error)
  250. return false;
  251. if (_lp.IsBusy)
  252. return false;
  253. return true;
  254. }, timeout * 1000);
  255. if (ret.Item1)
  256. {
  257. if (ret.Item2 == Result.FAIL)
  258. {
  259. Stop(string.Format("failed."));
  260. throw (new RoutineFaildException());
  261. }
  262. else if (ret.Item2 == Result.TIMEOUT) //timeout
  263. {
  264. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  265. throw (new RoutineFaildException());
  266. }
  267. else
  268. throw (new RoutineBreakException());
  269. }
  270. }
  271. public void QueryMapInfo(int id, LoadPort lp, int timeout)
  272. {
  273. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  274. {
  275. Notify($"Start to get wafer info {lp.Name}");
  276. //string reason;
  277. if (!lp.GetMapInfo(out string reason))
  278. {
  279. Stop(reason);
  280. return false;
  281. }
  282. return true;
  283. }, () =>
  284. {
  285. if (_lp.Error)
  286. return false;
  287. if (_lp.IsBusy)
  288. return false;
  289. return true;
  290. }, timeout * 1000);
  291. if (ret.Item1)
  292. {
  293. if (ret.Item2 == Result.FAIL)
  294. {
  295. Stop(string.Format("failed."));
  296. throw (new RoutineFaildException());
  297. }
  298. else if (ret.Item2 == Result.TIMEOUT) //timeout
  299. {
  300. Stop(string.Format("timeout, can not complete in {0} seconds", timeout));
  301. throw (new RoutineFaildException());
  302. }
  303. else
  304. throw (new RoutineBreakException());
  305. }
  306. }
  307. public void QueryStatus(int id, LoadPort lp, int timeout)
  308. {
  309. Tuple<bool, Result> ret = ExecuteAndWait(id, () =>
  310. {
  311. Notify($"Start query status {lp.Name}");
  312. string reason;
  313. if (!lp.QueryState(out reason))
  314. {
  315. Stop(reason);
  316. return false;
  317. }
  318. return true;
  319. }, () =>
  320. {
  321. if (_lp.Error)
  322. return false;
  323. if (_lp.IsBusy)
  324. return false;
  325. return true;
  326. }, timeout * 1000);
  327. if (ret.Item1)
  328. {
  329. if (ret.Item2 == Result.FAIL)
  330. {
  331. Stop(string.Format("Query status failed."));
  332. throw (new RoutineFaildException());
  333. }
  334. else if (ret.Item2 == Result.TIMEOUT) //timeout
  335. {
  336. Stop(string.Format("Home timeout, can not complete in {0} seconds", timeout));
  337. throw (new RoutineFaildException());
  338. }
  339. else
  340. throw (new RoutineBreakException());
  341. }
  342. }
  343. public void Abort()
  344. {
  345. }
  346. }
  347. }