JetEfemLoadPort.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961
  1. using System;
  2. using System.Collections;
  3. using System.Threading.Tasks;
  4. using Aitex.Core.Common;
  5. using Aitex.Core.RT.DataCenter;
  6. using Aitex.Core.RT.Device;
  7. using Aitex.Core.RT.Device.Unit;
  8. using Aitex.Core.RT.Event;
  9. using Aitex.Core.RT.Log;
  10. using Aitex.Core.RT.OperationCenter;
  11. using Aitex.Core.RT.SCCore;
  12. using Aitex.Core.Util;
  13. using Aitex.Sorter.Common;
  14. using MECF.Framework.Common.Equipment;
  15. using MECF.Framework.Common.FAServices;
  16. using MECF.Framework.Common.SubstrateTrackings;
  17. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Efems.Rorzes;
  18. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts;
  19. namespace JetEfemLib.LPs
  20. {
  21. public class JetEfemLoadPort : LoadPort, IEfemLoadPortCallback
  22. {
  23. public enum LoadPortStates
  24. {
  25. Undefined = 0,
  26. NotInitialized = 1,
  27. Initializing = 2,
  28. Idle = 3,
  29. Mapping = 4,
  30. MappingStation = 5,
  31. Homing = 6,
  32. Faulted = 7,
  33. Clamping = 8,
  34. Docking = 9,
  35. Unclamping = 10,
  36. Undocking = 11,
  37. OpeningDoor = 12,
  38. ClosingDoor = 13,
  39. Loading = 15,
  40. Unloading = 16,
  41. ReadingCarrierID = 17,
  42. Querying = 18,
  43. ChangeAccessMode = 19,
  44. ChangeTransferState = 20,
  45. WritingCarrierID = 21,
  46. ClearError,
  47. SetIndicator,
  48. }
  49. private LoadportCassetteState _cassetteState;
  50. public override LoadportCassetteState CassetteState
  51. {
  52. get { return _cassetteState; }
  53. set { _cassetteState = value; }
  54. }
  55. private FoupClampState _clampState;
  56. public override FoupClampState ClampState
  57. {
  58. get { return _clampState; }
  59. set { _clampState = value; }
  60. }
  61. private FoupDockState _dockState;
  62. public override FoupDockState DockState
  63. {
  64. get { return _dockState; }
  65. set { _dockState = value; }
  66. }
  67. private FoupDoorState _doorState;
  68. public override FoupDoorState DoorState
  69. {
  70. get { return _doorState; }
  71. set { _doorState = value; }
  72. }
  73. public override bool IsAutoClampOnFoupOn
  74. {
  75. get
  76. {
  77. return SC.GetValueOrDefault<bool>($"EFEM.LoadPort.AutoClampOnFoupOn");
  78. }
  79. }
  80. public override bool IsAutoReadCarrierID
  81. {
  82. get
  83. {
  84. return SC.GetValueOrDefault<bool>($"EFEM.LoadPort.EnableAutoCarrierIdRead");
  85. }
  86. }
  87. private RorzeEfem _efem;
  88. public override bool IsWaferProtrude { get; set; }
  89. private RD_TRIG _trigPresentAbsent = new RD_TRIG();
  90. private RD_TRIG _trigPresentAbsentDely = new RD_TRIG();
  91. private RD_TRIG _trigPlacement = new RD_TRIG();
  92. private R_TRIG _trigWaferProtrude = new R_TRIG();
  93. private LoadPortStates _loadPortState;
  94. public WaferSize WaferSize { get; set; }
  95. public string LastMapResult { get; set; }
  96. public override bool IsBusy => _loadPortState != LoadPortStates.Idle;
  97. private DeviceTimer _deviceTimer = new DeviceTimer();
  98. private int _timeDelayNotifyCassettePresent = 100; //ms
  99. public override WaferSize GetCurrentWaferSize()
  100. {
  101. return WaferSize;
  102. }
  103. //private bool _present4;
  104. //private bool _present6;
  105. private string _efemName;
  106. //private bool _indicatorPlaced;
  107. //private bool _indicatorError;
  108. //private bool _isIntialized;
  109. public JetEfemLoadPort(string module, string name, string efem)
  110. {
  111. base.Module = module;
  112. base.Name = name;
  113. base.Display = name;
  114. base.DeviceID = "";
  115. _efemName = efem;
  116. IsMapWaferByLoadPort = false;
  117. _loadPortState = LoadPortStates.NotInitialized;
  118. }
  119. public override bool Initialize()
  120. {
  121. if (_efem == null && !string.IsNullOrEmpty(_efemName))
  122. {
  123. _efem = DEVICE.GetDevice<JetEfem>(_efemName);
  124. _efem.SetLoadPortCallback(ModuleHelper.Converter(Module), this);
  125. }
  126. //DATA.Subscribe($"{Module}.IndicatorPlaced", () => _indicatorPlaced);
  127. //DATA.Subscribe($"{Module}.IndicatorError", () => _indicatorError);
  128. DATA.Subscribe($"{Module}.IsWaferProtrude", () => IsWaferProtrude);
  129. //DATA.Subscribe($"{Module}.IsPresent4", () => _present4);
  130. //DATA.Subscribe($"{Module}.IsPresent6", () => _present6);
  131. DATA.Subscribe($"{Module}.WaferSize", () => WaferSize.ToString());
  132. DATA.Subscribe($"{Module}.LastMapResult", () => LastMapResult);
  133. if (SC.ContainsItem("EFEM.LoadPort.TimeDelayNotifyCassettePresent"))
  134. {
  135. _timeDelayNotifyCassettePresent = SC.GetValue<int>("EFEM.LoadPort.TimeDelayNotifyCassettePresent");
  136. }
  137. return base.Initialize();
  138. }
  139. public override void Reset()
  140. {
  141. base.Reset();
  142. _trigWaferProtrude.RST = true;
  143. }
  144. public override bool IsEnableMapWafer()
  145. {
  146. return IsPlacement && !IsWaferProtrude;
  147. }
  148. public override bool IsEnableMapWafer(out string reason)
  149. {
  150. reason = string.Empty;
  151. if (_loadPortState != LoadPortStates.Idle)
  152. {
  153. reason = "Cassette is busy";
  154. return false;
  155. }
  156. if (!IsPlacement)
  157. {
  158. reason = "Cassette not properly placed";
  159. return false;
  160. }
  161. if (IsWaferProtrude)
  162. {
  163. reason = "Found wafer protrude";
  164. return false;
  165. }
  166. if (CassetteState != LoadportCassetteState.Normal)
  167. {
  168. reason = "Cassette is abnormal";
  169. return false;
  170. }
  171. return IsPlacement && !IsWaferProtrude;
  172. }
  173. public override bool IsEnableTransferWafer()
  174. {
  175. return IsEnableTransferWafer(out _);
  176. }
  177. public override bool IsEnableTransferWafer(out string reason)
  178. {
  179. if (_loadPortState != LoadPortStates.Idle)
  180. {
  181. reason = "Cassette is busy";
  182. return false;
  183. }
  184. if (!IsPlacement)
  185. {
  186. reason = "No cassette present";
  187. return false;
  188. }
  189. if (IsWaferProtrude)
  190. {
  191. reason = "Found wafer protrude";
  192. return false;
  193. }
  194. if (!_isMapped)
  195. {
  196. reason = "Cassette not mapped";
  197. return false;
  198. }
  199. if (DoorState != FoupDoorState.Open)
  200. {
  201. reason = "Cassette not open";
  202. return false;
  203. }
  204. if (CassetteState != LoadportCassetteState.Normal)
  205. {
  206. reason = "Cassette is abnormal";
  207. return false;
  208. }
  209. reason = "";
  210. return true;
  211. }
  212. public virtual void NoteStatus(string data1, string data2)
  213. {
  214. uint result1 = Convert.ToUInt32(data1, 16);
  215. uint result2 = Convert.ToUInt32(data2, 16);
  216. BitArray bitData1 = new BitArray(new int[] { Convert.ToInt32(data1, 16) });
  217. BitArray bitData2 = new BitArray(new int[] { Convert.ToInt32(data2, 16) });
  218. //placement bit 0
  219. //present bit 1
  220. //access sw bit 2
  221. //clampState bit 3
  222. //doorState bit 4
  223. //dockState bit 5
  224. //wafer size 8 bit 6
  225. //wafer size 12 bit 7
  226. bool placement = (result1 & 0x00000001u) == 0x00000001u;
  227. bool present = !((result1 & 0x00000002u) == 0x00000002u);
  228. SetPresent(present);
  229. SetPlaced(placement);
  230. _isAccessSwPressed = (result1 & 0x00000004u) == 0x00000004u;
  231. _clampState = (result1 & 0x00000008u) == 0x00000008u ? FoupClampState.Close : FoupClampState.Open;
  232. _doorState = (result1 & 0x00000800u) == 0x00000800u ? FoupDoorState.Open : FoupDoorState.Close;
  233. _dockState = (result1 & 0x00000020u) == 0x00000020u ? FoupDockState.Docked : FoupDockState.Undocked;
  234. bool sizecheck1 = (result1 & 0x00000040u) == 0x00000040u;
  235. bool sizecheck2 = (result1 & 0x00000080u) == 0x00000080u;
  236. bool sizecheck3 = (result1 & 0x00000100u) == 0x00000100u;
  237. if (IsPlacement)
  238. {
  239. //if (isWS8 == isWS12)
  240. //{
  241. // EV.PostAlarmLog(LPModuleName.ToString(), "Get WaferSize Data Abnormal , pls check config");
  242. //}
  243. if (sizecheck1 && sizecheck2 && sizecheck3)
  244. {
  245. WaferSize = WaferSize.WS8;
  246. CarrierManager.Instance.UpdateWaferSize(LPModuleName, 0, WaferSize);
  247. }
  248. else if (!sizecheck1 && sizecheck2 && sizecheck3)
  249. {
  250. WaferSize = WaferSize.WS3;
  251. CarrierManager.Instance.UpdateWaferSize(LPModuleName, 0, WaferSize);
  252. }
  253. else if (sizecheck1 && sizecheck2 && !sizecheck3)
  254. {
  255. WaferSize = WaferSize.WS6;
  256. CarrierManager.Instance.UpdateWaferSize(LPModuleName, 0, WaferSize);
  257. }
  258. else if (sizecheck1 && !sizecheck2 && sizecheck3)
  259. {
  260. WaferSize = WaferSize.WS4;
  261. CarrierManager.Instance.UpdateWaferSize(LPModuleName, 0, WaferSize);
  262. }
  263. }
  264. IndicatorVALID = GetIndicatorState((result1 & 0x01000000u) == 0x01000000u); //bit24
  265. IndicatorCS0 = GetIndicatorState((result1 & 0x02000000u) == 0x02000000u); //bit25
  266. IndicatorCS1 = GetIndicatorState((result1 & 0x04000000u) == 0x04000000u); //bit26
  267. IndicatorTR_REQ = GetIndicatorState((result1 & 0x10000000u) == 0x10000000u); //bit28
  268. IndicatorBUSY = GetIndicatorState((result1 & 0x20000000u) == 0x20000000u); //bit29
  269. IndicatorCOMPT = GetIndicatorState((result1 & 0x40000000u) == 0x40000000u); //bit30
  270. IndicatorCONT = GetIndicatorState((result1 & 0x80000000u) == 0x80000000u); //bit31
  271. //E84Signal.VALID = (result1 & 0x01000000u) == 0x01000000u //bit 24
  272. //E84Signal.CS_0 = (result1 & 0x02000000u) == 0x02000000u //bit 25
  273. //E84Signal.CS_1 = (result1 & 0x04000000u) == 0x04000000u //bit 26
  274. //E84Signal.TR_REQ = (result1 & 0x10000000u) == 0x10000000u //bit 28
  275. //E84Signal.BUSY = (result1 & 0x20000000u) == 0x20000000u //bit 29
  276. //E84Signal.COMPT = (result1 & 0x40000000u) == 0x40000000u //bit 30
  277. //E84Signal.CONT = (result1 & 0x80000000u) == 0x80000000u //bit 31
  278. //check presence light bit 0
  279. //check placement light bit 1
  280. //check load light bit 2
  281. //check unload light bit 3
  282. //check manual mode light bit 4
  283. //check error light bit 5
  284. //check clamp/unclamp light bit 6
  285. //check dock/undock light bit 7
  286. //check access switch light bit 8
  287. IndicatiorPresence = GetIndicatorState(bitData2[0]);
  288. IndicatiorPlacement = GetIndicatorState(bitData2[1]);
  289. IndicatiorLoad = GetIndicatorState(bitData2[2]);
  290. IndicatiorUnload = GetIndicatorState(bitData2[3]);
  291. IndicatiorManualMode = GetIndicatorState(bitData2[4]);
  292. IndicatorAlarm = GetIndicatorState(bitData2[5]);
  293. IndicatiorClampUnclamp = GetIndicatorState(bitData2[6]);
  294. IndicatiorDockUndock = GetIndicatorState(bitData2[7]);
  295. IndicatiorOpAccess = GetIndicatorState(bitData2[8]);
  296. IndicatorL_REQ = GetIndicatorState(bitData2[24]); //bit24
  297. IndicatorU_REQ = GetIndicatorState(bitData2[25]); //bit25
  298. IndicatorREADY = GetIndicatorState(bitData2[27]); //bit27
  299. IndicatorHO_AVBL = GetIndicatorState(bitData2[30]); //bit30
  300. IndicatorES = GetIndicatorState(bitData2[31]); //bit31
  301. //E84Signal.L_REQ = bitData2[24] //bit 24
  302. //E84Signal.U_REQ = bitData2[25] //bit 25
  303. //E84Signal.READY = bitData2[27] //bit 27
  304. //E84Signal.HO_AVBL = bitData2[30] //bit 30
  305. //E84Signal.ES = bitData2[31] //bit 31
  306. CassetteState = IsPlacement ? LoadportCassetteState.Normal : LoadportCassetteState.None;
  307. if (bitData2[5])
  308. {
  309. Error = true;
  310. }
  311. else
  312. {
  313. if (_loadPortState == LoadPortStates.Faulted)
  314. Error = true;
  315. else
  316. Error = false;
  317. }
  318. }
  319. /*
  320. *Report the wafer presence of all slots.
  321. 0 =No wafer
  322. 1 =Wafer presence
  323. 2 =Abnormal thickness (Wafer is thick)
  324. 3 =Cross slotted wafer
  325. 4 =Front down wafer
  326. 7 =Multiple wafers are in the same slot
  327. 8 =Abnormal thickness (Wafer is thin)
  328. */
  329. public virtual void NoteSlotMap(string slotMap)
  330. {
  331. slotMap = slotMap.Replace('3', '2');
  332. slotMap = slotMap.Replace('4', 'W');
  333. slotMap = slotMap.Replace('7', 'W');
  334. slotMap = slotMap.Replace('8', 'W');
  335. slotMap = slotMap.Replace('2', 'W');
  336. LastMapResult = slotMap;
  337. base.OnSlotMapRead(slotMap);
  338. }
  339. private IndicatorState GetIndicatorState(bool flag)
  340. {
  341. if (flag)
  342. return IndicatorState.ON;
  343. else
  344. return IndicatorState.OFF;
  345. }
  346. public override void ResetData()
  347. {
  348. _isMapped = false;
  349. _isLoaded = false;
  350. }
  351. public void NoteComplete()
  352. {
  353. //if(_loadPortState == LoadPortStates.Homing)
  354. // _isIntialized = true;
  355. if (_loadPortState == LoadPortStates.Clamping)
  356. EV.Notify(EventPortClamped, new SerializableDictionary<string, string>()
  357. {
  358. {DataVariables.PortID,PortId}
  359. });
  360. if (_loadPortState == LoadPortStates.Unclamping)
  361. EV.Notify(EventPortUnClamped, new SerializableDictionary<string, string>()
  362. {
  363. {DataVariables.PortID,PortId}
  364. });
  365. _loadPortState = LoadPortStates.Idle;
  366. }
  367. public void NoteCancel(string error)
  368. {
  369. IsBusy = false;
  370. EV.PostAlarmLog(Module, $"{Module} is canceled since {error}");
  371. }
  372. public void NoteFailed(string error)
  373. {
  374. IsBusy = false;
  375. EV.PostAlarmLog(Module, $"{Module} is failed since {error}");
  376. }
  377. public void NoteCarrierID(string carrierID)
  378. {
  379. base.OnCarrierIdRead(ModuleHelper.Converter(Module), Name, carrierID);
  380. }
  381. public void NoteWRITETAG(string cid)
  382. {
  383. base.ProceedSetCarrierID(cid);
  384. }
  385. public override bool FALoad(out string reason) //map and loads
  386. {
  387. reason = "";
  388. OP.DoOperation($"{Name}.Load");
  389. return true;
  390. }
  391. public override bool FAUnload(out string reason)
  392. {
  393. reason = "";
  394. OP.DoOperation($"{Name}.Unload");
  395. return true;
  396. }
  397. public override bool Home(out string reason)
  398. {
  399. reason = string.Empty;
  400. if (_efem == null || !_efem.Connection.IsConnected)
  401. {
  402. reason = "efem not connected";
  403. return false;
  404. }
  405. _loadPortState = LoadPortStates.Homing;
  406. //_isIntialized = false;
  407. _isMapped = false;
  408. if (!_efem.HomeLoadPort(Module, out reason))
  409. {
  410. _loadPortState = LoadPortStates.Faulted;
  411. return false;
  412. }
  413. _isLoaded = false;
  414. return true;
  415. }
  416. public override bool ClearError(out string reason)
  417. {
  418. reason = string.Empty;
  419. if (_efem == null || !_efem.Connection.IsConnected)
  420. {
  421. reason = "efem not connected";
  422. return false;
  423. }
  424. //_loadPortState = LoadPortStates.ClearError;
  425. //if (!_efem.ClearAlarm(Module, out reason))
  426. //{
  427. // _loadPortState = LoadPortStates.Faulted;
  428. // return false;
  429. //}
  430. return true;
  431. }
  432. public override bool Clamp(out string reason)
  433. {
  434. reason = string.Empty;
  435. if (_efem == null || !_efem.Connection.IsConnected)
  436. {
  437. reason = "efem not connected";
  438. return false;
  439. }
  440. if (!IsPlacement)
  441. {
  442. reason = "no carrier at load port";
  443. return false;
  444. }
  445. if (ClampState == FoupClampState.Close)
  446. {
  447. return true;
  448. }
  449. _loadPortState = LoadPortStates.Clamping;
  450. if (!_efem.ClampCarrier(Module, out reason))
  451. {
  452. _loadPortState = LoadPortStates.Faulted;
  453. return false;
  454. }
  455. return true;
  456. }
  457. public override bool Unclamp(out string reason)
  458. {
  459. reason = string.Empty;
  460. if (_efem == null || !_efem.Connection.IsConnected)
  461. {
  462. reason = "efem not connected";
  463. return false;
  464. }
  465. if (!IsPlacement)
  466. {
  467. reason = "no carrier at load port";
  468. return false;
  469. }
  470. //if(DoorState != FoupDoorState.Close)
  471. //{
  472. // reason = "cassette not closed";
  473. // return false;
  474. //}
  475. //if(DockState != FoupDockState.Undocked)
  476. //{
  477. // reason = "cassette not undocked";
  478. // return false;
  479. //}
  480. if (ClampState == FoupClampState.Open)
  481. {
  482. return true;
  483. }
  484. _loadPortState = LoadPortStates.Unclamping;
  485. if (!_efem.UnclampCarrier(Module, out reason))
  486. {
  487. _loadPortState = LoadPortStates.Faulted;
  488. return false;
  489. }
  490. _isMapped = false;
  491. return true;
  492. }
  493. public override bool Dock(out string reason)
  494. {
  495. reason = string.Empty;
  496. if (_efem == null || !_efem.Connection.IsConnected)
  497. {
  498. reason = "efem not connected";
  499. return false;
  500. }
  501. if (!IsPlacement)
  502. {
  503. reason = "no carrier at load port";
  504. return false;
  505. }
  506. //if (ClampState != FoupClampState.Close)
  507. //{
  508. // reason = "cassette not clamped";
  509. // return false;
  510. //}
  511. if (DockState == FoupDockState.Docked)
  512. {
  513. return true;
  514. }
  515. _loadPortState = LoadPortStates.Docking;
  516. if (!_efem.MoveCarrierPort(Module, "Dock", out reason))
  517. {
  518. _loadPortState = LoadPortStates.Faulted;
  519. return false;
  520. }
  521. return true;
  522. }
  523. public override bool Undock(out string reason)
  524. {
  525. reason = string.Empty;
  526. if (_efem == null || !_efem.Connection.IsConnected)
  527. {
  528. reason = "efem not connected";
  529. return false;
  530. }
  531. if (!IsPlacement)
  532. {
  533. reason = "no carrier at load port";
  534. return false;
  535. }
  536. //if (DoorState != FoupDoorState.Close)
  537. //{
  538. // reason = "cassette not closed";
  539. // return false;
  540. //}
  541. if (DockState == FoupDockState.Undocked)
  542. {
  543. return true;
  544. }
  545. _loadPortState = LoadPortStates.Undocking;
  546. if (!_efem.MoveCarrierPort(Module, "Undock", out reason))
  547. {
  548. _loadPortState = LoadPortStates.Faulted;
  549. return false;
  550. }
  551. _isMapped = false;
  552. return true;
  553. }
  554. public override bool OpenDoor(out string reason)
  555. {
  556. reason = string.Empty;
  557. if (_efem == null || !_efem.Connection.IsConnected)
  558. {
  559. reason = "efem not connected";
  560. return false;
  561. }
  562. if (!IsPlacement)
  563. {
  564. reason = "no carrier at load port";
  565. return false;
  566. }
  567. //if (ClampState != FoupClampState.Close)
  568. //{
  569. // reason = "cassette not clamped";
  570. // return false;
  571. //}
  572. //if (DockState != FoupDockState.Docked)
  573. //{
  574. // reason = "cassette not docked";
  575. // return false;
  576. //}
  577. if (DoorState == FoupDoorState.Open)
  578. {
  579. return true;
  580. }
  581. _loadPortState = LoadPortStates.OpeningDoor;
  582. if (!_efem.OpenCarrierDoor(Module, out reason))
  583. {
  584. _loadPortState = LoadPortStates.Faulted;
  585. return false;
  586. }
  587. return true;
  588. }
  589. public override bool CloseDoor(out string reason)
  590. {
  591. reason = string.Empty;
  592. if (_efem == null || !_efem.Connection.IsConnected)
  593. {
  594. reason = "efem not connected";
  595. return false;
  596. }
  597. if (!IsPlacement)
  598. {
  599. reason = "no carrier at load port";
  600. return false;
  601. }
  602. //if (ClampState != FoupClampState.Close)
  603. //{
  604. // reason = "cassette not clamped";
  605. // return false;
  606. //}
  607. //if (DockState != FoupDockState.Docked)
  608. //{
  609. // reason = "cassette not docked";
  610. // return false;
  611. //}
  612. if (DoorState == FoupDoorState.Close)
  613. {
  614. return true;
  615. }
  616. _loadPortState = LoadPortStates.ClosingDoor;
  617. if (!_efem.CloseCarrierDoor(Module, out reason))
  618. {
  619. _loadPortState = LoadPortStates.Faulted;
  620. return false;
  621. }
  622. _isMapped = false;
  623. return true;
  624. }
  625. public override bool ReadRfId(out string reason)
  626. {
  627. reason = string.Empty;
  628. if (_efem == null || !_efem.Connection.IsConnected)
  629. {
  630. reason = "efem not connected";
  631. return false;
  632. }
  633. if (!IsPlacement)
  634. {
  635. reason = "no carrier at load port";
  636. return false;
  637. }
  638. //_loadPortState = LoadPortStates.ReadingCarrierID;
  639. if (!_efem.ReadCarrierId(Module, out string carrierId, out reason))
  640. {
  641. EV.PostAlarmLog(Module, "Execute ReadRfid Failed " + reason);
  642. _loadPortState = LoadPortStates.Faulted;
  643. return false;
  644. }
  645. return true;
  646. }
  647. public override bool WriteRfId(string carrierId, out string reason)
  648. {
  649. reason = string.Empty;
  650. if (_efem == null || !_efem.Connection.IsConnected)
  651. {
  652. reason = "efem not connected";
  653. return false;
  654. }
  655. if (!IsPlacement)
  656. {
  657. reason = "no carrier at load port";
  658. return false;
  659. }
  660. //_loadPortState = LoadPortStates.WritingCarrierID;
  661. if (!_efem.WriteCarrierId(Module, carrierId, out reason))
  662. {
  663. SerializableDictionary<string, string> dvid = new SerializableDictionary<string, string>();
  664. dvid["PortID"] = PortId;
  665. dvid[PORT_CTGRY] = PortCategory;
  666. EV.Notify(EventCarrierIdWriteFailed, dvid);
  667. EV.PostAlarmLog(Module, "Execute WriteRfid Failed " + reason);
  668. _loadPortState = LoadPortStates.Faulted;
  669. return false;
  670. }
  671. return true;
  672. }
  673. public override bool ChangeAccessMode(bool auto, out string reason)
  674. {
  675. reason = string.Empty;
  676. if (_efem == null || !_efem.Connection.IsConnected)
  677. {
  678. reason = "efem not connected";
  679. return false;
  680. }
  681. _loadPortState = LoadPortStates.ChangeAccessMode;
  682. //if (!_efem.ChangeLoadPortAccessMode(ModuleHelper.Converter(Module), auto ? LPAccessMode.AUTO.ToString() : LPAccessMode.MANUAL.ToString(), out reason))
  683. if (!_efem.SetLoadPortLight(ModuleHelper.Converter(Module), IndicatorType.AccessManual, auto ? IndicatorState.OFF : IndicatorState.ON, out reason))
  684. {
  685. _loadPortState = LoadPortStates.Faulted;
  686. return false;
  687. }
  688. return true;
  689. }
  690. public override bool GetAccessMode(out string reason)
  691. {
  692. reason = string.Empty;
  693. if (_efem == null || !_efem.Connection.IsConnected)
  694. {
  695. reason = "efem not connected";
  696. return false;
  697. }
  698. if (!_efem.GetLoadPortAccessMode(ModuleHelper.Converter(Module), out reason))
  699. {
  700. return false;
  701. }
  702. return true;
  703. }
  704. public override bool SetIndicator(IndicatorType light, IndicatorState state)
  705. {
  706. if (_efem == null || !_efem.Connection.IsConnected)
  707. {
  708. return false;
  709. }
  710. if (!LoadPortIndicatorLightMap.ContainsKey(light))
  711. {
  712. EV.PostWarningLog(Module, $"Not supported indicator {light}");
  713. return false;
  714. }
  715. _loadPortState = LoadPortStates.SetIndicator;
  716. if (!_efem.SetLoadPortLight(ModuleHelper.Converter(Module), light, state, out string reason))
  717. {
  718. _loadPortState = LoadPortStates.Faulted;
  719. LOG.Write(reason);
  720. return false;
  721. }
  722. return true;
  723. }
  724. public override bool QueryState(out string reason)
  725. {
  726. reason = string.Empty;
  727. if (_efem == null || !_efem.Connection.IsConnected)
  728. {
  729. reason = "efem not connected";
  730. return false;
  731. }
  732. _loadPortState = LoadPortStates.Querying;
  733. if (!_efem.GetLoadPortStatus(Module, out _cassetteState, out _clampState, out _dockState, out _doorState, out reason))
  734. {
  735. _loadPortState = LoadPortStates.Faulted;
  736. return false;
  737. }
  738. return true;
  739. }
  740. public override bool QueryWaferMap(out string reason)
  741. {
  742. reason = string.Empty;
  743. if (_efem == null || !_efem.Connection.IsConnected)
  744. {
  745. reason = "efem not connected";
  746. return false;
  747. }
  748. if (!IsPlacement)
  749. {
  750. reason = "no carrier at load port";
  751. return false;
  752. }
  753. if (_efem.CheckIsBusy(ModuleName.EfemRobot))
  754. {
  755. reason = "efem robot is busy";
  756. return false;
  757. }
  758. //if (ClampState != FoupClampState.Close)
  759. //{
  760. // reason = "cassette not clamped";
  761. // return false;
  762. //}
  763. //if (DockState != FoupDockState.Docked)
  764. //{
  765. // reason = "cassette not docked";
  766. // return false;
  767. //}
  768. if (DoorState != FoupDoorState.Open)
  769. {
  770. reason = "cassette not open";
  771. return false;
  772. }
  773. _loadPortState = LoadPortStates.Mapping;
  774. if (!_efem.MapCarrier(Module, out string slotMap, out reason))
  775. {
  776. _loadPortState = LoadPortStates.Faulted;
  777. return false;
  778. }
  779. return true;
  780. }
  781. public override bool GetMapInfo(out string reason)
  782. {
  783. reason = string.Empty;
  784. if (!IsPlacement)
  785. {
  786. reason = "no carrier at load port";
  787. return false;
  788. }
  789. _loadPortState = LoadPortStates.Querying;
  790. if (!_efem.QueryMapResult(Module, out reason, false))
  791. {
  792. _loadPortState = LoadPortStates.Faulted;
  793. return false;
  794. }
  795. return true;
  796. }
  797. public override bool Stop(out string reason)
  798. {
  799. reason = string.Empty;
  800. _loadPortState = LoadPortStates.Idle;
  801. return true;
  802. }
  803. public void CarrierProcessStartEventNotify()
  804. {
  805. EV.Notify(UniversalEvents.CarrierProcessStart, new SerializableDictionary<string, object>()
  806. {
  807. { DataVariables.PortID, Module},
  808. { DataVariables.CarrierID, _carrierId},
  809. });
  810. }
  811. public void CarrierProcessCompleteEventNotify()
  812. {
  813. EV.Notify(UniversalEvents.CarrierProcessComplete, new SerializableDictionary<string, object>()
  814. {
  815. { DataVariables.PortID, Module},
  816. { DataVariables.CarrierID, _carrierId},
  817. });
  818. }
  819. public void WriteLoadPortAccessModeSuccess()
  820. {
  821. Task.Delay(200).ContinueWith(x=>GetAccessMode(out string reason));
  822. }
  823. }
  824. }