RorzeEfem.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Runtime.InteropServices.WindowsRuntime;
  5. using System.Xml;
  6. using Aitex.Core.Common;
  7. using Aitex.Core.RT.DataCenter;
  8. using Aitex.Core.RT.Device;
  9. using Aitex.Core.RT.Event;
  10. using Aitex.Core.RT.Log;
  11. using Aitex.Core.RT.OperationCenter;
  12. using Aitex.Core.RT.SCCore;
  13. using Aitex.Core.Util;
  14. using Aitex.Sorter.Common;
  15. using MECF.Framework.Common.Communications;
  16. using MECF.Framework.Common.Device.Bases;
  17. using MECF.Framework.Common.Equipment;
  18. using MECF.Framework.Common.SubstrateTrackings;
  19. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Common;
  20. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  21. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK;
  22. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes
  23. {
  24. public interface IRorzeEfemController : IEfemController
  25. {
  26. void SetLoadPortCallback(ModuleName module, IEfemLoadPortCallback lpCallback);
  27. void SetRobotCallback(ModuleName module, IEfemRobotCallback robotCallback);
  28. void SetAlignerCallback(ModuleName module, IEfemAlignerCallback alignerCallback);
  29. void SetSignalTowerCallback(ModuleName module, IEfemSignalTowerCallback signalTowerCallback);
  30. void SetBufferCallback(ModuleName module, IEfemBufferCallback bufferCallback);
  31. }
  32. public class RorzeEfem : BaseDevice, IDevice, IConnectionContext, IRorzeEfemController
  33. {
  34. #region Connection Config
  35. public virtual bool IsEnabled => true;
  36. public int RetryConnectIntervalMs => 500;
  37. public int MaxRetryConnectCount => 3;
  38. public bool EnableCheckConnection => true;
  39. private string _address = "127.0.0.1:13000";
  40. public string Address => _address;
  41. public bool IsAscii => true;
  42. public string NewLine => "\r";
  43. public bool EnableLog => true;
  44. #endregion
  45. private R_TRIG _trigError = new R_TRIG();
  46. private R_TRIG _trigWarningMessage = new R_TRIG();
  47. private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
  48. private LinkedList<HandlerBase> _lstMonitorHandler = new LinkedList<HandlerBase>();
  49. private object _locker = new object();
  50. private string _scRoot;
  51. protected IEfemAlignerCallback _aligner;
  52. protected IEfemRobotCallback _robot;
  53. protected IEfemSignalTowerCallback _signalTower;
  54. protected IEfemFfuCallback _ffu;
  55. protected IEfemSystemCallback _system;
  56. protected Dictionary<ModuleName, IEfemLoadPortCallback> _lpCallback = new Dictionary<ModuleName, IEfemLoadPortCallback>();
  57. public RorzeEfemConnection Connection
  58. {
  59. get
  60. {
  61. return _connection;
  62. }
  63. }
  64. private RorzeEfemConnection _connection;
  65. public event Action<string, EventLevel, string> AlarmGenerated;
  66. public bool IsInitialized { get; private set; }
  67. public bool IsCommunicationReady { get; set; }
  68. public RorzeEfem(string module, string name, string scRoot) : base(module, name, name, name)
  69. {
  70. _scRoot = scRoot;
  71. }
  72. public virtual bool Initialize()
  73. {
  74. if(SC.ContainsItem($"{Name}.Address"))
  75. _address = SC.GetStringValue($"{Name}.Address");
  76. _connection = new RorzeEfemConnection(this);
  77. _connection.OnDisconnected += OnDisconnected;
  78. _connection.OnConnected += OnConnected;
  79. _connection.OnError += OnError;
  80. _connection.Name = $"{Module}.{Name}";
  81. _connection.Initialize();
  82. _connection.AddEventHandler(RorzeEfemBasicMessage.MAPDT, new RorzeEfemHandlerMapdt(this, ModuleName.System, true));
  83. _connection.AddEventHandler(RorzeEfemBasicMessage.SIGSTAT, new RorzeEfemHandlerSigStat(this, ModuleName.System));
  84. _connection.AddEventHandler(RorzeEfemBasicMessage.TRANSREQ, new RorzeEfemHandlerTransReq(this, ModuleName.System));
  85. _connection.AddEventHandler(RorzeEfemBasicMessage.READY, new RorzeEfemHandlerReady(this, ModuleName.System));
  86. DATA.Subscribe($"{Module}.{Name}.Status", () => _connection.StringFsmStatus);
  87. return true;
  88. }
  89. void IEfemController.Initialize()
  90. {
  91. Init();
  92. }
  93. public void Init()
  94. {
  95. if (_connection == null || !_connection.IsConnected)
  96. {
  97. EV.PostWarningLog("System", $"EFEM can not do initialize, not connected");
  98. return;
  99. }
  100. IsInitialized = false;
  101. if (!_connection.Execute(new RorzeEfemHandlerInit(this, ModuleName.System), out string reason))
  102. {
  103. EV.PostWarningLog("System", $"EFEM can not do initialize, {reason}");
  104. return;
  105. }
  106. }
  107. public void ClearError()
  108. {
  109. if (_connection == null || !_connection.IsConnected)
  110. {
  111. EV.PostWarningLog("System", $"EFEM can not do clear error, not connected");
  112. return;
  113. }
  114. if (!_connection.Execute(new RorzeEfemHandlerError(this, false), out string reason))
  115. {
  116. EV.PostWarningLog("System", $"EFEM can not do clear error, {reason}");
  117. return;
  118. }
  119. }
  120. public void SetLoadPortCallback(ModuleName module, IEfemLoadPortCallback lpCallback)
  121. {
  122. lock (_locker)
  123. {
  124. _lpCallback[module] = lpCallback;
  125. }
  126. }
  127. public void SetRobotCallback(ModuleName module, IEfemRobotCallback robotCallback)
  128. {
  129. _robot = robotCallback;
  130. }
  131. public void SetAlignerCallback(ModuleName module, IEfemAlignerCallback alignerCallback)
  132. {
  133. _aligner = alignerCallback;
  134. }
  135. public void SetBufferCallback(ModuleName module, IEfemBufferCallback bufferCallback)
  136. {
  137. }
  138. public void SetSignalTowerCallback(ModuleName module, IEfemSignalTowerCallback signalTowerCallback)
  139. {
  140. _signalTower = signalTowerCallback;
  141. }
  142. public void SetSystemCallback(ModuleName module, IEfemSystemCallback systemCallback)
  143. {
  144. _system = systemCallback;
  145. }
  146. public void SetFfuCallback(ModuleName module, IEfemFfuCallback ffuCallback)
  147. {
  148. _ffu = ffuCallback;
  149. }
  150. protected virtual void OnError(string obj)
  151. {
  152. if (!string.IsNullOrEmpty(obj))
  153. EV.PostAlarmLog(Module, obj);
  154. }
  155. protected virtual void OnConnected()
  156. {
  157. EV.PostInfoLog(Module, $"{Name} connected.");
  158. }
  159. protected virtual void OnDisconnected()
  160. {
  161. EV.PostWarningLog(Module, $"{Name} disconnected.");
  162. }
  163. public virtual void Monitor()
  164. {
  165. }
  166. public void Terminate()
  167. {
  168. if (_connection != null)
  169. {
  170. _connection.Terminate();
  171. }
  172. }
  173. public bool AlarmIsTripped()
  174. {
  175. throw new NotImplementedException();
  176. }
  177. public bool IsOperable()
  178. {
  179. return false;
  180. }
  181. public bool Home(out string reason)
  182. {
  183. Init();
  184. reason = string.Empty;
  185. return true;
  186. }
  187. public bool QueryWaferPresence(out string reason)
  188. {
  189. throw new NotImplementedException();
  190. }
  191. public event Action<string> CarrierArrived;
  192. public event Action<string> CarrierRemoved;
  193. public event Action<string, string> CarrierPresenceStateError;
  194. public event Action<string, bool> CarrierPresenceStateChanged;
  195. public event Action<string> CarrierDoorClosed;
  196. public event Action<string> CarrierDoorOpened;
  197. public event Action<string> E84HandOffStart;
  198. public event Action<string> E84HandOffComplete;
  199. public bool HomeLoadPort(string lp, out string reason)
  200. {
  201. if (_connection == null || !_connection.IsConnected)
  202. {
  203. reason = "not connected";
  204. return false;
  205. }
  206. return _connection.Execute(new RorzeEfemHandlerInit(this, ModuleHelper.Converter(lp)), out reason);
  207. }
  208. public bool LoadPortClearAlarm(string lp, out string reason)
  209. {
  210. if (_connection == null || !_connection.IsConnected)
  211. {
  212. reason = "not connected";
  213. return false;
  214. }
  215. return _connection.Execute(new RorzeEfemHandlerError(this, false), out reason);
  216. }
  217. public bool UnclampCarrier(string lp, out string reason)
  218. {
  219. if (_connection == null || !_connection.IsConnected)
  220. {
  221. reason = "not connected";
  222. return false;
  223. }
  224. return _connection.Execute(new RorzeEfemHandlerUnlock(this, ModuleHelper.Converter(lp)), out reason);
  225. }
  226. public bool ClampCarrier(string lp, out string reason)
  227. {
  228. if (_connection == null || !_connection.IsConnected)
  229. {
  230. reason = "not connected";
  231. return false;
  232. }
  233. return _connection.Execute(new RorzeEfemHandlerLock(this, ModuleHelper.Converter(lp)), out reason);
  234. }
  235. public bool MoveCarrierPort(string lp, string position, out string reason)
  236. {
  237. if (_connection == null || !_connection.IsConnected)
  238. {
  239. reason = "not connected";
  240. return false;
  241. }
  242. if(position.ToUpper() == "DOCK")
  243. return _connection.Execute(new RorzeEfemHandlerDock(this, ModuleHelper.Converter(lp)), out reason);
  244. if (position.ToUpper() == "UNDOCK")
  245. return _connection.Execute(new RorzeEfemHandlerUndock(this, ModuleHelper.Converter(lp)), out reason);
  246. reason = "invalid parameter";
  247. return false;
  248. }
  249. public bool OpenCarrierDoor(string lp, out string reason)
  250. {
  251. if (_connection == null || !_connection.IsConnected)
  252. {
  253. reason = "not connected";
  254. return false;
  255. }
  256. return _connection.Execute(new RorzeEfemHandlerOpen(this, ModuleHelper.Converter(lp)), out reason);
  257. }
  258. public bool OpenDoorAndMapCarrier(string lp, out string slotMap, out string reason)
  259. {
  260. throw new NotImplementedException();
  261. }
  262. public bool CloseCarrierDoor(string lp, out string reason)
  263. {
  264. if (_connection == null || !_connection.IsConnected)
  265. {
  266. reason = "not connected";
  267. return false;
  268. }
  269. return _connection.Execute(new RorzeEfemHandlerClose(this, ModuleHelper.Converter(lp)), out reason);
  270. }
  271. public bool GetLoadPortStatus(string lp, out LoadportCassetteState cassetteState, out FoupClampState clampState,
  272. out FoupDockState dockState, out FoupDoorState doorState, out string reason)
  273. {
  274. reason = string.Empty;
  275. cassetteState = LoadportCassetteState.Unknown;
  276. clampState = FoupClampState.Unknown;
  277. dockState = FoupDockState.Unknown;
  278. doorState = FoupDoorState.Unknown;
  279. if (_connection == null || !_connection.IsConnected)
  280. {
  281. reason = "not connected";
  282. return false;
  283. }
  284. return _connection.Execute(new RorzeEfemHandlerSigStat(this, ModuleHelper.Converter(lp)), out reason);
  285. }
  286. public virtual bool MapCarrier(string lp, out string slotMap, out string reason)
  287. {
  288. slotMap = string.Empty;
  289. if (_connection == null || !_connection.IsConnected)
  290. {
  291. reason = "not connected";
  292. return false;
  293. }
  294. return _connection.Execute(new RorzeEfemHandlerWafsh(this, ModuleHelper.Converter(lp), true), out reason);
  295. }
  296. public bool QueryMapResult(string lp, out string reason, bool mapByRobot = true)
  297. {
  298. if (_connection == null || !_connection.IsConnected)
  299. {
  300. reason = "not connected";
  301. return false;
  302. }
  303. return _connection.Execute(new RorzeEfemHandlerMapdt(this, ModuleHelper.Converter(lp), mapByRobot), out reason);
  304. }
  305. public bool ReadCarrierId(string lp, out string carrierId, out string reason)
  306. {
  307. carrierId = string.Empty;
  308. if (_connection == null || !_connection.IsConnected)
  309. {
  310. reason = "not connected";
  311. return false;
  312. }
  313. return _connection.Execute(new RorzeEfemHandlerCstid(this, ModuleHelper.Converter(lp)), out reason);
  314. }
  315. public bool HomeWaferAligner(out string reason)
  316. {
  317. throw new NotImplementedException();
  318. }
  319. public bool AlignWafer(double angle, out string reason)
  320. {
  321. throw new NotImplementedException();
  322. }
  323. public bool AlignerMapWaferPresence(out string slotMap, out string reason)
  324. {
  325. throw new NotImplementedException();
  326. }
  327. public bool HomeAllAxes(out string reason)
  328. {
  329. if (_connection == null || !_connection.IsConnected)
  330. {
  331. reason = "not connected";
  332. return false;
  333. }
  334. return _connection.Execute(new RorzeEfemHandlerHome(this, ModuleName.EfemRobot), out reason);
  335. }
  336. public bool QueryRobotWaferPresence(out string slotMap, out string reason)
  337. {
  338. slotMap = string.Empty;
  339. if (_connection == null || !_connection.IsConnected || !IsInitialized)
  340. {
  341. reason = "not connected";
  342. return false;
  343. }
  344. return _connection.Execute(new RorzeEfemHandlerState(this, RorzeEfemStateType.TRACK), out reason);
  345. }
  346. public bool GetTwoWafers(ModuleName chamber, int slot, out string reason)
  347. {
  348. throw new NotImplementedException();
  349. }
  350. public bool PutTwoWafers(ModuleName chamber, int slot, out string reason)
  351. {
  352. throw new NotImplementedException();
  353. }
  354. public bool GetWafer(ModuleName chamber, int slot, Hand hand, out string reason)
  355. {
  356. if (_connection == null || !_connection.IsConnected || !IsInitialized)
  357. {
  358. reason = "not connected";
  359. return false;
  360. }
  361. return _connection.Execute(new RorzeEfemHandlerLoad(this, chamber, slot, hand, WaferManager.Instance.GetWaferSize(chamber, slot)), out reason);
  362. }
  363. public bool PutWafer(ModuleName chamber, int slot, Hand hand, out string reason)
  364. {
  365. if (_connection == null || !_connection.IsConnected || !IsInitialized)
  366. {
  367. reason = "not connected";
  368. return false;
  369. }
  370. return _connection.Execute(new RorzeEfemHandlerUnload(this, chamber, slot, hand, WaferManager.Instance.GetWaferSize(ModuleName.EfemRobot, (int)hand)), out reason);
  371. }
  372. public bool MoveToReadyGet(ModuleName chamber, int slot, Hand hand, out string reason)
  373. {
  374. if (_connection == null || !_connection.IsConnected || !IsInitialized)
  375. {
  376. reason = "not connected";
  377. return false;
  378. }
  379. return _connection.Execute(new RorzeEfemHandlerGoto(this, chamber, slot, hand, true), out reason);
  380. }
  381. public bool MoveToReadyPut(ModuleName chamber, int slot, Hand hand, out string reason)
  382. {
  383. if (_connection == null || !_connection.IsConnected || !IsInitialized)
  384. {
  385. reason = "not connected";
  386. return false;
  387. }
  388. return _connection.Execute(new RorzeEfemHandlerGoto(this, chamber, slot, hand, false), out reason);
  389. }
  390. public bool SetSignalLight(LightType type, TowerLightStatus state, out string reason)
  391. {
  392. if (_connection == null || !_connection.IsConnected || !IsCommunicationReady)
  393. {
  394. reason = "not connected";
  395. return false;
  396. }
  397. return _connection.Execute(new RorzeEfemHandlerSigout(this, ModuleName.System, type, state), out reason);
  398. }
  399. public bool SetLoadPortLight(ModuleName chamber, Indicator light, IndicatorState state)
  400. {
  401. throw new NotImplementedException();
  402. }
  403. public bool SetLoadPortLight(ModuleName chamber, IndicatorType light, IndicatorState state, out string reason)
  404. {
  405. if (_connection == null || !_connection.IsConnected || !IsCommunicationReady)
  406. {
  407. reason = "not connected";
  408. return false;
  409. }
  410. return _connection.Execute(new RorzeEfemHandlerSigout(this, chamber, light, state), out reason);
  411. }
  412. public bool SetE84Available(string lp, out string reason)
  413. {
  414. throw new NotImplementedException();
  415. }
  416. public bool SetE84Unavailable(string lp, out string reason)
  417. {
  418. throw new NotImplementedException();
  419. }
  420. public virtual void Reset()
  421. {
  422. if (_connection != null)
  423. {
  424. _connection.Reset();
  425. }
  426. }
  427. public void Connect()
  428. {
  429. if (_connection != null)
  430. {
  431. _connection.InvokeConnect();
  432. }
  433. }
  434. public void Disconnect()
  435. {
  436. if (_connection != null)
  437. {
  438. _connection.InvokeDisconnect();
  439. }
  440. }
  441. public bool CheckIsBusy(ModuleName module)
  442. {
  443. return _connection.IsBusy((int)module);
  444. }
  445. public bool Map(ModuleName module, out string reason, bool mapByRobot = true)
  446. {
  447. if (_connection == null || !_connection.IsConnected)
  448. {
  449. reason = "Not connected";
  450. return false;
  451. }
  452. if (!_connection.Execute(new RorzeEfemHandlerMapdt(this, module, mapByRobot), out reason))
  453. {
  454. return false;
  455. }
  456. return true;
  457. }
  458. public void QueryState(ModuleName module)
  459. {
  460. if (_connection != null && _connection.IsConnected)
  461. {
  462. if (!_connection.Execute(new RorzeEfemHandlerSigStat(this, module), out string reason))
  463. {
  464. EV.PostWarningLog(Module, reason);
  465. }
  466. }
  467. }
  468. public virtual void NoteStateEvent(ModuleName module, string data1, string data2)
  469. {
  470. if (ModuleHelper.IsLoadPort(module) && _lpCallback.ContainsKey(module))
  471. _lpCallback[module].NoteStatus(data1, data2);
  472. }
  473. internal void NoteFailed(ModuleName module, string error)
  474. {
  475. switch (module)
  476. {
  477. case ModuleName.EfemRobot:
  478. _robot.NoteFailed(error);
  479. break;
  480. }
  481. }
  482. internal void NoteCancel(ModuleName module, string error)
  483. {
  484. switch (module)
  485. {
  486. case ModuleName.EfemRobot:
  487. _robot?.NoteCancel(error);
  488. break;
  489. case ModuleName.System:
  490. {
  491. _robot?.NoteCancel(error);
  492. _aligner?.NoteCancel(error);
  493. _lpCallback.Values.ToList().ForEach(x => x.NoteCancel(error));
  494. }
  495. break;
  496. case ModuleName.LP1:
  497. case ModuleName.LP2:
  498. case ModuleName.LP3:
  499. _lpCallback[module].NoteCancel(error);
  500. break;
  501. case ModuleName.Aligner:
  502. _aligner?.NoteCancel(error);
  503. break;
  504. }
  505. }
  506. internal void NoteComplete(ModuleName module)
  507. {
  508. switch (module)
  509. {
  510. case ModuleName.EfemRobot:
  511. _robot.NoteComplete();
  512. break;
  513. case ModuleName.System:
  514. {
  515. IsInitialized = true;
  516. _robot?.NoteComplete();
  517. _aligner?.NoteComplete();
  518. _lpCallback.Values.ToList().ForEach(x => x.NoteComplete());
  519. }
  520. break;
  521. case ModuleName.LP1:
  522. case ModuleName.LP2:
  523. case ModuleName.LP3:
  524. _lpCallback[module].NoteComplete();
  525. break;
  526. case ModuleName.Aligner:
  527. _aligner?.NoteComplete();
  528. break;
  529. }
  530. }
  531. internal void NoteWaferMapResult(ModuleName module, string slotMap)
  532. {
  533. if (ModuleHelper.IsLoadPort(module))
  534. {
  535. _lpCallback[module].NoteSlotMap(slotMap);
  536. }
  537. }
  538. internal void NoteCarrierIDReadResult(ModuleName module, string carrierID)
  539. {
  540. if (ModuleHelper.IsLoadPort(module))
  541. {
  542. _lpCallback[module].NoteCarrierID(carrierID);
  543. }
  544. }
  545. public void NoteInitialized()
  546. {
  547. IsInitialized = true;
  548. }
  549. public void NoteCommunicationReady()
  550. {
  551. IsCommunicationReady = true;
  552. }
  553. public virtual void NoteWaferTrack(string waferInfo)
  554. {
  555. }
  556. protected virtual void OnCarrierArrived(string obj)
  557. {
  558. CarrierArrived?.Invoke(obj);
  559. }
  560. public void AlarmStateChanged(string s, string arg)
  561. {
  562. AlarmGenerated?.Invoke(s, EventLevel.Alarm, arg);
  563. }
  564. }
  565. }