FuQiAligner.cs 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156
  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. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Aligners.AlignersBase;
  15. using Aitex.Core.Common;
  16. using Aitex.Core.RT.Device.Unit;
  17. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robots;
  18. using Aitex.Core.RT.OperationCenter;
  19. using System.Diagnostics;
  20. namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.HonghuAligners
  21. {
  22. public class FuqiAligner : AlignerBaseDevice, IConnection
  23. {
  24. public enum AlignerType
  25. {
  26. Mechnical = 0,
  27. Vaccum,
  28. }
  29. public string Address
  30. {
  31. get
  32. {
  33. return "";
  34. }
  35. }
  36. public virtual bool IsConnected
  37. {
  38. get { return true; }
  39. }
  40. public virtual bool Disconnect()
  41. {
  42. return true;
  43. }
  44. public virtual bool Connect()
  45. {
  46. return true;
  47. }
  48. public const string delimiter = "\r";
  49. public int LastErrorCode { get; set; }
  50. public int Status { get; set; }
  51. public int ElapseTime { get; set; }
  52. public int Notch { get; set; }
  53. public bool Initalized { get; set; }
  54. private AlignerType _tazmotype = AlignerType.Vaccum;
  55. public AlignerType TazmoType { get => _tazmotype; }
  56. public bool IsAlignSuccess { get; set; }
  57. protected Stopwatch _timerActionMonitor = new Stopwatch();
  58. protected int _retryTime;
  59. public List<string> RecipeList;
  60. protected int TotalRetryTimes
  61. {
  62. get
  63. {
  64. if(SC.ContainsItem("{ _scRoot}.{ Name}.RetryTime"))
  65. {
  66. return SC.GetValue<int>("{ _scRoot}.{ Name}.RetryTime");
  67. }
  68. return 3;
  69. }
  70. }
  71. public bool Communication
  72. {
  73. get
  74. {
  75. return !_commErr;
  76. }
  77. }
  78. public virtual bool Error
  79. {
  80. get; set;
  81. }
  82. public bool Busy { get { return _connection.IsBusy || _lstHandler.Count != 0; } }
  83. public bool TaExecuteSuccss
  84. {
  85. get; set;
  86. }
  87. public void OnWaferPresent(bool iswaferon)
  88. {
  89. if(iswaferon)
  90. {
  91. if (WaferManager.Instance.CheckNoWafer(RobotModuleName, 0))
  92. WaferManager.Instance.CreateWafer(RobotModuleName, 0, WaferStatus.Normal);
  93. }
  94. else
  95. {
  96. if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 0))
  97. {
  98. var wafer = WaferManager.Instance.GetWafer(RobotModuleName, 0);
  99. WaferManager.Instance.UpdateWaferE90State(RobotModuleName, 0, EnumE90Status.Aborted);
  100. }
  101. }
  102. }
  103. //private int _deviceAddress;
  104. public override bool IsNeedRelease
  105. {
  106. get
  107. {
  108. return true;
  109. }
  110. }
  111. public FuqiAlignerConnection Connection
  112. {
  113. get => _connection;
  114. }
  115. protected FuqiAlignerConnection _connection;
  116. //private int _presetNumber;
  117. private R_TRIG _trigError = new R_TRIG();
  118. private R_TRIG _trigWarningMessage = new R_TRIG();
  119. private R_TRIG _trigCommunicationError = new R_TRIG();
  120. private R_TRIG _trigRetryConnect = new R_TRIG();
  121. protected PeriodicJob _thread;
  122. protected static Object _locker = new Object();
  123. protected LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
  124. private bool _enableLog = true;
  125. private bool _commErr = false;
  126. private int _defaultChuckPosition;
  127. //private bool _exceuteErr = false;
  128. //private string _addr;
  129. protected DeviceTimer _timerQuery = new DeviceTimer();
  130. protected string _scRoot;
  131. private string AlarmMechanicalAlignmentError = "MechanicalAlignmentError";
  132. private IoSensor _diOcrOn6Inch;
  133. private IoSensor _diOcrOn8Inch;
  134. private IoSensor _diOcrOn12Inch;
  135. private IoSensor _diOcrOn4Inch;
  136. private IoSensor _diWaferPresent;
  137. private IoTrigger _doOcrTo4Inch;
  138. private IoTrigger _doOcrTo6Inch;
  139. private IoTrigger _doOcrTo8Inch;
  140. private IoTrigger _doOcrTo12Inch;
  141. protected bool _isEnableTwiceAdjustment
  142. {
  143. get
  144. {
  145. if (SC.ContainsItem($"{_scRoot}.{Name}.EnableTwiceAdjustment"))
  146. return SC.GetValue<bool>($"{_scRoot}.{Name}.EnableTwiceAdjustment");
  147. return true;
  148. }
  149. }
  150. public FuqiAligner(string module, string name,string scRoot,int alignertype=0)
  151. : base(module,name)
  152. {
  153. Name = name;
  154. Module = module;
  155. _scRoot = scRoot;
  156. InitializeFuqi();
  157. //WaferManager.Instance.SubscribeLocation(name, 1);
  158. }
  159. public FuqiAligner(string module, string name, string scRoot, IoSensor[] dis,IoTrigger[] dos)
  160. : base(module, name)
  161. {
  162. Name = name;
  163. Module = module;
  164. _scRoot = scRoot;
  165. _diOcrOn6Inch = dis[0];
  166. _diOcrOn8Inch = dis[1];
  167. _diWaferPresent = dis[2];
  168. _doOcrTo6Inch = dos[0];
  169. _doOcrTo8Inch = dos[1];
  170. InitializeFuqi();
  171. //WaferManager.Instance.SubscribeLocation(name, 1);
  172. }
  173. public FuqiAligner(string module, string name, string scRoot, IoSensor[] dis, IoTrigger[] dos,WaferSize[] wsizes=null)
  174. : base(module, name)
  175. {
  176. Name = name;
  177. Module = module;
  178. _scRoot = scRoot;
  179. if(wsizes == null || wsizes.Length ==1)
  180. {
  181. _diWaferPresent = dis[0];
  182. InitializeFuqi();
  183. return;
  184. }
  185. switch(wsizes[0])
  186. {
  187. case WaferSize.WS4:
  188. _diOcrOn4Inch = dis[0];
  189. _doOcrTo4Inch = dos[0];
  190. break;
  191. case WaferSize.WS6:
  192. _diOcrOn6Inch = dis[0];
  193. _doOcrTo6Inch = dos[0];
  194. break;
  195. case WaferSize.WS8:
  196. _diOcrOn8Inch = dis[0];
  197. _doOcrTo8Inch = dos[0];
  198. break;
  199. case WaferSize.WS12:
  200. _diOcrOn12Inch = dis[0];
  201. _doOcrTo12Inch = dos[0];
  202. break;
  203. default:
  204. break;
  205. }
  206. switch(wsizes[1])
  207. {
  208. case WaferSize.WS4:
  209. _diOcrOn4Inch = dis[1];
  210. _doOcrTo4Inch = dos[1];
  211. break;
  212. case WaferSize.WS6:
  213. _diOcrOn6Inch = dis[1];
  214. _doOcrTo6Inch = dos[1];
  215. break;
  216. case WaferSize.WS8:
  217. _diOcrOn8Inch = dis[1];
  218. _doOcrTo8Inch = dos[1];
  219. break;
  220. case WaferSize.WS12:
  221. _diOcrOn12Inch = dis[1];
  222. _doOcrTo12Inch = dos[1];
  223. break;
  224. default:
  225. break;
  226. }
  227. if(dis.Length >2)
  228. _diWaferPresent = dis[2];
  229. InitializeFuqi();
  230. //WaferManager.Instance.SubscribeLocation(name, 1);
  231. }
  232. public bool InitializeFuqi()
  233. {
  234. string portName = SC.GetStringValue($"{_scRoot}.{Name}.PortName");
  235. int bautRate = SC.GetValue<int>($"{_scRoot}.{Name}.BaudRate");
  236. int dataBits = SC.GetValue<int>($"{_scRoot}.{Name}.DataBits");
  237. Enum.TryParse(SC.GetStringValue($"{_scRoot}.{Name}.Parity"), out Parity parity);
  238. Enum.TryParse(SC.GetStringValue($"{_scRoot}.{Name}.StopBits"), out StopBits stopBits);
  239. _enableLog = SC.GetValue<bool>($"{_scRoot}.{Name}.EnableLogMessage");
  240. _connection = new FuqiAlignerConnection(portName, bautRate, dataBits, parity, stopBits);
  241. _connection.EnableLog(_enableLog);
  242. int count = SC.ContainsItem("System.ComPortRetryCount") ? SC.GetValue<int>("System.ComPortRetryCount") : 5;
  243. int sleep = SC.ContainsItem("System.ComPortRetryDelayTime") ? SC.GetValue<int>("System.ComPortRetryDelayTime") : 2;
  244. if (sleep <= 0 || sleep > 10)
  245. sleep = 2;
  246. int retry = 0;
  247. do
  248. {
  249. _connection.Disconnect();
  250. Thread.Sleep(sleep * 1000);
  251. if (_connection.Connect())
  252. {
  253. EV.PostInfoLog(Module, $"{Module}.{Name} connected");
  254. break;
  255. }
  256. if (count > 0 && retry++ > count)
  257. {
  258. LOG.Write($"Retry connect {Module}.{Name} stop retry.");
  259. EV.PostAlarmLog(Module, $"Can't connect to {Module}.{Name}.");
  260. break;
  261. }
  262. Thread.Sleep(sleep * 1000);
  263. LOG.Write($"Retry connect {Module}.{Name} for the {retry + 1} time.");
  264. } while (true);
  265. _thread = new PeriodicJob(100, OnTimer, $"{Module}.{Name} MonitorHandler", true);
  266. // string str = string.Empty;
  267. SubscribeSpecialData();
  268. // _timerQuery.Start(_queryPeriod);
  269. return true;
  270. }
  271. private void SubscribeSpecialData()
  272. {
  273. DATA.Subscribe($"{Name}.RecipeList", () => RecipeList);
  274. EV.Subscribe(new EventItem(0, "Event", AlarmMechanicalAlignmentError, "Aligner error", EventLevel.Alarm, Aitex.Core.RT.Event.EventType.HostNotification));
  275. OP.Subscribe(String.Format("{0}.{1}", Name, "SetAlignmentLine"), (out string reason, int time, object[] param) =>
  276. {
  277. bool ret = ExecuteSetLine(out reason);
  278. if (ret)
  279. {
  280. reason = string.Format("{0} {1}", Name, "LiftDown");
  281. return true;
  282. }
  283. //reason = "";
  284. return false;
  285. });
  286. OP.Subscribe(String.Format("{0}.{1}", Name, "SetAlignmentNotch"), (out string reason, int time, object[] param) =>
  287. {
  288. bool ret = ExecuteSetNotch(out reason);
  289. if (ret)
  290. {
  291. reason = string.Format("{0} {1}", Name, "LiftDown");
  292. return true;
  293. }
  294. //reason = "";
  295. return false;
  296. });
  297. }
  298. public bool ExecuteSetNotch(out string reason)
  299. {
  300. reason = "";
  301. if(!IsReady())
  302. {
  303. reason = "NotReady";
  304. return false;
  305. }
  306. lock (_locker)
  307. {
  308. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetNotchProduct));
  309. }
  310. if (SC.ContainsItem($"Aligner.{RobotModuleName}.WS6ProductType"))
  311. SC.SetItemValue($"Aligner.{RobotModuleName}.WS6ProductType", "Notch");
  312. CurrentWaferAlignmentType = WaferAlignerTypeEnum.Notch;
  313. return true;
  314. }
  315. public bool ExecuteSetLine(out string reason)
  316. {
  317. reason = "";
  318. if (!IsReady())
  319. {
  320. reason = "NotReady";
  321. return false;
  322. }
  323. lock (_locker)
  324. {
  325. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetLineProduct));
  326. }
  327. if (SC.ContainsItem($"Aligner.{RobotModuleName}.WS6ProductType"))
  328. SC.SetItemValue($"Aligner.{RobotModuleName}.WS6ProductType", "Line");
  329. CurrentWaferAlignmentType = WaferAlignerTypeEnum.Line;
  330. return true;
  331. }
  332. public bool ExecuteSetRecipe(string recipename,out string reason)
  333. {
  334. reason = "";
  335. lock (_locker)
  336. {
  337. _lstHandler.AddLast(new FuqiRequestHandler(this, "SET"+recipename));
  338. }
  339. return true;
  340. }
  341. internal void OnSetComplete(bool value)
  342. {
  343. EV.PostInfoLog("Aligner", $"{RobotModuleName} set recipe {(value ? "Success":"Failed")}");
  344. }
  345. private bool OnTimer()
  346. {
  347. try
  348. {
  349. _connection.EnableLog(_enableLog);
  350. _connection.MonitorTimeout();
  351. _trigCommunicationError.CLK = _connection.IsCommunicationError ||
  352. (_connection.ActiveHandler != null && _connection.ActiveHandler.IsCompleteTimeout);
  353. if (_trigCommunicationError.Q)
  354. {
  355. OnError("CommunicationError");
  356. EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}");
  357. }
  358. if (!_connection.IsConnected || _connection.IsCommunicationError)
  359. {
  360. // lock (_locker)
  361. // {
  362. // _lstHandler.Clear();
  363. // }
  364. // _trigRetryConnect.CLK = !_connection.IsConnected;
  365. // if (_trigRetryConnect.Q)
  366. // {
  367. // _connection.SetPortAddress(SC.GetStringValue($"{_scRoot}.{Name}.PortName"));
  368. // if (!_connection.Connect())
  369. // {
  370. // EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}");
  371. // }
  372. // }
  373. return true;
  374. }
  375. HandlerBase handler = null;
  376. if (!_connection.IsBusy)
  377. {
  378. lock (_locker)
  379. {
  380. if (_lstHandler.Count == 0)
  381. {
  382. //_lstHandler.AddLast(new SingleTransactionHandler(this, TazmoCommand.RequeststatusStatus, null));
  383. //_lstHandler.AddLast(new SingleTransactionHandler(this, TazmoCommand.Requeststatus2Status, null));
  384. }
  385. if (_lstHandler.Count > 0)
  386. {
  387. handler = _lstHandler.First.Value;
  388. _lstHandler.RemoveFirst();
  389. if (handler != null) _connection.Execute(handler);
  390. }
  391. }
  392. }
  393. }
  394. catch (Exception ex)
  395. {
  396. LOG.Write(ex);
  397. }
  398. return true;
  399. }
  400. internal void OnRecipeReceived(string rawMsg)
  401. {
  402. string recipeList = rawMsg.Replace("PCtoPA:C200","").Replace("\r", "");
  403. RecipeList = new List<string>();
  404. foreach(string recipe in recipeList.Split(';'))
  405. {
  406. if (!string.IsNullOrEmpty(recipe))
  407. RecipeList.Add(recipe);
  408. }
  409. }
  410. #region Command
  411. public virtual bool MoveToReady(out string reason)
  412. {
  413. reason = "";
  414. return true;
  415. }
  416. public bool RequestPlace(out string reason)
  417. {
  418. lock (_locker)
  419. {
  420. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestPlace));
  421. }
  422. reason = "";
  423. return true;
  424. }
  425. public override bool IsReady()
  426. {
  427. return AlignerState == AlignerStateEnum.Idle && !IsBusy;
  428. }
  429. public override bool IsWaferPresent(int slotindex)
  430. {
  431. if(_diWaferPresent == null)
  432. return WaferManager.Instance.CheckHasWafer(RobotModuleName, 0);
  433. if (WaferManager.Instance.CheckNoWafer(RobotModuleName, 0))
  434. return !_diWaferPresent.Value;
  435. return true;
  436. }
  437. protected override bool fStartLiftup(object[] param)
  438. {
  439. lock (_locker)
  440. {
  441. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestPlace));
  442. }
  443. _timerActionMonitor.Restart();
  444. return true;
  445. }
  446. protected override bool fMonitorLiftup(object[] param)
  447. {
  448. IsBusy = false;
  449. if(_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  450. {
  451. _timerActionMonitor.Stop();
  452. OnError("LiftUpTimeout");
  453. return false;
  454. }
  455. if( _lstHandler.Count == 0 && !_connection.IsBusy)
  456. {
  457. _timerActionMonitor.Stop();
  458. return true;
  459. }
  460. return false;
  461. }
  462. protected override bool fStartPrepareAccept(object[] param)
  463. {
  464. lock (_locker)
  465. {
  466. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestPlace));
  467. }
  468. _timerActionMonitor.Restart();
  469. return true;
  470. }
  471. protected override bool fMonitorPrepareAccept(object[] param)
  472. {
  473. IsBusy = false;
  474. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  475. {
  476. _timerActionMonitor.Stop();
  477. OnError("PrepareAcceptTimeout");
  478. return false;
  479. }
  480. if (_lstHandler.Count == 0 && !_connection.IsBusy)
  481. {
  482. _timerActionMonitor.Stop();
  483. return true;
  484. }
  485. return false;
  486. }
  487. protected override bool fStartLiftdown(object[] param)
  488. {
  489. return true;
  490. }
  491. protected override bool fMonitorLiftdown(object[] param)
  492. {
  493. IsBusy = false;
  494. return _lstHandler.Count == 0 && !_connection.IsBusy;
  495. }
  496. protected override bool fStartAlign(object[] param)
  497. {
  498. double aligneangle = (double)param[0];
  499. int nAngle = Convert.ToInt32(aligneangle);
  500. lock (_locker)
  501. {
  502. _lstHandler.AddLast(new FuqiRequestHandler(this, $"B{nAngle}"));
  503. //_lstHandler.AddLast(new FuqiRequestHandler(this, $"B{aligneangle.ToString("f1")}"));
  504. //_lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetVacuumOffAfterAlign));
  505. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestFinishPlace));
  506. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestVacuumOff));
  507. }
  508. _timerActionMonitor.Restart();
  509. _retryTime = 0;
  510. return true;
  511. }
  512. protected override bool fMonitorAligning(object[] param)
  513. {
  514. IsBusy = false;
  515. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  516. {
  517. _timerActionMonitor.Stop();
  518. OnError("AlignmentTimeout");
  519. }
  520. if(_lstHandler.Count == 0 && !_connection.IsBusy)
  521. {
  522. if(!IsAlignSuccess)
  523. {
  524. if (_retryTime >= TotalRetryTimes)
  525. {
  526. OnError("AlignmentFailed");
  527. }
  528. else
  529. {
  530. lock (_locker)
  531. {
  532. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestFinishPlace));
  533. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestVacuumOff));
  534. _retryTime++;
  535. }
  536. }
  537. return false;
  538. }
  539. _timerActionMonitor.Stop();
  540. return true;
  541. }
  542. return false;
  543. }
  544. protected override bool fStop(object[] param)
  545. {
  546. return true;
  547. }
  548. protected override bool FsmAbort(object[] param)
  549. {
  550. return true;
  551. }
  552. protected override bool fClear(object[] param)
  553. {
  554. return true;
  555. }
  556. protected override bool fStartReadData(object[] param)
  557. {
  558. return true;
  559. }
  560. protected override bool fStartUnGrip(object[] param)
  561. {
  562. lock (_locker)
  563. {
  564. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestVacuumOff));
  565. }
  566. _timerActionMonitor.Restart();
  567. return true;
  568. }
  569. protected override bool fMonitorGrip(object[] param)
  570. {
  571. IsBusy = false;
  572. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  573. {
  574. _timerActionMonitor.Stop();
  575. OnError("GripTimeout");
  576. return false;
  577. }
  578. if (_lstHandler.Count == 0 && !_connection.IsBusy)
  579. {
  580. _timerActionMonitor.Stop();
  581. return true;
  582. }
  583. return false;
  584. }
  585. protected override bool fStartGrip(object[] param)
  586. {
  587. lock (_locker)
  588. {
  589. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestVacuumOn));
  590. }
  591. _timerActionMonitor.Restart();
  592. return true;
  593. }
  594. protected override bool fMonitorUnGrip(object[] param)
  595. {
  596. IsBusy = false;
  597. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  598. {
  599. _timerActionMonitor.Stop();
  600. OnError("UnGripTimeout");
  601. return false;
  602. }
  603. if (_lstHandler.Count == 0 && !_connection.IsBusy)
  604. {
  605. _timerActionMonitor.Stop();
  606. return true;
  607. }
  608. return false;
  609. }
  610. protected override bool fResetToReady(object[] param)
  611. {
  612. return true;
  613. }
  614. protected override bool fReset(object[] param)
  615. {
  616. _trigError.RST = true;
  617. _trigWarningMessage.RST = true;
  618. lock (_locker)
  619. {
  620. _lstHandler.Clear();
  621. }
  622. _connection.ForceClear();
  623. _trigCommunicationError.RST = true;
  624. if(!_connection.IsConnected)
  625. {
  626. string portName = SC.GetStringValue($"{_scRoot}.{Name}.PortName");
  627. int bautRate = SC.GetValue<int>($"{_scRoot}.{Name}.BaudRate");
  628. int dataBits = SC.GetValue<int>($"{_scRoot}.{Name}.DataBits");
  629. Enum.TryParse(SC.GetStringValue($"{_scRoot}.{Name}.Parity"), out Parity parity);
  630. Enum.TryParse(SC.GetStringValue($"{_scRoot}.{Name}.StopBits"), out StopBits stopBits);
  631. _enableLog = SC.GetValue<bool>($"{_scRoot}.{Name}.EnableLogMessage");
  632. _connection = new FuqiAlignerConnection(portName, bautRate, dataBits, parity, stopBits);
  633. _connection.EnableLog(_enableLog);
  634. _connection.Connect();
  635. }
  636. _trigRetryConnect.RST = true;
  637. lock (_locker)
  638. {
  639. _lstHandler.Clear();
  640. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetUseNewCommand));
  641. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.Reset));
  642. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetVacuumOffAfterAlign));
  643. if(SC.ContainsItem($"{_scRoot}.{Name}.CenterAndNotch") && SC.GetValue<bool>($"{_scRoot}.{Name}.CenterAndNotch"))
  644. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetCenterAndNotch));
  645. else
  646. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetOnlyNotch));
  647. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetWIDReaderOff));
  648. }
  649. _timerActionMonitor.Restart();
  650. return true;
  651. }
  652. protected override bool fMonitorReset(object[] param)
  653. {
  654. IsBusy = false;
  655. if (WaferManager.Instance.CheckNoWafer(RobotModuleName, 0))
  656. {
  657. Size = WaferSize.WS0;
  658. }
  659. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  660. {
  661. _timerActionMonitor.Stop();
  662. OnError("ResetTimeout");
  663. return false;
  664. }
  665. if (_lstHandler.Count == 0 && !_connection.IsBusy)
  666. {
  667. _timerActionMonitor.Stop();
  668. return true;
  669. }
  670. return false;
  671. }
  672. protected override bool fStartInit(object[] param)
  673. {
  674. lock (_locker)
  675. {
  676. _lstHandler.Clear();
  677. }
  678. _connection.ForceClear();
  679. lock (_locker)
  680. {
  681. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetUseNewCommand));
  682. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.Reset));
  683. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetWIDReaderOff));
  684. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetVacuumOnAfterAlign));
  685. if (SC.ContainsItem($"{_scRoot}.{Name}.CenterAndNotch") && SC.GetValue<bool>($"{_scRoot}.{Name}.CenterAndNotch"))
  686. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetCenterAndNotch));
  687. else
  688. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetOnlyNotch));
  689. if(_isEnableTwiceAdjustment)
  690. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetAdjustTwice));
  691. else
  692. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetAdjustFirstTime));
  693. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.RequestPlace));
  694. }
  695. _timerActionMonitor.Restart();
  696. return true;
  697. }
  698. protected override bool fMonitorInit(object[] param)
  699. {
  700. IsBusy = false;
  701. if(WaferManager.Instance.CheckNoWafer(RobotModuleName,0))
  702. {
  703. Size = WaferSize.WS0;
  704. }
  705. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  706. {
  707. _timerActionMonitor.Stop();
  708. OnError("InitTimeout");
  709. return false;
  710. }
  711. if (_lstHandler.Count == 0 && !_connection.IsBusy)
  712. {
  713. _timerActionMonitor.Stop();
  714. return true;
  715. }
  716. return false;
  717. }
  718. protected override bool fStartHome(object[] param)
  719. {
  720. lock (_locker)
  721. {
  722. _lstHandler.Clear();
  723. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.Reset));
  724. }
  725. _timerActionMonitor.Restart();
  726. return true;
  727. }
  728. protected override bool fMonitorHome(object[] param)
  729. {
  730. IsBusy = false;
  731. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  732. {
  733. _timerActionMonitor.Stop();
  734. OnError("HomeTimeout");
  735. return false;
  736. }
  737. if (_lstHandler.Count == 0 && !_connection.IsBusy)
  738. {
  739. _timerActionMonitor.Stop();
  740. return true;
  741. }
  742. return false;
  743. }
  744. private DateTime _dtActionStart;
  745. protected override bool fStartSetParameters(object[] param)
  746. {
  747. _dtActionStart = DateTime.Now;
  748. _currentSetParameter = param[0].ToString();
  749. switch (_currentSetParameter)
  750. {
  751. case "WaferSize":
  752. //if (GetWaferState() != RobotArmWaferStateEnum.Absent)
  753. //{
  754. // EV.PostAlarmLog("System", "Can't set wafersize when wafer is not absent");
  755. // return false;
  756. //}
  757. _currentSetWaferSize = (WaferSize)param[1];
  758. if (WaferManager.Instance.CheckHasWafer(RobotModuleName, 0))
  759. {
  760. WaferManager.Instance.UpdateWaferSize(RobotModuleName, 0, _currentSetWaferSize);
  761. }
  762. switch (_currentSetWaferSize)
  763. {
  764. case WaferSize.WS12:
  765. if (_doOcrTo8Inch != null && _doOcrTo8Inch.DoTrigger != null)
  766. _doOcrTo8Inch.SetTrigger(false, out _);
  767. if (_doOcrTo6Inch != null && _doOcrTo6Inch.DoTrigger != null)
  768. _doOcrTo6Inch.SetTrigger(false, out _);
  769. if (_doOcrTo12Inch != null && _doOcrTo12Inch.DoTrigger != null)
  770. _doOcrTo12Inch.SetTrigger(true, out _);
  771. if (_doOcrTo4Inch != null && _doOcrTo4Inch.DoTrigger != null)
  772. _doOcrTo4Inch.SetTrigger(false, out _);
  773. lock (_locker)
  774. {
  775. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetNotchProduct));
  776. CurrentWaferAlignmentType = WaferAlignerTypeEnum.Notch;
  777. }
  778. break;
  779. case WaferSize.WS8:
  780. if (_doOcrTo8Inch != null && _doOcrTo8Inch.DoTrigger != null)
  781. _doOcrTo8Inch.SetTrigger(true, out _);
  782. if (_doOcrTo6Inch != null && _doOcrTo6Inch.DoTrigger != null)
  783. _doOcrTo6Inch.SetTrigger(false, out _);
  784. if (_doOcrTo12Inch != null && _doOcrTo12Inch.DoTrigger != null)
  785. _doOcrTo12Inch.SetTrigger(false, out _);
  786. if (_doOcrTo4Inch != null && _doOcrTo4Inch.DoTrigger != null)
  787. _doOcrTo4Inch.SetTrigger(false, out _);
  788. //lock (_locker)
  789. //{
  790. // _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetNotchProduct));
  791. // CurrentWaferAlignmentType = WaferAlignerTypeEnum.Notch;
  792. //}
  793. break;
  794. case WaferSize.WS2:
  795. case WaferSize.WS3:
  796. case WaferSize.WS4:
  797. if (_doOcrTo8Inch != null && _doOcrTo8Inch.DoTrigger != null)
  798. _doOcrTo8Inch.SetTrigger(false, out _);
  799. if (_doOcrTo6Inch != null && _doOcrTo6Inch.DoTrigger != null)
  800. _doOcrTo6Inch.SetTrigger(false, out _);
  801. if (_doOcrTo12Inch != null && _doOcrTo12Inch.DoTrigger != null)
  802. _doOcrTo12Inch.SetTrigger(false, out _);
  803. if (_doOcrTo4Inch != null && _doOcrTo4Inch.DoTrigger != null)
  804. _doOcrTo4Inch.SetTrigger(true, out _);
  805. //lock (_locker)
  806. //{
  807. // _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetNotchProduct));
  808. // CurrentWaferAlignmentType = WaferAlignerTypeEnum.Notch;
  809. //}
  810. break;
  811. case WaferSize.WS5:
  812. case WaferSize.WS6:
  813. case WaferSize.WS7:
  814. if (_doOcrTo4Inch != null && _doOcrTo4Inch.DoTrigger != null)
  815. _doOcrTo4Inch.SetTrigger(false, out _);
  816. if (_doOcrTo6Inch != null && _doOcrTo6Inch.DoTrigger != null)
  817. _doOcrTo6Inch.SetTrigger(true, out _);
  818. if (_doOcrTo8Inch != null && _doOcrTo8Inch.DoTrigger != null)
  819. _doOcrTo8Inch.SetTrigger(false, out _);
  820. if (_doOcrTo12Inch != null && _doOcrTo12Inch.DoTrigger != null)
  821. _doOcrTo12Inch.SetTrigger(false, out _);
  822. //lock (_locker)
  823. //{
  824. // if(SC.ContainsItem($"Aligner.{RobotModuleName}.WS6ProductType") &&
  825. // SC.GetStringValue($"Aligner.{RobotModuleName}.WS6ProductType")=="Notch")
  826. // {
  827. // _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetNotchProduct));
  828. // CurrentWaferAlignmentType = WaferAlignerTypeEnum.Notch;
  829. // }
  830. // else
  831. // {
  832. // _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetLineProduct));
  833. // CurrentWaferAlignmentType = WaferAlignerTypeEnum.Line;
  834. // }
  835. //}
  836. break;
  837. default:
  838. break;
  839. }
  840. lock (_locker)
  841. {
  842. if (Size != _currentSetWaferSize)
  843. {
  844. string strpara = _currentSetWaferSize.ToString().Replace("WS", "");
  845. if (strpara == "7")
  846. strpara = "6";
  847. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.SetWaferSize + strpara));
  848. _lstHandler.AddLast(new FuqiRequestHandler(this, FuqiAlignerCommand.Reset));
  849. }
  850. Size = _currentSetWaferSize;
  851. }
  852. break;
  853. }
  854. _timerActionMonitor.Restart();
  855. return true;
  856. }
  857. private string _currentSetParameter;
  858. private WaferSize _currentSetWaferSize = WaferSize.WS0;
  859. protected override bool fMonitorSetParamter(object[] param)
  860. {
  861. IsBusy = false;
  862. if (_timerActionMonitor.IsRunning && _timerActionMonitor.Elapsed > TimeSpan.FromSeconds(TimeLimitAlignWafer))
  863. {
  864. _timerActionMonitor.Stop();
  865. OnError("SetParameterTimeout");
  866. return false;
  867. }
  868. if (_lstHandler.Count != 0 || _connection.IsBusy) return false;
  869. switch (_currentSetParameter)
  870. {
  871. case "WaferSize":
  872. switch (_currentSetWaferSize)
  873. {
  874. case WaferSize.WS6:
  875. if (_diOcrOn4Inch != null && _diOcrOn4Inch.SensorDI != null && _diOcrOn4Inch.Value)
  876. return false;
  877. if (_diOcrOn6Inch != null && _diOcrOn6Inch.SensorDI != null && !_diOcrOn6Inch.Value)
  878. return false;
  879. if (_diOcrOn8Inch != null && _diOcrOn8Inch.SensorDI != null && _diOcrOn8Inch.Value)
  880. return false;
  881. if (_diOcrOn12Inch != null && _diOcrOn12Inch.SensorDI != null && _diOcrOn12Inch.Value)
  882. return false;
  883. break;
  884. case WaferSize.WS8:
  885. if (_diOcrOn4Inch != null && _diOcrOn4Inch.SensorDI != null && _diOcrOn4Inch.Value)
  886. return false;
  887. if (_diOcrOn6Inch != null && _diOcrOn6Inch.SensorDI != null && _diOcrOn6Inch.Value)
  888. return false;
  889. if (_diOcrOn8Inch != null && _diOcrOn8Inch.SensorDI != null && !_diOcrOn8Inch.Value)
  890. return false;
  891. if (_diOcrOn12Inch != null && _diOcrOn12Inch.SensorDI != null && _diOcrOn12Inch.Value)
  892. return false;
  893. break;
  894. case WaferSize.WS4:
  895. if (_diOcrOn4Inch != null && _diOcrOn4Inch.SensorDI != null && !_diOcrOn4Inch.Value)
  896. return false;
  897. if (_diOcrOn6Inch != null && _diOcrOn6Inch.SensorDI != null && _diOcrOn6Inch.Value)
  898. return false;
  899. if (_diOcrOn8Inch != null && _diOcrOn8Inch.SensorDI != null && _diOcrOn8Inch.Value)
  900. return false;
  901. if (_diOcrOn12Inch != null && _diOcrOn12Inch.SensorDI != null && _diOcrOn12Inch.Value)
  902. return false;
  903. break;
  904. case WaferSize.WS12:
  905. if (_diOcrOn4Inch != null && _diOcrOn4Inch.SensorDI != null && _diOcrOn4Inch.Value)
  906. return false;
  907. if (_diOcrOn6Inch != null && _diOcrOn6Inch.SensorDI != null && _diOcrOn6Inch.Value)
  908. return false;
  909. if (_diOcrOn8Inch != null && _diOcrOn8Inch.SensorDI != null && _diOcrOn8Inch.Value)
  910. return false;
  911. if (_diOcrOn12Inch != null && _diOcrOn12Inch.SensorDI != null && !_diOcrOn12Inch.Value)
  912. return false;
  913. break;
  914. default:
  915. _timerActionMonitor.Stop();
  916. return true;
  917. }
  918. WaferManager.Instance.UpdateWaferSize(RobotModuleName, 0, _currentSetWaferSize);
  919. _timerActionMonitor.Stop();
  920. return true;
  921. default:
  922. _timerActionMonitor.Stop();
  923. return true;
  924. }
  925. }
  926. public override RobotArmWaferStateEnum GetWaferState(int slotindex = 0)
  927. {
  928. return IsWaferPresent(slotindex) ? RobotArmWaferStateEnum.Present : RobotArmWaferStateEnum.Absent;
  929. }
  930. public override bool IsNeedChangeWaferSize(WaferSize wz)
  931. {
  932. return true;
  933. }
  934. protected override bool fError(object[] param)
  935. {
  936. return true;
  937. }
  938. public void OnActionDone()
  939. {
  940. IsBusy = false;
  941. //if (_lstHandler.Count == 0)
  942. // OnActionDone(null);
  943. }
  944. #endregion
  945. public override bool IsNeedPrepareBeforePlaceWafer()
  946. {
  947. return true;
  948. }
  949. public override double CompensationAngleValue
  950. {
  951. get
  952. {
  953. if (SC.ContainsItem($"Aligner.{Name}.CompensationAngle"))
  954. return SC.GetValue<double>($"Aligner.{Name}.CompensationAngle");
  955. return 0;
  956. }
  957. }
  958. }
  959. }