IoE84.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using System.Xml;
  7. using Aitex.Core.Common.DeviceData;
  8. using Aitex.Core.RT.DataCenter;
  9. using Aitex.Core.RT.Device;
  10. using Aitex.Core.RT.Event;
  11. using Aitex.Core.RT.IOCore;
  12. using Aitex.Core.RT.Log;
  13. using Aitex.Core.RT.OperationCenter;
  14. using Aitex.Core.RT.SCCore;
  15. using Aitex.Core.Util;
  16. namespace Aitex.Core.RT.Device.Unit
  17. {
  18. public enum SignalType
  19. {
  20. Acitvie,
  21. Passive,
  22. }
  23. public enum SignalID
  24. {
  25. CS_0,
  26. CS_1,
  27. AM_AVBL,
  28. VALID,
  29. TR_REQ,
  30. BUSY,
  31. COMPT,
  32. CONT,
  33. L_REQ,
  34. U_REQ,
  35. HO_AVBL,
  36. READY,
  37. ES
  38. }
  39. public class Signal
  40. {
  41. public bool Value
  42. {
  43. get
  44. {
  45. if (_di != null)
  46. return _di.Value;
  47. if (_do != null)
  48. return _do.Value;
  49. return false;
  50. }
  51. }
  52. private SignalID _id;
  53. private RD_TRIG _trig = new RD_TRIG();
  54. private DIAccessor _di = null;
  55. private DOAccessor _do = null;
  56. public event Action<SignalID, bool> OnChanged;
  57. public Signal(SignalID id, DIAccessor diAccessor, DOAccessor doAccessor)
  58. {
  59. _id = id;
  60. _di = diAccessor;
  61. _do = doAccessor;
  62. }
  63. public void Monitor()
  64. {
  65. if (_di != null)
  66. _trig.CLK = _di.Value;
  67. if (_do != null)
  68. _trig.CLK = _do.Value;
  69. if (_trig.R)
  70. {
  71. if (OnChanged != null)
  72. OnChanged(_id, true);
  73. }
  74. if (_trig.M)
  75. {
  76. if (OnChanged != null)
  77. OnChanged(_id, false);
  78. }
  79. }
  80. public void Reset()
  81. {
  82. _trig.RST = true;
  83. }
  84. }
  85. public enum LPAccessMode
  86. {
  87. Operator = 0,
  88. AMHS = 1,
  89. };
  90. public enum LPTransferState
  91. {
  92. OutOfService = 0,
  93. TransferBlocked = 1,
  94. ReadyToLoad = 2,
  95. ReadyToUnload = 3,
  96. InService = 4,
  97. TransferReady = 5,
  98. }
  99. public interface IE84Provider
  100. {
  101. bool ReadyForLoad();
  102. bool ReadyForUnload();
  103. bool FoupArrirved();
  104. bool FoupRemoved();
  105. }
  106. public class E84Passiver : BaseDevice, IDevice
  107. {
  108. public enum E84State
  109. {
  110. Idle,
  111. WaitForTrReqOn,
  112. WaitForBusyOn,
  113. WaitForTransfer,
  114. WaitForBusyOff,
  115. WaitForValidOff,
  116. Error,
  117. }
  118. public enum Timeout
  119. {
  120. TP1,
  121. TP2,
  122. TP3,
  123. TP4,
  124. TP5,
  125. }
  126. public bool LightCurtainBroken { get; set; } //interlock
  127. public LPAccessMode Mode{ get; set; }
  128. public LPTransferState TransferState { get; set; }
  129. public IE84Provider Provider { get; set; }
  130. //Active equipment signal
  131. private DIAccessor _diValid;
  132. private DIAccessor _diCS0;
  133. private DIAccessor _diCS1;
  134. private DIAccessor _diAmAvbl;
  135. private DIAccessor _diTrReq;
  136. private DIAccessor _diBusy;
  137. private DIAccessor _diCompt;
  138. private DIAccessor _diCont;
  139. //Passive
  140. private DOAccessor _doLoadReq;
  141. private DOAccessor _doUnloadReq;
  142. private DOAccessor _doReady;
  143. private DOAccessor _doHOAvbl;
  144. private DOAccessor _doES;
  145. private DeviceTimer _timer = new DeviceTimer();
  146. private R_TRIG _trigReset = new R_TRIG();
  147. private List<Signal> _signals = new List<Signal>();
  148. //timeout
  149. private SCConfigItem _scTimeoutTP1;
  150. private SCConfigItem _scTimeoutTP2;
  151. private SCConfigItem _scTimeoutTP3;
  152. private SCConfigItem _scTimeoutTP4;
  153. private SCConfigItem _scTimeoutTP5;
  154. private int reqOnTimeout = 2; //L_REQ|U_REQ_ON ON ---> TR REQ ON
  155. private int readyOnTimeout = 2; //READY ON ---> BUSY ON
  156. private int busyOnTimeout = 2; //BUSYON -- CARRIAGE DETECT|CARRIAGE REMOVE
  157. private int reqOffTimeout = 2; //L_REQ|U_REQ off --->BUSY off
  158. private int readyOffTimeout = 2; //Ready off --->Valid off
  159. private E84State _state;
  160. private Timeout _tp;
  161. public E84Passiver(string module, XmlElement node, string ioModule = "")
  162. {
  163. base.Module = node.GetAttribute("module");
  164. base.Name = node.GetAttribute("id");
  165. base.Display = node.GetAttribute("display");
  166. base.DeviceID = node.GetAttribute("schematicId");
  167. _diValid = ParseDiNode("VALID", node, ioModule);
  168. _signals.Add(new Signal(SignalID.VALID, _diValid, null));
  169. _diCS0 = ParseDiNode("CS_0", node, ioModule);
  170. _signals.Add(new Signal(SignalID.CS_0, _diCS0, null));
  171. _diCS1 = ParseDiNode("CS_1", node, ioModule);
  172. _signals.Add(new Signal(SignalID.CS_1, _diCS1, null));
  173. _diAmAvbl = ParseDiNode("AM_AVBL", node, ioModule);
  174. _signals.Add(new Signal(SignalID.AM_AVBL, _diAmAvbl, null));
  175. _diTrReq = ParseDiNode("TR_REQ", node, ioModule);
  176. _signals.Add(new Signal(SignalID.TR_REQ, _diTrReq, null));
  177. _diBusy = ParseDiNode("BUSY", node, ioModule);
  178. _signals.Add(new Signal(SignalID.BUSY, _diBusy, null));
  179. _diCompt = ParseDiNode("COMPT", node, ioModule);
  180. _signals.Add(new Signal(SignalID.COMPT, _diCompt, null));
  181. _diCont = ParseDiNode("CONT", node, ioModule);
  182. _signals.Add(new Signal(SignalID.CONT, _diCont, null));
  183. _doLoadReq = ParseDoNode("L_REQ", node, ioModule);
  184. _signals.Add(new Signal(SignalID.L_REQ, null, _doLoadReq));
  185. _doUnloadReq = ParseDoNode("U_REQ", node, ioModule);
  186. _signals.Add(new Signal(SignalID.U_REQ, null, _doUnloadReq));
  187. _doReady = ParseDoNode("READY", node, ioModule);
  188. _signals.Add(new Signal(SignalID.READY, null, _doReady));
  189. _doHOAvbl = ParseDoNode("HO_AVBL", node, ioModule);
  190. _signals.Add(new Signal(SignalID.HO_AVBL, null, _doHOAvbl));
  191. _doES = ParseDoNode("ES", node, ioModule);
  192. _signals.Add(new Signal(SignalID.ES, null, _doES));
  193. foreach (var signal in _signals)
  194. {
  195. signal.OnChanged += OnSignalChange;
  196. }
  197. _scTimeoutTP1 = SC.GetConfigItem("Fa.E84.TP1");
  198. _scTimeoutTP2 = SC.GetConfigItem("Fa.E84.TP2");
  199. _scTimeoutTP3 = SC.GetConfigItem("Fa.E84.TP3");
  200. _scTimeoutTP4 = SC.GetConfigItem("Fa.E84.TP4");
  201. _scTimeoutTP5 = SC.GetConfigItem("Fa.E84.TP5");
  202. }
  203. public bool Initialize()
  204. {
  205. reset();
  206. return true;
  207. }
  208. private bool InvokeReset(string arg1, object[] arg2)
  209. {
  210. //string reason;
  211. EV.PostInfoLog(Module, $"E84 reset {Module}.{Name}");
  212. reset();
  213. return true;
  214. }
  215. public void Terminate()
  216. {
  217. reset();
  218. }
  219. private void reset()
  220. {
  221. _doLoadReq.Value = false;
  222. _doUnloadReq.Value = false;
  223. _doReady.Value = false;
  224. _doHOAvbl.Value = false;
  225. _doES.Value = false;
  226. _state = E84State.Idle;
  227. foreach (var signal in _signals)
  228. {
  229. signal.Reset();
  230. }
  231. }
  232. public void Monitor()
  233. {
  234. try
  235. {
  236. foreach (var signal in _signals)
  237. {
  238. signal.Monitor();
  239. }
  240. if (LightCurtainBroken)
  241. {
  242. _doES.Value = false;
  243. }
  244. else
  245. {
  246. _doES.Value = true;
  247. }
  248. if (Mode != LPAccessMode.AMHS)
  249. {
  250. _doHOAvbl.Value = false;
  251. return;
  252. }
  253. if (_timer.IsTimeout())
  254. {
  255. _doHOAvbl.Value = false;
  256. _doLoadReq.Value = false;
  257. _doUnloadReq.Value = false;
  258. _doReady.Value = false;
  259. _doES.Value = false;
  260. _state = E84State.Error;
  261. switch (_state)
  262. {
  263. case E84State.WaitForTrReqOn:
  264. _tp = Timeout.TP1;
  265. break;
  266. case E84State.WaitForBusyOn:
  267. _tp = Timeout.TP2;
  268. break;
  269. case E84State.WaitForTransfer:
  270. _tp = Timeout.TP3;
  271. break;
  272. case E84State.WaitForBusyOff:
  273. _tp = Timeout.TP4;
  274. break;
  275. case E84State.WaitForValidOff:
  276. _tp = Timeout.TP5;
  277. break;
  278. }
  279. EV.PostMessage("E84", EventEnum.DefaultAlarm, string.Format("E84 {0} Timeout", _tp));
  280. }
  281. switch (_state)
  282. {
  283. case E84State.Idle:
  284. {
  285. if (waitValidOn())
  286. {
  287. _state = E84State.WaitForTrReqOn;
  288. if (_scTimeoutTP1 != null)
  289. reqOnTimeout = _scTimeoutTP1.IntValue;
  290. _timer.Start(reqOnTimeout);
  291. }
  292. }
  293. break;
  294. case E84State.WaitForTrReqOn:
  295. {
  296. if (wait4TrReqOn())
  297. {
  298. _state = E84State.WaitForBusyOn;
  299. if(_scTimeoutTP2!= null)
  300. readyOnTimeout = _scTimeoutTP2.IntValue;
  301. _timer.Start(readyOnTimeout);
  302. }
  303. }
  304. break;
  305. case E84State.WaitForBusyOn:
  306. {
  307. if (wait4BusyOn())
  308. {
  309. _state = E84State.WaitForTransfer;
  310. if (_scTimeoutTP3 != null)
  311. busyOnTimeout = _scTimeoutTP3.IntValue;
  312. _timer.Start(busyOnTimeout);
  313. }
  314. }
  315. break;
  316. case E84State.WaitForTransfer:
  317. {
  318. if (wait4Transfer())
  319. {
  320. _state = E84State.WaitForBusyOff;
  321. if (_scTimeoutTP4 != null)
  322. reqOffTimeout = _scTimeoutTP4.IntValue;
  323. _timer.Start(reqOffTimeout);
  324. }
  325. }
  326. break;
  327. case E84State.WaitForBusyOff:
  328. {
  329. if (wait4BusyOff())
  330. {
  331. _state = E84State.WaitForValidOff;
  332. if (_scTimeoutTP5 != null)
  333. readyOffTimeout = _scTimeoutTP5.IntValue;
  334. _timer.Start(readyOffTimeout);
  335. }
  336. }
  337. break;
  338. case E84State.WaitForValidOff:
  339. {
  340. if (waitValidOff())
  341. {
  342. _state = E84State.Idle;
  343. _timer.Stop();
  344. }
  345. }
  346. break;
  347. case E84State.Error:
  348. {
  349. if (autoRecovery())
  350. {
  351. _state = E84State.Idle;
  352. _timer.Stop();
  353. }
  354. }
  355. break;
  356. }
  357. }
  358. catch (Exception ex)
  359. {
  360. LOG.Write(ex);
  361. }
  362. }
  363. public void Reset()
  364. {
  365. _doLoadReq.Value = false;
  366. _doUnloadReq.Value = false;
  367. _doReady.Value = false;
  368. _doHOAvbl.Value = false;
  369. _doES.Value = false;
  370. foreach (var signal in _signals)
  371. {
  372. signal.Reset();
  373. }
  374. if (TransferState != LPTransferState.OutOfService)
  375. {
  376. if (Mode == LPAccessMode.AMHS)
  377. {
  378. _doHOAvbl.Value = true;
  379. _doES.Value = true;
  380. }
  381. }
  382. }
  383. private bool waitValidOn()
  384. {
  385. if (_diValid.Value)
  386. {
  387. if (!_diCS0.Value && !_diCS1.Value)
  388. {
  389. EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, CS0 or CS1 should be on");
  390. _doHOAvbl.Value = false;
  391. return false;
  392. }
  393. if (_diTrReq.Value)
  394. {
  395. EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, VALID should be off");
  396. _doHOAvbl.Value = false;
  397. return false;
  398. }
  399. if (_diBusy.Value)
  400. {
  401. EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, BUSY should be off");
  402. _doHOAvbl.Value = false;
  403. return false;
  404. }
  405. if (_diCompt.Value)
  406. {
  407. EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn on, COMPT should be off");
  408. _doHOAvbl.Value = false;
  409. return false;
  410. }
  411. if (TransferState == LPTransferState.ReadyToLoad)
  412. {
  413. _doLoadReq.Value = true;
  414. }
  415. else if (TransferState == LPTransferState.ReadyToUnload)
  416. {
  417. _doUnloadReq.Value = true;
  418. }
  419. }
  420. return true;
  421. }
  422. private bool wait4TrReqOn()
  423. {
  424. if (_diTrReq.Value)
  425. {
  426. if (!_diCS0.Value && !_diCS1.Value)
  427. {
  428. EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, CS0 or CS1 should be on");
  429. _doHOAvbl.Value = false;
  430. return false;
  431. }
  432. if (!_diValid.Value)
  433. {
  434. EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, TR_REQ should be off");
  435. _doHOAvbl.Value = false;
  436. return false;
  437. }
  438. if (_diBusy.Value)
  439. {
  440. EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, BUSY should be off");
  441. _doHOAvbl.Value = false;
  442. return false;
  443. }
  444. if (_diCompt.Value)
  445. {
  446. EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, COMPT should be off");
  447. _doHOAvbl.Value = false;
  448. return false;
  449. }
  450. if (TransferState == LPTransferState.ReadyToLoad)
  451. {
  452. if(Provider.ReadyForLoad())
  453. _doReady.Value = true;
  454. }
  455. else if (TransferState == LPTransferState.ReadyToUnload)
  456. {
  457. if(Provider.ReadyForUnload())
  458. _doReady.Value = true;
  459. }
  460. return true;
  461. }
  462. return false;
  463. }
  464. private bool wait4BusyOn()
  465. {
  466. if (_diBusy.Value)
  467. {
  468. if (!_diCS0.Value && !_diCS1.Value)
  469. {
  470. EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn on, CS0 or CS1 should be on");
  471. _doHOAvbl.Value = false;
  472. return false;
  473. }
  474. if (!_diValid.Value)
  475. {
  476. EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn on, VALID should be on");
  477. _doHOAvbl.Value = false;
  478. return false;
  479. }
  480. if (!_diTrReq.Value)
  481. {
  482. EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, TR_REQ should be on");
  483. _doHOAvbl.Value = false;
  484. return false;
  485. }
  486. if (_diCompt.Value)
  487. {
  488. EV.PostMessage("E84", EventEnum.DefaultWarning, "When TR_REQ turn on, COMPT should be off");
  489. _doHOAvbl.Value = false;
  490. return false;
  491. }
  492. return true;
  493. }
  494. return false;
  495. }
  496. private bool wait4Transfer()
  497. {
  498. if (TransferState == LPTransferState.ReadyToLoad)
  499. {
  500. if (Provider.FoupArrirved()) //FOUP placement
  501. {
  502. _doLoadReq.Value = false;
  503. return true;
  504. }
  505. }
  506. else if (TransferState == LPTransferState.ReadyToUnload)
  507. {
  508. if (Provider.FoupArrirved()) //FOUP placement
  509. {
  510. _doUnloadReq.Value = false;
  511. return true;
  512. }
  513. }
  514. return false;
  515. }
  516. private bool wait4BusyOff()
  517. {
  518. if (_diCompt.Value && !_diTrReq.Value && !_diBusy.Value)
  519. {
  520. if (!_diValid.Value)
  521. {
  522. EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn off, VALID should be on");
  523. _doHOAvbl.Value = false;
  524. return false;
  525. }
  526. if (!_diCS0.Value && !_diCS1.Value)
  527. {
  528. EV.PostMessage("E84", EventEnum.DefaultWarning, "When BUSY turn off, CS0 or CS1 should be on");
  529. _doHOAvbl.Value = false;
  530. return false;
  531. }
  532. _doReady.Value = false;
  533. return true;
  534. }
  535. return false;
  536. }
  537. private bool waitValidOff()
  538. {
  539. if (_diValid.Value && (_diCS0.Value || _diCS1.Value) && !_diCompt.Value)
  540. {
  541. _doHOAvbl.Value = true;
  542. if (_diBusy.Value)
  543. {
  544. EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn off, BUSY should be off");
  545. _doHOAvbl.Value = false;
  546. return false;
  547. }
  548. if (_diTrReq.Value)
  549. {
  550. EV.PostMessage("E84", EventEnum.DefaultWarning, "When VALID turn off, TR REQ should be off");
  551. _doHOAvbl.Value = false;
  552. return false;
  553. }
  554. _doLoadReq.Value = false;
  555. _doUnloadReq.Value = false;
  556. _doReady.Value = false;
  557. _doES.Value = false;
  558. return true;
  559. }
  560. return false;
  561. }
  562. private bool autoRecovery()
  563. {
  564. bool ret = false;
  565. switch (_tp)
  566. {
  567. case Timeout.TP1:
  568. case Timeout.TP2:
  569. case Timeout.TP5:
  570. {
  571. if ( !_diAmAvbl.Value && !_diValid.Value && !_diCS0.Value && !_diCS1.Value
  572. &&!_diTrReq.Value && !_diBusy.Value && !_diCompt.Value && !_diCont.Value)
  573. ret = true;
  574. }
  575. break;
  576. }
  577. return ret;
  578. }
  579. private void OnSignalChange(SignalID signal, bool value)
  580. {
  581. }
  582. }
  583. }