PostProcessRoutine.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. using System;
  2. using System.Collections.Generic;
  3. using Aitex.Core.RT.Log;
  4. using Aitex.Core.RT.Routine;
  5. using Aitex.Core.RT.SCCore;
  6. using JetVirgoPM.Devices;
  7. using JetVirgoPM.PMs.Routines;
  8. using MECF.Framework.Common.Equipment;
  9. using MECF.Framework.Common.Routine;
  10. using MECF.Framework.Common.SubstrateTrackings;
  11. using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.PMs;
  12. using MECF.Framework.RT.ModuleLibrary.PMModules;
  13. namespace JetVirgoPM.PMs.RecipeExecutors
  14. {
  15. class PostProcessRoutine : PMRoutineBase
  16. {
  17. private enum PostProcessSequence
  18. {
  19. DelayForTest,
  20. RFPowerOff,
  21. StopGasFlow,
  22. CloseAllValves,
  23. ClosePumpValve,
  24. DelayWaitValve,
  25. Loop,
  26. SetLiftPin1,
  27. SetLiftPin2,
  28. Pump,
  29. PumpDelay,
  30. Vent,
  31. VentDelay,
  32. EndLoop,
  33. ClosePurgeValve,
  34. VentEndToPrecision,
  35. VentEndDelay,
  36. VentEndCloseVentValve,
  37. SetSlitDoor,
  38. VentAndPinDown,
  39. End,
  40. };
  41. private RecipeHead head;
  42. private int _purgeCycleCount;
  43. private int _purgeVentPressure;
  44. private int _purgePumpPressure;
  45. private int _purgeVentTimeLimit;
  46. private int _purgePumpTimeLimit;
  47. private int _purgeVentStableTime;
  48. private int _purgePumpStableTime;
  49. private int _ventTime;
  50. //private int _ventTimeLimit;
  51. private readonly RfPowerRoutine _rfPowerRoutine;
  52. private readonly VentRoutine _ventRoutine;
  53. private readonly int _VentingAndPinUpTimeout = 60 * 1000;
  54. private bool _isSimulatorMode;
  55. private bool _isVented = false;
  56. //---------------------------------Properties------------------------------------
  57. //
  58. public string RecipeName { get; private set; }
  59. public string RecipeContext { get; private set; }
  60. private bool PurgeActive
  61. {
  62. get
  63. {
  64. if (head != null)
  65. {
  66. if (!string.IsNullOrEmpty(head.PurgeActive))
  67. {
  68. return Convert.ToBoolean(head.PurgeActive);
  69. }
  70. }
  71. return true;
  72. }
  73. }
  74. //For keep vacuum after idle clean
  75. private bool NotToPurgeOrVent
  76. {
  77. get
  78. {
  79. if (head != null)
  80. {
  81. if (!string.IsNullOrEmpty(head.NotToPurgeOrVent))
  82. {
  83. return Convert.ToBoolean(head.NotToPurgeOrVent);
  84. }
  85. }
  86. return false;
  87. }
  88. }
  89. private bool LiftPinWhileVenting
  90. {
  91. get
  92. {
  93. if (head != null)
  94. {
  95. if (!string.IsNullOrEmpty(head.VentingPinState))
  96. {
  97. return head.VentingPinState == "Up" ? true : false;
  98. }
  99. }
  100. return false;
  101. }
  102. }
  103. //--------------------------------Constructor------------------------------------
  104. //
  105. public PostProcessRoutine(JetDualPM chamber, VentRoutine _vRoutine) : base(chamber)
  106. {
  107. Name = "PostProcess";
  108. _rfPowerRoutine = new RfPowerRoutine(_chamber, false);
  109. _ventRoutine = _vRoutine;
  110. }
  111. public void Terminate()
  112. {
  113. }
  114. public RState Start(params object[] objs)
  115. {
  116. try
  117. {
  118. Reset();
  119. //this.UpdateSCValue();
  120. RecipeName = (string)objs[0];
  121. RecipeContext = (string)objs[1];
  122. List<RecipeStep> recipeSteps;
  123. if (!Recipe.Parse(Module, RecipeContext, out head, out recipeSteps))
  124. {
  125. return RState.Failed;
  126. }
  127. _purgeCycleCount = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeCycleCount");
  128. _purgeVentPressure = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeVentPressure");
  129. _purgePumpPressure = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgePumpPressure");
  130. _purgeVentTimeLimit = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeVentTimeLimit");
  131. _purgePumpTimeLimit = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgePumpTimeLimit");
  132. _purgeVentStableTime = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgeVentStableTime");
  133. _purgePumpStableTime = (int)SC.GetValue<double>($"{_chamber.Module}.Purge.PurgePumpStableTime");
  134. _isSimulatorMode = SC.GetValue<bool>("System.IsSimulatorMode");
  135. _ventTime = (int)SC.GetValue<double>($"{_chamber.Module}.VentTime");
  136. //_ventTimeLimit = (int)SC.GetSC<double>(SCName.System_VentTimeLimit).Value;
  137. }
  138. catch (Exception ex)
  139. {
  140. LOG.Write(ex, "Post process Start has exception");
  141. return RState.Failed;
  142. }
  143. return Runner.Start(_chamber.Module.ToString(), Name);
  144. }
  145. public RState Monitor()
  146. {
  147. var hasWafer0 = WaferManager.Instance.CheckHasWafer(Module, 0);
  148. var hasWafer1 = WaferManager.Instance.CheckHasWafer(Module, 1);
  149. var pos = (hasWafer0 && hasWafer1) ? EnumDualPM.Both : hasWafer0 ? EnumDualPM.Left : hasWafer1 ? EnumDualPM.Right : EnumDualPM.None;
  150. var pos2 = LiftPinWhileVenting ? EnumDualPM.None : EnumDualPM.Both;
  151. if (!NotToPurgeOrVent && PurgeActive) //For keep vacuum after idle clean
  152. {
  153. Runner.Run(PostProcessSequence.DelayForTest, HOFs.Apply(DelayTime, _isSimulatorMode ? _delay_1s : 0), _isSimulatorMode ? _delay_1s : 0)
  154. .Run(PostProcessSequence.RFPowerOff, RFPowerOff, CheckRFPowerOff)
  155. .Wait(PostProcessSequence.CloseAllValves, CloseAllValve, _delay_1s)
  156. .LoopStart(PostProcessSequence.Loop, "", _purgeCycleCount, HOFs.Apply(Pump, _purgePumpPressure), HOFs.Apply(CheckPump, _purgePumpPressure, true), _purgePumpTimeLimit * 1000)
  157. .LoopDelay(PostProcessSequence.PumpDelay, _purgePumpStableTime * 1000)
  158. .LoopRun(PostProcessSequence.Vent, HOFs.Apply(Vent, _purgeVentPressure), HOFs.Apply(CheckVent, _purgeVentPressure, true), _purgeVentTimeLimit * 1000)
  159. .LoopDelay(PostProcessSequence.VentDelay, _purgeVentStableTime * 1000)
  160. .LoopEnd(PostProcessSequence.EndLoop, NullFun, _delay_1s)
  161. .Run(PostProcessSequence.VentAndPinDown, ParallellyVentAndLiftPin, CheckParallellyVentAndLiftPin, _VentingAndPinUpTimeout * 1000)
  162. .Run(PostProcessSequence.SetLiftPin1, HOFs.Apply(SetLiftPinUpDown, pos2, false), HOFs.Apply(ChecktLiftPinUpDown, pos2, false), _delay_5s)
  163. .Run(PostProcessSequence.VentEndToPrecision, Vent, CheckVent)
  164. .Wait(PostProcessSequence.VentEndCloseVentValve, CloseValve, valveOpenCloseTimeout*1000)
  165. .Run(PostProcessSequence.SetLiftPin2, HOFs.Apply(SetLiftPinUpDown, pos, true), HOFs.Apply(ChecktLiftPinUpDown, pos, true), _delay_5s)
  166. .Run(PostProcessSequence.SetSlitDoor, HOFs.Apply(SetSlitDoor, pos, true), HOFs.Apply(CheckSlitDoor, pos, true), _delay_5s)
  167. .End(PostProcessSequence.End, EndFunc, _delay_1s);
  168. }
  169. else if(!NotToPurgeOrVent)
  170. {
  171. Runner.Run(PostProcessSequence.DelayForTest, HOFs.Apply(DelayTime, _isSimulatorMode ? _delay_1s : 0), _isSimulatorMode ? _delay_1s : 0)
  172. .Run(PostProcessSequence.RFPowerOff, RFPowerOff, CheckRFPowerOff)
  173. .Wait(PostProcessSequence.CloseAllValves, CloseAllValve, _delay_1s)
  174. .Run(PostProcessSequence.VentAndPinDown, ParallellyVentAndLiftPin, CheckParallellyVentAndLiftPin, _VentingAndPinUpTimeout * 1000)
  175. .Run(PostProcessSequence.SetLiftPin1, HOFs.Apply(SetLiftPinUpDown, pos2, false), HOFs.Apply(ChecktLiftPinUpDown, pos2, false), _delay_5s)
  176. .Run(PostProcessSequence.VentEndToPrecision, Vent, CheckVent)
  177. .Wait(PostProcessSequence.VentEndCloseVentValve, CloseValve, valveOpenCloseTimeout * 1000)
  178. .Run(PostProcessSequence.SetLiftPin2, HOFs.Apply(SetLiftPinUpDown, pos, true), HOFs.Apply(ChecktLiftPinUpDown, pos, true), _delay_5s)
  179. .Run(PostProcessSequence.SetSlitDoor, HOFs.Apply(SetSlitDoor, pos, true), HOFs.Apply(CheckSlitDoor, pos, true), _delay_5s)
  180. .End(PostProcessSequence.End, EndFunc, _delay_1s);
  181. }
  182. else
  183. {
  184. Runner.Run(PostProcessSequence.DelayForTest, HOFs.Apply(DelayTime, _isSimulatorMode ? _delay_1s : 0), _isSimulatorMode ? _delay_1s : 0)
  185. .Run(PostProcessSequence.RFPowerOff, RFPowerOff, CheckRFPowerOff)
  186. .Wait(PostProcessSequence.CloseAllValves, CloseAllValve, _delay_1s)
  187. .End(PostProcessSequence.End, EndFunc, _delay_1s);
  188. }
  189. return Runner.Status;
  190. }
  191. bool RFPowerOff()
  192. {
  193. return _rfPowerRoutine.Start() == RState.Running;
  194. }
  195. bool CheckRFPowerOff()
  196. {
  197. var status = _rfPowerRoutine.Monitor();
  198. if (status == RState.End)
  199. {
  200. return true;
  201. }
  202. else if (status == RState.Failed || status == RState.Timeout)
  203. {
  204. Runner.Stop($"RF power off failed.");
  205. return true;
  206. }
  207. return false;
  208. }
  209. bool Vent()
  210. {
  211. if (LiftPinWhileVenting) return true;
  212. _isVented = _ventRoutine.Start() == RState.End;
  213. return _ventRoutine.Start() == RState.Running || _isVented;
  214. }
  215. bool CheckVent()
  216. {
  217. if (LiftPinWhileVenting || _isVented) return true;
  218. var status = _ventRoutine.Monitor();
  219. if (status == RState.End)
  220. {
  221. return true;
  222. }
  223. else if (status == RState.Failed || status == RState.Timeout)
  224. {
  225. Runner.Stop($"Vent failed.");
  226. return true;
  227. }
  228. return false;
  229. }
  230. public void Exit()
  231. {
  232. //ProcessDataRecorder.End(RecipeRunGuid.ToString(), SusceptorStatus.Processed.ToString(), Module);
  233. //if (DeviceModel.SignalTower != null)
  234. //{
  235. // DeviceModel.SignalTower.BuzzerBlinking(SC.GetValue<double>(SCName.System_BuzzerBlinkingTime));
  236. //}
  237. //update processing end time
  238. //Singleton<ProcessRecorder>.Instance.EndRecipeProcess(Singleton<PMEntity>.Instance.CurrentRunningJob.RecipeRunId, SusceptorStatus.Processed);
  239. }
  240. private bool ParallellyVentAndLiftPin()
  241. {
  242. if(LiftPinWhileVenting)
  243. {
  244. Notify($"设置 lift pin {_chamber.Name} " + "升");
  245. if (!SC.GetValue<bool>($"System.SetUp.{_chamber.Name}Chamber1Disabled.IsInstalled"))
  246. {
  247. if (!_chamber.SetLiftPin1(MovementPosition.Up, out string reasonPin1))
  248. {
  249. Stop(reasonPin1);
  250. return false;
  251. }
  252. }
  253. if (!SC.GetValue<bool>($"System.SetUp.{_chamber.Name}Chamber2Disabled.IsInstalled"))
  254. {
  255. if (!_chamber.SetLiftPin2(MovementPosition.Up, out string reasonPin2))
  256. {
  257. Stop(reasonPin2);
  258. return false;
  259. }
  260. }
  261. _ventRoutine.Start();
  262. return true;
  263. }
  264. else
  265. return true;
  266. }
  267. bool CheckParallellyVentAndLiftPin()
  268. {
  269. if (LiftPinWhileVenting)
  270. {
  271. bool res1 = _chamber.CheckLift1Up();
  272. bool res2 = _chamber.CheckLift2Up();
  273. if (SC.GetValue<bool>($"System.SetUp.{_chamber.Name}Chamber1Disabled.IsInstalled"))
  274. {
  275. res1 = true;
  276. }
  277. if (SC.GetValue<bool>($"System.SetUp.{_chamber.Name}Chamber2Disabled.IsInstalled"))
  278. {
  279. res2 = true;
  280. }
  281. var result = _ventRoutine.Monitor();
  282. if (result == RState.Failed || result == RState.Timeout)
  283. {
  284. Runner.Stop($"Vent failed.");
  285. if (result == RState.Timeout)
  286. {
  287. Stop(_chamber.CheckLift1Up() ? $"Set Lift1 Pin Up timeout in {_VentingAndPinUpTimeout / 1000} seconds" : $"Venting timeout in {_VentingAndPinUpTimeout / 1000} seconds");
  288. Stop(_chamber.CheckLift2Up() ? $"Set Lift2 Pin Up timeout in {_VentingAndPinUpTimeout / 1000} seconds" : $"Venting timeout in {_VentingAndPinUpTimeout / 1000} seconds");
  289. }
  290. return true;
  291. }
  292. return res1 && res2 && result == RState.End;
  293. }
  294. else
  295. return true;
  296. }
  297. }
  298. }