HonghuAligner.cs 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. using System;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Event;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.Util;
  6. using Aitex.Sorter.Common;
  7. using Aitex.Core.RT.Device;
  8. using MECF.Framework.Common.Communications;
  9. using MECF.Framework.Common.SubstrateTrackings;
  10. using System.Collections.Generic;
  11. using Aitex.Core.RT.SCCore;
  12. using System.IO.Ports;
  13. using System.Threading;
  14. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.HonghuAligners
  15. {
  16. public class HonghuAligner : BaseDevice, IDevice
  17. {
  18. public enum AlignerType
  19. {
  20. Mechnical =0,
  21. Vaccum,
  22. }
  23. public string Address
  24. {
  25. get
  26. {
  27. return "";
  28. }
  29. }
  30. public virtual bool IsConnected
  31. {
  32. get { return true; }
  33. }
  34. public virtual bool Disconnect()
  35. {
  36. return true;
  37. }
  38. public virtual bool Connect()
  39. {
  40. return true;
  41. }
  42. public const string delimiter = "\r";
  43. public int LastErrorCode { get; set; }
  44. public int Status { get; set; }
  45. public int ErrorCode { get; set; }
  46. public int ElapseTime { get; set; }
  47. public int Notch { get; set; }
  48. public bool Initalized { get; set; }
  49. private AlignerType _tazmotype;
  50. public AlignerType TazmoType { get => _tazmotype; }
  51. public bool Communication
  52. {
  53. get
  54. {
  55. return !_commErr;
  56. }
  57. }
  58. public virtual bool Error
  59. {
  60. get;set;
  61. }
  62. public bool Busy { get { return _connection.IsBusy || _lstHandler.Count != 0; } }
  63. public DeviceState State
  64. {
  65. get
  66. {
  67. if (!Initalized)
  68. {
  69. return DeviceState.Unknown;
  70. }
  71. if (Error)
  72. {
  73. return DeviceState.Error;
  74. }
  75. if (Busy)
  76. return DeviceState.Busy;
  77. return DeviceState.Idle;
  78. }
  79. }
  80. public bool TaExecuteSuccss
  81. {
  82. get;set;
  83. }
  84. public virtual bool WaferOnAligner
  85. {
  86. get
  87. {
  88. return true;
  89. }
  90. }
  91. //private int _deviceAddress;
  92. public HonghuAlignerConnection Connection
  93. {
  94. get => _connection;
  95. }
  96. private HonghuAlignerConnection _connection;
  97. //private int _presetNumber;
  98. private R_TRIG _trigError = new R_TRIG();
  99. private R_TRIG _trigWarningMessage = new R_TRIG();
  100. private R_TRIG _trigCommunicationError = new R_TRIG();
  101. private R_TRIG _trigRetryConnect = new R_TRIG();
  102. private PeriodicJob _thread;
  103. private static Object _locker = new Object();
  104. private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
  105. private bool _enableLog = true;
  106. private bool _commErr = false;
  107. private int _defaultChuckPosition;
  108. //private bool _exceuteErr = false;
  109. //private string _addr;
  110. private DeviceTimer _timerQuery = new DeviceTimer();
  111. private string AlarmMechanicalAlignmentError = "MechanicalAlignmentError";
  112. public HonghuAligner(string module, string name)
  113. : base()
  114. {
  115. Name = name;
  116. Module = module;
  117. WaferManager.Instance.SubscribeLocation(name, 1);
  118. }
  119. public bool Initialize()
  120. {
  121. string portName = SC.GetStringValue($"{Module}.{Name}.Address");
  122. int bautRate = SC.GetValue<int>($"{Module}.{Name}.BaudRate");
  123. int dataBits = SC.GetValue<int>($"{Module}.{Name}.DataBits");
  124. Enum.TryParse(SC.GetStringValue($"{Module}.{Name}.Parity"), out Parity parity);
  125. Enum.TryParse(SC.GetStringValue($"{Module}.{Name}.StopBits"), out StopBits stopBits);
  126. //_deviceAddress = SC.GetValue<int>($"{Name}.DeviceAddress");
  127. _enableLog = SC.GetValue<bool>($"{Module}.{Name}.EnableLogMessage");
  128. _tazmotype = (AlignerType)(SC.ContainsItem($"{Name}.AlignerType") ? SC.GetValue<int>($"{Name}.AlignerType") : 0);
  129. _defaultChuckPosition = SC.ContainsItem("Aligner.DefaultChuckPosition") ?
  130. SC.GetValue<int>("Aligner.DefaultChuckPosition") : 1;
  131. _connection = new HonghuAlignerConnection(portName, bautRate, dataBits, parity, stopBits);
  132. _connection.EnableLog(_enableLog);
  133. int count = SC.ContainsItem("System.ComPortRetryCount") ? SC.GetValue<int>("System.ComPortRetryCount") : 5;
  134. int sleep = SC.ContainsItem("System.ComPortRetryDelayTime") ? SC.GetValue<int>("System.ComPortRetryDelayTime") : 2;
  135. if (sleep <= 0 || sleep > 10)
  136. sleep = 2;
  137. int retry = 0;
  138. do
  139. {
  140. _connection.Disconnect();
  141. Thread.Sleep(sleep * 1000);
  142. if (_connection.Connect())
  143. {
  144. EV.PostInfoLog(Module, $"{Module}.{Name} connected");
  145. break;
  146. }
  147. if (count > 0 && retry++ > count)
  148. {
  149. LOG.Write($"Retry connect {Module}.{Name} stop retry.");
  150. EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
  151. break;
  152. }
  153. Thread.Sleep(sleep * 1000);
  154. LOG.Write($"Retry connect {Module}.{Name} for the {retry + 1} time.");
  155. } while (true);
  156. _thread = new PeriodicJob(100, OnTimer, $"{Module}.{Name} MonitorHandler", true);
  157. DEVICE.Register(String.Format("{0}.{1}", Name, "Init"), (out string reason, int time, object[] param) =>
  158. {
  159. bool ret = Init(out reason);
  160. if (ret)
  161. {
  162. reason = string.Format("{0} {1}", Name, "Reset Error");
  163. return true;
  164. }
  165. return false;
  166. });
  167. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerInit"), (out string reason, int time, object[] param) =>
  168. {
  169. bool ret = Init(out reason);
  170. if (ret)
  171. {
  172. reason = string.Format("{0} {1}", Name, "Reset Error");
  173. return true;
  174. }
  175. return false;
  176. });
  177. DEVICE.Register(String.Format("{0}.{1}", Name, "Home"), (out string reason, int time, object[] param) =>
  178. {
  179. bool ret = Home(out reason);
  180. if (ret)
  181. {
  182. reason = string.Format("{0} {1}", Name, "Reset Error");
  183. return true;
  184. }
  185. return false;
  186. });
  187. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerHome"), (out string reason, int time, object[] param) =>
  188. {
  189. bool ret = Home(out reason);
  190. if (ret)
  191. {
  192. reason = string.Format("{0} {1}", Name, "Reset Error");
  193. return true;
  194. }
  195. return false;
  196. });
  197. DEVICE.Register(String.Format("{0}.{1}", Name, "Reset"), (out string reason, int time, object[] param) =>
  198. {
  199. bool ret = Clear(out reason);
  200. if (ret)
  201. {
  202. reason = string.Format("{0} {1}", Name, "Reset Error");
  203. return true;
  204. }
  205. return false;
  206. });
  207. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerReset"), (out string reason, int time, object[] param) =>
  208. {
  209. bool ret = Clear(out reason);
  210. if (ret)
  211. {
  212. reason = string.Format("{0} {1}", Name, "Reset Error");
  213. return true;
  214. }
  215. return false;
  216. });
  217. DEVICE.Register(String.Format("{0}.{1}", Name, "Grip"), (out string reason, int time, object[] param) =>
  218. {
  219. bool ret = Grip(out reason);
  220. if (ret)
  221. {
  222. reason = string.Format("{0} {1}", Name, "Hold Wafer");
  223. return true;
  224. }
  225. return false;
  226. });
  227. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerGrip"), (out string reason, int time, object[] param) =>
  228. {
  229. bool ret = Grip(out reason);
  230. if (ret)
  231. {
  232. reason = string.Format("{0} {1}", Name, "Hold Wafer");
  233. return true;
  234. }
  235. return false;
  236. });
  237. DEVICE.Register(String.Format("{0}.{1}", Name, "Release"), (out string reason, int time, object[] param) =>
  238. {
  239. bool ret = Release(out reason);
  240. if (ret)
  241. {
  242. reason = string.Format("{0} {1}", Name, "Release Wafer");
  243. return true;
  244. }
  245. return false;
  246. });
  247. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerRelease"), (out string reason, int time, object[] param) =>
  248. {
  249. bool ret = Release(out reason);
  250. if (ret)
  251. {
  252. reason = string.Format("{0} {1}", Name, "Release Wafer");
  253. return true;
  254. }
  255. return false;
  256. });
  257. DEVICE.Register(String.Format("{0}.{1}", Name, "LiftUp"), (out string reason, int time, object[] param) =>
  258. {
  259. bool ret = LiftUp(out reason);
  260. if (ret)
  261. {
  262. reason = string.Format("{0} {1}", Name, "Lifter Up");
  263. return true;
  264. }
  265. return false;
  266. });
  267. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerLiftUp"), (out string reason, int time, object[] param) =>
  268. {
  269. bool ret = LiftUp(out reason);
  270. if (ret)
  271. {
  272. reason = string.Format("{0} {1}", Name, "Lifter Up");
  273. return true;
  274. }
  275. return false;
  276. });
  277. DEVICE.Register(String.Format("{0}.{1}", Name, "LiftDown"), (out string reason, int time, object[] param) =>
  278. {
  279. bool ret = LiftDown(out reason);
  280. if (ret)
  281. {
  282. reason = string.Format("{0} {1}", Name, "Lifter Down");
  283. return true;
  284. }
  285. return false;
  286. });
  287. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerLiftDown"), (out string reason, int time, object[] param) =>
  288. {
  289. bool ret = LiftDown(out reason);
  290. if (ret)
  291. {
  292. reason = string.Format("{0} {1}", Name, "Lifter Down");
  293. return true;
  294. }
  295. return false;
  296. });
  297. DEVICE.Register(String.Format("{0}.{1}", Name, "Stop"), (out string reason, int time, object[] param) =>
  298. {
  299. bool ret = Stop(out reason);
  300. if (ret)
  301. {
  302. reason = string.Format("{0} {1}", Name, "Stop Align");
  303. return true;
  304. }
  305. return false;
  306. });
  307. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerStop"), (out string reason, int time, object[] param) =>
  308. {
  309. bool ret = Stop(out reason);
  310. if (ret)
  311. {
  312. reason = string.Format("{0} {1}", Name, "Stop Align");
  313. return true;
  314. }
  315. return false;
  316. });
  317. DEVICE.Register(String.Format("{0}.{1}", Name, "Align"), (out string reason, int time, object[] param) =>
  318. {
  319. double angle = double.Parse((string)param[0]);
  320. bool ret = Align(angle, out reason);
  321. if (ret)
  322. {
  323. reason = string.Format("{0} {1}", Name, "PreAlign");
  324. return true;
  325. }
  326. return false;
  327. });
  328. DEVICE.Register(String.Format("{0}.{1}", Name, "AlignerAlign"), (out string reason, int time, object[] param) =>
  329. {
  330. double angle = double.Parse((string)param[0]);
  331. bool ret = Align(angle, out reason);
  332. if (ret)
  333. {
  334. reason = string.Format("{0} {1}", Name, "PreAlign");
  335. return true;
  336. }
  337. return false;
  338. });
  339. DATA.Subscribe($"{Name}.State", () => State);
  340. DATA.Subscribe($"{Name}.AlignerState", () => State.ToString());
  341. DATA.Subscribe($"{Name}.Busy", () => Busy);
  342. DATA.Subscribe($"{Name}.ErrorCode", () => ErrorCode);
  343. DATA.Subscribe($"{Name}.Error", () => Error);
  344. DATA.Subscribe($"{Name}.ElapseTime", () => ElapseTime);
  345. DATA.Subscribe($"{Name}.Notch", () => Notch);
  346. DATA.Subscribe($"{Name}.WaferOnAligner", () => WaferOnAligner);
  347. // string str = string.Empty;
  348. EV.Subscribe(new EventItem(0, "Event", AlarmMechanicalAlignmentError, "Aligner error", EventLevel.Alarm, Aitex.Core.RT.Event.EventType.HostNotification));
  349. // _timerQuery.Start(_queryPeriod);
  350. return true;
  351. }
  352. private bool OnTimer()
  353. {
  354. try
  355. {
  356. _connection.MonitorTimeout();
  357. if (!_connection.IsConnected || _connection.IsCommunicationError)
  358. {
  359. lock (_locker)
  360. {
  361. _lstHandler.Clear();
  362. }
  363. _trigRetryConnect.CLK = !_connection.IsConnected;
  364. if (_trigRetryConnect.Q)
  365. {
  366. _connection.SetPortAddress(SC.GetStringValue($"{Name}.Address"));
  367. if (!_connection.Connect())
  368. {
  369. EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
  370. }
  371. }
  372. return true;
  373. }
  374. HandlerBase handler = null;
  375. if (!_connection.IsBusy)
  376. {
  377. lock (_locker)
  378. {
  379. if (_lstHandler.Count == 0)
  380. {
  381. //_lstHandler.AddLast(new SingleTransactionHandler(this, TazmoCommand.RequeststatusStatus, null));
  382. //_lstHandler.AddLast(new SingleTransactionHandler(this, TazmoCommand.Requeststatus2Status, null));
  383. }
  384. if (_lstHandler.Count > 0)
  385. {
  386. handler = _lstHandler.First.Value;
  387. if (handler != null) _connection.Execute(handler);
  388. _lstHandler.RemoveFirst();
  389. }
  390. }
  391. }
  392. }
  393. catch (Exception ex)
  394. {
  395. LOG.Write(ex);
  396. }
  397. return true;
  398. }
  399. public void Terminate()
  400. {
  401. _connection.Disconnect();
  402. }
  403. public void Monitor()
  404. {
  405. try
  406. {
  407. _connection.EnableLog(_enableLog);
  408. _trigCommunicationError.CLK = _connection.IsCommunicationError;
  409. if (_trigCommunicationError.Q)
  410. {
  411. EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
  412. }
  413. }
  414. catch (Exception ex)
  415. {
  416. LOG.Write(ex);
  417. }
  418. }
  419. public void Reset()
  420. {
  421. _trigError.RST = true;
  422. _trigWarningMessage.RST = true;
  423. _connection.SetCommunicationError(false, "");
  424. _trigCommunicationError.RST = true;
  425. _enableLog = SC.GetValue<bool>($"{Module}.{Name}.EnableLogMessage");
  426. _trigRetryConnect.RST = true;
  427. }
  428. internal void NoteError(string reason)
  429. {
  430. _trigWarningMessage.CLK = true;
  431. if (_trigWarningMessage.Q)
  432. {
  433. EV.PostWarningLog(Module, $"{Module}.{Name} error, {reason}");
  434. }
  435. }
  436. #region Command
  437. public virtual bool Reset(out string reason)
  438. {
  439. lock (_locker)
  440. {
  441. _lstHandler.Clear();
  442. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.Reset));
  443. }
  444. reason = "";
  445. return true;
  446. }
  447. public virtual bool Init(out string reason)
  448. {
  449. lock (_locker)
  450. {
  451. _lstHandler.Clear();
  452. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.Reset));
  453. }
  454. reason = "";
  455. return true;
  456. }
  457. public virtual bool Home(out string reason)
  458. {
  459. lock (_locker)
  460. {
  461. _lstHandler.Clear();
  462. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.Reset));
  463. }
  464. reason = "";
  465. return true;
  466. }
  467. public virtual bool Clear(out string reason)
  468. {
  469. lock (_locker)
  470. {
  471. _lstHandler.Clear();
  472. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.Reset));
  473. }
  474. reason = "";
  475. return true;
  476. }
  477. public virtual bool Grip(out string reason)
  478. {
  479. lock (_locker)
  480. {
  481. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.RequestVacuumOn));
  482. }
  483. reason = "";
  484. return true;
  485. }
  486. public virtual bool Release(out string reason)
  487. {
  488. lock (_locker)
  489. {
  490. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.RequestVacuumOff));
  491. }
  492. reason = "";
  493. return true;
  494. }
  495. public virtual bool LiftUp(out string reason)
  496. {
  497. lock (_locker)
  498. {
  499. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.RequestPlace));
  500. }
  501. reason = "";
  502. return true;
  503. }
  504. public virtual bool LiftDown(out string reason)
  505. {
  506. lock (_locker)
  507. {
  508. }
  509. reason = "";
  510. return true;
  511. }
  512. public virtual bool MoveToReady(out string reason)
  513. {
  514. reason = "";
  515. return true;
  516. }
  517. public virtual bool Stop(out string reason)
  518. {
  519. reason = string.Empty;
  520. reason = "";
  521. return true;
  522. }
  523. public virtual bool Align(double angle, out string reason)
  524. {
  525. lock (_locker)
  526. {
  527. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.SetNotReadLM));
  528. _lstHandler.AddLast(new RequestHandler(this, $"B{angle.ToString()}"));
  529. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.SetVacuumOnAfterAln));
  530. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.RequestFinishPlace));
  531. }
  532. reason = "";
  533. return true;
  534. }
  535. public virtual bool RequestPlace(out string reason)
  536. {
  537. lock (_locker)
  538. {
  539. _lstHandler.AddLast(new RequestHandler(this, HonghuAlignerCommand.RequestPlace));
  540. }
  541. reason = "";
  542. return true;
  543. }
  544. public virtual bool QueryStatus(out string reason)
  545. {
  546. lock (_locker)
  547. {
  548. }
  549. reason = "";
  550. return true;
  551. }
  552. #endregion
  553. }
  554. }