RouteManager.cs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931
  1. using System;
  2. using System.Collections.Generic;
  3. using Aitex.Core.Common;
  4. using Aitex.Core.RT.DataCenter;
  5. using Aitex.Core.RT.Event;
  6. using Aitex.Core.RT.Fsm;
  7. using Aitex.Core.RT.OperationCenter;
  8. using Aitex.Core.RT.Routine;
  9. using Aitex.Core.RT.SCCore;
  10. using Aitex.Core.Util;
  11. using MECF.Framework.Common.Equipment;
  12. using MECF.Framework.Common.SubstrateTrackings;
  13. using VirgoCommon;
  14. using VirgoRT.HostWrapper;
  15. using VirgoRT.Instances;
  16. using VirgoRT.Module;
  17. namespace VirgoRT.Modules
  18. {
  19. class RouteManager : Entity, IEntity
  20. {
  21. public enum MSG
  22. {
  23. MoveWafer,
  24. ReturnWafer,
  25. HomeUnit,
  26. PauseAuto,
  27. ResumeAuto,
  28. Stop,
  29. StartCycle,
  30. HOME,
  31. RESET,
  32. ABORT,
  33. ERROR,
  34. SetAutoMode,
  35. SetManualMode,
  36. ResetIdleCleanTime,
  37. ResetIdlePurgeTime,
  38. CreateJob,
  39. PauseJob,
  40. ResumeJob,
  41. StartJob,
  42. StopJob,
  43. AbortJob,
  44. JobDone,
  45. CassetteLeave, //For unload light control off afer job done
  46. Map,
  47. ReturnAllWafer,
  48. }
  49. //public LoadPortEntity LP1 { get; private set; }
  50. //public LoadPortEntity LP2 { get; private set; }
  51. //public CoolingStorageEntity Aligner { get; private set; }
  52. public EfemEntity EFEM { get; private set; }
  53. public PMEntity PMA { get; private set; }
  54. public PMEntity PMB { get; private set; }
  55. //routine
  56. public bool IsAutoIdle
  57. {
  58. get
  59. {
  60. return fsm.State == (int)RtState.AutoIdle;
  61. }
  62. }
  63. public bool IsAutoMode
  64. {
  65. get
  66. {
  67. return fsm.State == (int)RtState.AutoRunning || fsm.State == (int)RtState.AutoIdle;
  68. }
  69. }
  70. public string Name { get; set; }
  71. public bool IsInit
  72. {
  73. get { return fsm.State == (int)RtState.Init; }
  74. }
  75. public bool IsIdle
  76. {
  77. get { return fsm.State == (int)RtState.Idle; }
  78. }
  79. public bool IsAlarm
  80. {
  81. get { return fsm.State == (int)RtState.Error; }
  82. }
  83. public bool IsEntityError
  84. {
  85. get
  86. {
  87. return (EFEM?.IsError ?? false)
  88. || (PMA?.IsError ?? false)
  89. || (PMB?.IsError ?? false);
  90. }
  91. }
  92. public bool IsRunning
  93. {
  94. get
  95. {
  96. return !IsInit && !IsAlarm && !IsIdle;
  97. }
  98. }
  99. private ManualTransfer _manualTransfer;
  100. private AutoTransfer _auto = null;
  101. private ReturnAllWafer _returnWafer;
  102. private HomeAll _homeAll = new HomeAll();
  103. private bool _isWaitUnload;
  104. public RouteManager()
  105. {
  106. Name = "System";
  107. //LP1 = new LoadPortEntity(ModuleName.LP1);
  108. //LP2 = new LoadPortEntity(ModuleName.LP2);
  109. //Aligner = new CoolingStorageEntity(ModuleName.Aligner);
  110. EFEM = new EfemEntity();
  111. if (SC.GetValue<bool>("System.PMAIsInstalled"))
  112. PMA = new PMEntity(ModuleName.PMA);
  113. if (SC.GetValue<bool>("System.PMBIsInstalled"))
  114. PMB = new PMEntity(ModuleName.PMB);
  115. fsm = new StateMachine<RouteManager>(Name, (int)RtState.Init, 50);
  116. BuildTransitionTable();
  117. SubscribeDataVariable();
  118. SubscribeOperation();
  119. Running = true;
  120. }
  121. private void BuildTransitionTable()
  122. {
  123. EnterExitTransition<RtState, FSM_MSG>(RtState.AutoRunning, fEnterAutoRunning, FSM_MSG.NONE, fExitAutoTransfer);
  124. EnterExitTransition<RtState, FSM_MSG>(RtState.Transfer, null, FSM_MSG.NONE, fExitTransfer);
  125. EnterExitTransition<RtState, FSM_MSG>(RtState.Idle, fEnterIdle, FSM_MSG.NONE, fExitIdle);
  126. EnterExitTransition<RtState, FSM_MSG>(RtState.ReturnWafer, null, FSM_MSG.NONE, FsmExitReturnWafer);
  127. //Init sequence
  128. Transition(RtState.Init, MSG.HOME, FsmStartHome, RtState.Initializing);
  129. Transition(RtState.Idle, MSG.HOME, FsmStartHome, RtState.Initializing);
  130. Transition(RtState.Error, MSG.HOME, FsmStartHome, RtState.Initializing);
  131. // EnterExitTransition<RtState, FSM_MSG>(RtState.Initializing, fStartInit, FSM_MSG.NONE, null);
  132. Transition(RtState.Initializing, FSM_MSG.TIMER, FsmMonitorHome, RtState.Idle);
  133. Transition(RtState.Initializing, MSG.ERROR, fError, RtState.Error);
  134. Transition(RtState.Initializing, MSG.ABORT, FsmAbort, RtState.Init);
  135. //Reset
  136. AnyStateTransition(MSG.RESET, fStartReset, RtState.Idle);
  137. AnyStateTransition(MSG.ERROR, fError, RtState.Error);
  138. AnyStateTransition((int)FSM_MSG.ALARM, fError, (int)RtState.Error);
  139. //Unload cassette
  140. AnyStateTransition(MSG.CassetteLeave, fCassetteLeave, FSM_STATE.SAME);
  141. //Auto/manual
  142. Transition(RtState.Idle, MSG.SetAutoMode, fStartAutoTransfer, RtState.AutoIdle);
  143. Transition(RtState.AutoRunning, FSM_MSG.TIMER, fAutoTransfer, RtState.Idle);
  144. Transition(RtState.AutoRunning, MSG.ABORT, fAbortAutoTransfer, RtState.Idle);
  145. //Transition(RtState.AutoRunning, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
  146. Transition(RtState.AutoRunning, MSG.JobDone, fJobDone, RtState.AutoIdle);
  147. //Transition(RtState.AutoRunning, MSG.CassetteLeave, fCassetteLeave, RtState.AutoRunning); //For unload light control off afer job done
  148. Transition(RtState.AutoRunning, MSG.CreateJob, FsmCreateJob, RtState.AutoRunning);
  149. Transition(RtState.AutoRunning, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
  150. Transition(RtState.AutoRunning, MSG.PauseJob, FsmPauseJob, RtState.AutoRunning);
  151. Transition(RtState.AutoRunning, MSG.ResumeJob, FsmResumeJob, RtState.AutoRunning);
  152. Transition(RtState.AutoRunning, MSG.StopJob, FsmStopJob, RtState.AutoRunning);
  153. Transition(RtState.AutoRunning, MSG.AbortJob, FsmAbortJob, RtState.AutoRunning);
  154. Transition(RtState.AutoRunning, MSG.Map, FsmMap, RtState.AutoRunning);
  155. Transition(RtState.AutoRunning, MSG.ResetIdleCleanTime, FsmResetIdleCleanTime, RtState.AutoRunning);
  156. Transition(RtState.AutoRunning, MSG.ResetIdlePurgeTime, FsmResetIdlePurgeTime, RtState.AutoRunning);
  157. Transition(RtState.AutoIdle, FSM_MSG.TIMER, FsmMonitorAutoIdle, RtState.AutoIdle);
  158. Transition(RtState.AutoIdle, MSG.SetManualMode, FsmStartSetManualMode, RtState.Idle);
  159. Transition(RtState.AutoIdle, MSG.CreateJob, FsmCreateJob, RtState.AutoIdle);
  160. Transition(RtState.AutoIdle, MSG.StartJob, FsmStartJob, RtState.AutoRunning);
  161. Transition(RtState.AutoIdle, MSG.PauseJob, FsmPauseJob, RtState.AutoIdle);
  162. Transition(RtState.AutoIdle, MSG.ResumeJob, FsmResumeJob, RtState.AutoIdle);
  163. Transition(RtState.AutoIdle, MSG.StopJob, FsmStopJob, RtState.AutoIdle);
  164. Transition(RtState.AutoIdle, MSG.AbortJob, FsmAbortJob, RtState.AutoIdle);
  165. Transition(RtState.AutoIdle, MSG.Map, FsmMap, RtState.AutoIdle);
  166. //Transition(RtState.AutoIdle, MSG.CassetteLeave, fCassetteLeave, RtState.AutoIdle); //For unload light control off afer job done
  167. Transition(RtState.AutoIdle, MSG.ResetIdleCleanTime, FsmResetIdleCleanTime, RtState.AutoIdle);
  168. Transition(RtState.AutoIdle, MSG.ResetIdlePurgeTime, FsmResetIdlePurgeTime, RtState.AutoIdle);
  169. //Transfer
  170. Transition(RtState.Idle, MSG.MoveWafer, fStartTransfer, RtState.Transfer);
  171. Transition(RtState.Transfer, FSM_MSG.TIMER, fTransfer, RtState.Idle);
  172. Transition(RtState.Transfer, MSG.ABORT, FsmAbort, RtState.Idle);
  173. //Return Wafer
  174. Transition(RtState.Idle, MSG.ReturnAllWafer, FsmStartReturnWafer, RtState.ReturnWafer);
  175. Transition(RtState.ReturnWafer, FSM_MSG.TIMER, FsmMonitorReturnWafer, RtState.Idle);
  176. Transition(RtState.ReturnWafer, MSG.ABORT, FsmAbort, RtState.Idle);
  177. }
  178. void SubscribeDataVariable()
  179. {
  180. DATA.Subscribe("Rt.Status", () => ((RtState)fsm.State).ToString());
  181. DATA.Subscribe(ModuleName.System.ToString(), "AlarmEvent", EV.GetAlarmEvent);
  182. DATA.Subscribe("System.IsAutoMode", () => IsAutoMode);
  183. DATA.Subscribe("System.IsIdle", () => IsIdle || IsInit || IsAutoIdle);
  184. DATA.Subscribe("System.IsAlarm", () => IsAlarm || IsEntityError);
  185. DATA.Subscribe("System.IsBusy", () => IsRunning);
  186. DATA.Subscribe("System.IsWaitUnload", () => _isWaitUnload && IsAutoMode);
  187. DATA.Subscribe("System.IsConnectedWithHost", () => Singleton<FaManager>.Instance.IsConnected);
  188. DATA.Subscribe("EquipmentMode", () => IsAutoMode ? 0 : 1, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  189. DATA.Subscribe("EquipmentStatus", () =>
  190. {
  191. //"0 = Uninit
  192. //1 = Idle
  193. //2 = Running
  194. //3 = Error
  195. //4 = Pause
  196. //"
  197. if (IsInit) return 0;
  198. if (IsIdle||fsm.State == (int)RtState.AutoIdle) return 1;
  199. if (IsAlarm) return 3;
  200. return 2;
  201. }, SubscriptionAttribute.FLAG.IgnoreSaveDB);
  202. }
  203. void SubscribeOperation()
  204. {
  205. OP.Subscribe("CreateWafer", InvokeCreateWafer);
  206. OP.Subscribe("DeleteWafer", InvokeDeleteWafer);
  207. OP.Subscribe("ReturnWafer", InvokeReturnWafer);
  208. OP.Subscribe("System.ReturnAllWafer", (string cmd, object[] args) =>
  209. {
  210. return CheckToPostMessage((int)MSG.ReturnAllWafer, args[0], args[1]);
  211. });
  212. OP.Subscribe("System.MoveWafer", (string cmd, object[] args) =>
  213. {
  214. if (!Enum.TryParse((string)args[0], out ModuleName source))
  215. {
  216. EV.PostWarningLog(Name, $"Parameter source {(string)args[0]} not valid");
  217. return false;
  218. }
  219. if (!Enum.TryParse((string)args[2], out ModuleName destination))
  220. {
  221. EV.PostWarningLog(Name, $"Parameter destination {(string)args[1]} not valid");
  222. return false;
  223. }
  224. return CheckToPostMessage((int)MSG.MoveWafer,
  225. source, (int)args[1],
  226. destination, (int)args[3],
  227. (bool)args[4], (int)args[5],
  228. (bool)args[6], (int)args[7], (string)args[8]);
  229. });
  230. OP.Subscribe("System.HomeAll", (string cmd, object[] args) =>
  231. {
  232. return CheckToPostMessage((int)MSG.HOME);
  233. });
  234. OP.Subscribe("System.Abort", (string cmd, object[] args) =>
  235. {
  236. return CheckToPostMessage((int)MSG.ABORT);
  237. });
  238. OP.Subscribe("System.Reset", (string cmd, object[] args) =>
  239. {
  240. return CheckToPostMessage((int)MSG.RESET);
  241. });
  242. OP.Subscribe("System.SetAutoMode", (string cmd, object[] args) =>
  243. {
  244. return CheckToPostMessage((int)MSG.SetAutoMode);
  245. });
  246. OP.Subscribe("System.SetManualMode", (string cmd, object[] args) =>
  247. {
  248. return CheckToPostMessage((int)MSG.SetManualMode);
  249. });
  250. OP.Subscribe("System.CreateJob", (string cmd, object[] args) =>
  251. {
  252. return CheckToPostMessage((int)MSG.CreateJob, args[0]);
  253. });
  254. OP.Subscribe("System.StartJob", (string cmd, object[] args) =>
  255. {
  256. return CheckToPostMessage((int)MSG.StartJob, args[0]);
  257. });
  258. OP.Subscribe("System.PauseJob", (string cmd, object[] args) =>
  259. {
  260. return CheckToPostMessage((int)MSG.PauseJob, args[0]);
  261. });
  262. OP.Subscribe("System.ResumeJob", (string cmd, object[] args) =>
  263. {
  264. return CheckToPostMessage((int)MSG.ResumeJob, args[0]);
  265. });
  266. OP.Subscribe("System.StopJob", (string cmd, object[] args) =>
  267. {
  268. return CheckToPostMessage((int)MSG.StopJob, args[0]);
  269. });
  270. OP.Subscribe("System.AbortJob", (string cmd, object[] args) =>
  271. {
  272. return CheckToPostMessage((int)MSG.AbortJob, args[0]);
  273. });
  274. OP.Subscribe("LP1.Map", (string cmd, object[] args) =>
  275. {
  276. if (IsAutoMode)
  277. {
  278. return CheckToPostMessage((int)MSG.Map, ModuleName.LP1.ToString());
  279. }
  280. return EFEM.InvokeMap(ModuleName.LP1.ToString())!= (int)FSM_MSG.NONE;
  281. });
  282. OP.Subscribe("LP2.Map", (string cmd, object[] args) =>
  283. {
  284. if (IsAutoMode)
  285. {
  286. return CheckToPostMessage((int)MSG.Map, ModuleName.LP2.ToString());
  287. }
  288. return EFEM.InvokeMap(ModuleName.LP2.ToString()) != (int)FSM_MSG.NONE;
  289. });
  290. OP.Subscribe(RtOperation.SetConfig.ToString(), (name, args) =>
  291. {
  292. string sc_key = args[0] as string;
  293. if (!string.IsNullOrWhiteSpace(sc_key) && args.Length > 1)
  294. {
  295. SC.SetItemValue(sc_key, args[1]);
  296. }
  297. return true;
  298. });
  299. OP.Subscribe("System.ResetIdleCleanTime", (string cmd, object[] args) =>
  300. {
  301. return CheckToPostMessage((int)MSG.ResetIdleCleanTime, args[0]);
  302. });
  303. OP.Subscribe("System.ResetIdlePurgeTime", (string cmd, object[] args) =>
  304. {
  305. return CheckToPostMessage((int)MSG.ResetIdlePurgeTime, args[0]);
  306. });
  307. OP.Subscribe("System.SetWaferSize", (string cmd, object[] args) =>
  308. {
  309. string module = (string)args[0];
  310. string size = (string)args[1];
  311. switch (size)
  312. {
  313. case "3":
  314. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS3);
  315. break;
  316. case "4":
  317. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS4);
  318. break;
  319. case "6":
  320. WaferManager.Instance.UpdateWaferSize(ModuleHelper.Converter(module), 0, WaferSize.WS6);
  321. break;
  322. default:
  323. EV.PostWarningLog("System", $"wafer size {size} not valid");
  324. break;
  325. }
  326. return true;
  327. });
  328. OP.Subscribe("System.CassetteLeave", (string cmd, object[] args) =>
  329. {
  330. return CheckToPostMessage((int)MSG.CassetteLeave);
  331. });
  332. }
  333. public bool CheckToPostMessage(int msg, params object[] args)
  334. {
  335. if (!fsm.FindTransition(fsm.State, msg))
  336. {
  337. EV.PostWarningLog(Name, $"{Name} is in { (RtState)fsm.State} state,can not do {(MSG)msg}");
  338. return false;
  339. }
  340. fsm.PostMsg(msg, args);
  341. return true;
  342. }
  343. public bool Check(int msg, out string reason, params object[] args)
  344. {
  345. if (!fsm.FindTransition(fsm.State, msg))
  346. {
  347. reason = String.Format("{0} is in {1} state,can not do {2}", Name, (RtState)fsm.State, (MSG)msg);
  348. return false;
  349. }
  350. if (msg == (int)MSG.StartCycle)
  351. {
  352. if (!IsAutoMode)
  353. {
  354. reason = String.Format("can not do {0}, isn't auto mode.", msg.ToString());
  355. return false;
  356. }
  357. }
  358. reason = "";
  359. return true;
  360. }
  361. protected override bool Init()
  362. {
  363. _manualTransfer = new ManualTransfer();
  364. Singleton<EventManager>.Instance.OnAlarmEvent += Instance_OnAlarmEvent;
  365. EFEM.Initialize();
  366. //Aligner.Initialize();
  367. //LP1.Initialize();
  368. //LP2.Initialize();
  369. PMA?.Initialize();
  370. PMB?.Initialize();
  371. _auto = new AutoTransfer();
  372. _returnWafer = new ReturnAllWafer();
  373. return true;
  374. }
  375. private void Instance_OnAlarmEvent(EventItem obj)
  376. {
  377. FSM_MSG msg = FSM_MSG.NONE;
  378. if (obj.Level == EventLevel.Warning)
  379. msg = FSM_MSG.WARNING;
  380. else if (obj.Level == EventLevel.Alarm)
  381. msg = FSM_MSG.ALARM;
  382. switch (obj.Source)
  383. {
  384. case "PMA":
  385. PMA?.PostMsg(msg, obj.Id, obj.Description);
  386. break;
  387. case "PMB":
  388. PMB?.PostMsg(msg, obj.Id, obj.Description);
  389. break;
  390. case "EFEM":
  391. EFEM?.PostMsg(msg, obj.Id, obj.Description);
  392. break;
  393. //case "System":
  394. // PostMsg(msg, obj.Id, obj.Description);
  395. // break;
  396. }
  397. }
  398. protected override void Term()
  399. {
  400. PMA?.Terminate();
  401. PMB?.Terminate();
  402. //LP2.Terminate();
  403. //LP1.Terminate();
  404. EFEM.Terminate();
  405. }
  406. #region Init
  407. private bool FsmStartHome(object[] objs)
  408. {
  409. return _homeAll.Start() == Result.RUN;
  410. }
  411. private bool FsmMonitorHome(object[] objs)
  412. {
  413. Result ret = _homeAll.Monitor();
  414. if (ret == Result.DONE)
  415. {
  416. _homeAll.Clear();
  417. return true;
  418. }
  419. if (ret == Result.FAIL)
  420. {
  421. _homeAll.Clear();
  422. PostMsg(MSG.ERROR);
  423. }
  424. return false;
  425. }
  426. private bool fError(object[] objs)
  427. {
  428. if (fsm.State == (int)RtState.Transfer)
  429. {
  430. _manualTransfer.Clear();
  431. }
  432. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.RED, LightStatus.ON);
  433. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.YELLOW, LightStatus.OFF);
  434. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.GREEN, LightStatus.OFF);
  435. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BLUE, LightStatus.OFF);
  436. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BUZZER1, LightStatus.ON);
  437. return true;
  438. }
  439. private bool fEnterIdle(object[] param)
  440. {
  441. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.RED, LightStatus.OFF);
  442. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.YELLOW, LightStatus.ON);
  443. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.GREEN, LightStatus.OFF);
  444. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BLUE, LightStatus.OFF);
  445. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BUZZER1, LightStatus.OFF);
  446. return true;
  447. }
  448. private bool fExitIdle(object[] param)
  449. {
  450. return true;
  451. }
  452. #endregion Init
  453. #region AutoTransfer
  454. private bool FsmMonitorAutoIdle(object[] param)
  455. {
  456. Result ret = _auto.Monitor();
  457. if (!_auto.CheckAllJobDone())
  458. {
  459. return false;
  460. }
  461. _isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone");
  462. return ret == Result.DONE;
  463. }
  464. private bool FsmStartSetManualMode(object[] objs)
  465. {
  466. if (_auto.HasJobRunning)
  467. {
  468. EV.PostWarningLog("System", "Can not change to manual mode, abort running job first");
  469. return false;
  470. }
  471. return true;
  472. }
  473. private bool fStartAutoTransfer(object[] objs)
  474. {
  475. Result ret = _auto.Start(objs);
  476. return ret == Result.RUN;
  477. }
  478. private bool fAutoTransfer(object[] objs)
  479. {
  480. Result ret = _auto.Monitor();
  481. if (_auto.CheckJobJustDone(out string jobInfo))
  482. {
  483. EV.PostPopDialogMessage(EventLevel.InformationNoDelay, "Job complete", jobInfo);
  484. }
  485. if (_auto.CheckAllJobDone())
  486. {
  487. if (!CheckToPostMessage((int)MSG.JobDone))
  488. return false;
  489. }
  490. _isWaitUnload = (bool)DATA.Poll("LP1.NotifyJobDone") || (bool)DATA.Poll("LP2.NotifyJobDone");
  491. return ret == Result.DONE;
  492. }
  493. private bool fEnterAutoRunning(object[] objs)
  494. {
  495. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.RED, LightStatus.OFF);
  496. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.GREEN, LightStatus.ON);
  497. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.YELLOW, LightStatus.OFF);
  498. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BLUE, LightStatus.OFF);
  499. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BUZZER1, LightStatus.OFF);
  500. return true;
  501. }
  502. private bool fExitAutoTransfer(object[] objs)
  503. {
  504. _auto.Clear();
  505. return true;
  506. }
  507. private bool fJobDone(object[] objs)
  508. {
  509. //Unload light control on
  510. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.RED, LightStatus.OFF);
  511. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.GREEN, LightStatus.BLINK);
  512. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.YELLOW, LightStatus.OFF);
  513. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BLUE, LightStatus.OFF);
  514. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BUZZER1, LightStatus.OFF);
  515. _isWaitUnload = true;
  516. return true;
  517. }
  518. private bool fCassetteLeave(object[] objs)
  519. {
  520. //Unload light control off,light as idle & autoidle mode
  521. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.RED, LightStatus.OFF);
  522. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.GREEN, LightStatus.OFF);
  523. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.YELLOW, LightStatus.ON);
  524. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BLUE, LightStatus.OFF);
  525. //EFEM.PostMsg(EfemEntity.MSG.LED, LightType.BUZZER1, LightStatus.OFF);
  526. _isWaitUnload = false;
  527. return true;
  528. }
  529. private bool fAbortAutoTransfer(object[] objs)
  530. {
  531. _auto.Clear();
  532. return true;
  533. }
  534. #endregion AutoTransfer
  535. #region return wafer
  536. private bool FsmStartReturnWafer(object[] objs)
  537. {
  538. Result ret = _returnWafer.Start(objs);
  539. if (ret == Result.FAIL || ret == Result.DONE)
  540. return false;
  541. return ret == Result.RUN;
  542. }
  543. private bool FsmMonitorReturnWafer(object[] objs)
  544. {
  545. Result ret = _returnWafer.Monitor(objs);
  546. if (ret == Result.FAIL)
  547. {
  548. PostMsg(MSG.ERROR);
  549. return false;
  550. }
  551. return ret == Result.DONE;
  552. }
  553. private bool FsmExitReturnWafer(object[] objs)
  554. {
  555. _returnWafer.Clear();
  556. return true;
  557. }
  558. #endregion cycle
  559. #region Transfer
  560. private bool fStartTransfer(object[] objs)
  561. {
  562. Result ret = _manualTransfer.Start(objs);
  563. if (ret == Result.FAIL || ret == Result.DONE)
  564. return false;
  565. return ret == Result.RUN;
  566. }
  567. private bool fTransfer(object[] objs)
  568. {
  569. Result ret = _manualTransfer.Monitor(objs);
  570. if (ret == Result.FAIL)
  571. {
  572. PostMsg(MSG.ERROR);
  573. return false;
  574. }
  575. return ret == Result.DONE;
  576. }
  577. private bool fExitTransfer(object[] objs)
  578. {
  579. _manualTransfer.Clear();
  580. return true;
  581. }
  582. #endregion Transfer
  583. #region reset
  584. private bool fStartReset(object[] objs)
  585. {
  586. //LP1.InvokeReset();
  587. //LP2.InvokeReset();
  588. //Aligner.InvokeReset();
  589. EFEM.InvokeReset();
  590. PMA?.InvokeReset();
  591. PMB?.InvokeReset();
  592. Singleton<DeviceEntity>.Instance.PostMsg(DeviceEntity.MSG.RESET);
  593. Singleton<FaManager>.Instance.ClearAlarm(null);
  594. if (fsm.State == (int)RtState.Error)
  595. return true;
  596. return false;
  597. }
  598. #endregion reset
  599. private bool FsmMap(object[] param)
  600. {
  601. _auto.Map((string)param[0]);
  602. return true;
  603. }
  604. public bool CheckRecipeUsedInJob(string pathName)
  605. {
  606. if (!IsAutoMode)
  607. return false;
  608. return _auto.CheckRecipeUsedInJob(pathName);
  609. }
  610. public bool CheckSequenceUsedInJob(string pathName)
  611. {
  612. if (!IsAutoMode)
  613. return false;
  614. return _auto.CheckSequenceUsedInJob(pathName);
  615. }
  616. private bool FsmCreateJob(object[] param)
  617. {
  618. _auto.CreateJob((Dictionary<string, object>)param[0]);
  619. return true;
  620. }
  621. private bool FsmAbortJob(object[] param)
  622. {
  623. _auto.AbortJob((string)param[0]);
  624. return true;
  625. }
  626. private bool FsmStopJob(object[] param)
  627. {
  628. _auto.StopJob((string)param[0]);
  629. return true;
  630. }
  631. private bool FsmResumeJob(object[] param)
  632. {
  633. _auto.ResumeJob((string)param[0]);
  634. return true;
  635. }
  636. private bool FsmPauseJob(object[] param)
  637. {
  638. _auto.PauseJob((string)param[0]);
  639. return true;
  640. }
  641. private bool FsmStartJob(object[] param)
  642. {
  643. _auto.StartJob((string)param[0]);
  644. return true;
  645. }
  646. private bool FsmAbort(object[] param)
  647. {
  648. if (fsm.State == (int)RtState.Transfer)
  649. {
  650. _manualTransfer.Clear();
  651. }
  652. if (fsm.State == (int)RtState.AutoRunning)
  653. {
  654. _auto.Clear();
  655. }
  656. if (fsm.State == (int)RtState.ReturnWafer)
  657. {
  658. _returnWafer.Clear();
  659. }
  660. return true;
  661. }
  662. private bool FsmResetIdlePurgeTime(object[] param)
  663. {
  664. _auto.ResetIdlePurgeTime((string)param[0]);
  665. return true;
  666. }
  667. private bool FsmResetIdleCleanTime(object[] param)
  668. {
  669. _auto.ResetIdleCleanTime((string)param[0]);
  670. return true;
  671. }
  672. private bool InvokeReturnWafer(string arg1, object[] args)
  673. {
  674. ModuleName target = ModuleHelper.Converter(args[0].ToString());
  675. int slot = (int)args[1];
  676. if (ModuleHelper.IsLoadPort(target))
  677. {
  678. EV.PostInfoLog("System", string.Format("Wafer already at LoadPort {0} {1}, return operation is not valid", target.ToString(), slot + 1));
  679. return false;
  680. }
  681. if (!WaferManager.Instance.IsWaferSlotLocationValid(target, slot))
  682. {
  683. EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", target.ToString(), slot.ToString()));
  684. return false;
  685. }
  686. WaferInfo wafer = WaferManager.Instance.GetWafer(target, slot);
  687. if (wafer.IsEmpty)
  688. {
  689. EV.PostInfoLog("System", string.Format("No wafer at {0} {1}, return operation is not valid", target.ToString(), slot + 1));
  690. return false;
  691. }
  692. return CheckToPostMessage((int)MSG.MoveWafer,
  693. target, slot,
  694. (ModuleName)wafer.OriginStation, wafer.OriginSlot,
  695. false, 0, false, 0 , "Blade1");
  696. }
  697. private bool InvokeDeleteWafer(string arg1, object[] args)
  698. {
  699. ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
  700. int slot = (int)args[1];
  701. if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
  702. {
  703. if (WaferManager.Instance.CheckHasWafer(chamber, slot))
  704. {
  705. WaferManager.Instance.DeleteWafer(chamber, slot);
  706. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferDelete, chamber.ToString(), slot + 1);
  707. }
  708. else
  709. {
  710. EV.PostInfoLog("System", string.Format("No wafer at {0} {1}, delete not valid", chamber.ToString(), slot + 1));
  711. }
  712. }
  713. else
  714. {
  715. EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
  716. return false;
  717. }
  718. return true;
  719. }
  720. private bool InvokeCreateWafer(string arg1, object[] args)
  721. {
  722. ModuleName chamber = ModuleHelper.Converter(args[0].ToString());
  723. int slot = (int)args[1];
  724. WaferStatus state = WaferStatus.Normal;
  725. if (WaferManager.Instance.IsWaferSlotLocationValid(chamber, slot))
  726. {
  727. if (WaferManager.Instance.CheckHasWafer(chamber, slot))
  728. {
  729. EV.PostInfoLog("System", string.Format("{0} slot {1} already has wafer.create wafer is not valid", chamber, slot));
  730. }
  731. else if (WaferManager.Instance.CreateWafer(chamber, slot, state) != null)
  732. {
  733. EV.PostMessage(ModuleName.System.ToString(), EventEnum.WaferCreate, chamber.ToString(), slot + 1, state.ToString());
  734. }
  735. }
  736. else
  737. {
  738. EV.PostWarningLog("System", string.Format("Invalid position,{0},{1}", chamber.ToString(), slot.ToString()));
  739. return false;
  740. }
  741. return true;
  742. }
  743. }
  744. }