PMProcessRoutine.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. using System;
  2. using System.Collections.Generic;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Venus_RT.Devices;
  6. using MECF.Framework.Common.SubstrateTrackings;
  7. using System.Text.Json;
  8. using Venus_Core;
  9. namespace Venus_RT.Modules.PMs
  10. {
  11. class PMProcessRoutine : PMRoutineBase, IRoutine
  12. {
  13. private enum ProcessStep
  14. {
  15. kPreparePressure,
  16. kPrepareTemperature,
  17. kRunRecipes,
  18. kEnd,
  19. }
  20. public string CurrentRunningRecipe { get; set; }
  21. public string ProcessRecipeName { get; set; }
  22. public string ChuckRecipeName { get; set; }
  23. public string DechuckRecipeNamae { get; set; }
  24. public string CleanRecipeName { get; set; }
  25. public RecipeHead ProcessRecipeHead { get; set; }
  26. public DateTime RecipeStartTime { get; private set; }
  27. private readonly PumpDownRoutine _pumpDownRoutine;
  28. private bool _withWafer = true;
  29. private bool _needPumpDown = false;
  30. private Recipe _currentRecipe = null;
  31. private int _currentStep = 0;
  32. private Queue<Recipe> _qeRecipes = new Queue<Recipe>();
  33. private double _tolerance;
  34. private double _OffsetTemp = 0.0f;
  35. private double ChillerTemp
  36. {
  37. get
  38. {
  39. if (ProcessRecipeHead != null)
  40. {
  41. if (!string.IsNullOrEmpty(ProcessRecipeHead.ChillerTemp))
  42. {
  43. double setpoint = Convert.ToDouble(ProcessRecipeHead.ChillerTemp);
  44. if (setpoint > 0 && setpoint < 600)
  45. return setpoint;
  46. }
  47. }
  48. return 0;
  49. }
  50. }
  51. private double BasePressure
  52. {
  53. get
  54. {
  55. if (ProcessRecipeHead != null)
  56. {
  57. if (!string.IsNullOrEmpty(ProcessRecipeHead.BasePressure))
  58. {
  59. double setpoint = Convert.ToDouble(ProcessRecipeHead.BasePressure);
  60. if (setpoint > 0 && setpoint < 750000)
  61. return setpoint;
  62. }
  63. }
  64. return SC.GetValue<int>($"{Module}.Pump.PumpBasePressure");
  65. }
  66. }
  67. public double EstimatedTotalLeftTime
  68. {
  69. get;
  70. private set;
  71. }
  72. public PMProcessRoutine(JetPM chamber, PumpDownRoutine pdRoutine) : base(chamber)
  73. {
  74. Name = "Process";
  75. _pumpDownRoutine = pdRoutine;
  76. }
  77. public RState Start(params object[] objs)
  78. {
  79. if (_withWafer && WaferManager.Instance.CheckNoWafer(Module.ToString(), 0))
  80. {
  81. Stop($"can not run process, no wafer at {Module}");
  82. return RState.Failed;
  83. }
  84. if (!CheckSlitDoor() || !CheckDryPump() || !CheckTurboPump())
  85. {
  86. return RState.Failed;
  87. }
  88. // Load/Validate Recipe
  89. _qeRecipes.Clear();
  90. string recipeName = (string)objs[0];
  91. Recipe recipe = Recipe.Load(recipeName);
  92. if(recipe == null)
  93. {
  94. return RState.Failed;
  95. }
  96. switch(recipe.Header.Type)
  97. {
  98. case RecipeType.Process:
  99. var chuckRecipe = Recipe.Load(recipe.Header.ChuckRecipe);
  100. var dechuckRecipe = Recipe.Load(recipe.Header.DechuckRecipe);
  101. if(chuckRecipe == null || dechuckRecipe == null)
  102. {
  103. return RState.Failed;
  104. }
  105. ProcessRecipeName = recipeName;
  106. ChuckRecipeName = recipe.Header.ChuckRecipe;
  107. DechuckRecipeNamae = recipe.Header.DechuckRecipe;
  108. _qeRecipes.Enqueue(chuckRecipe);
  109. _qeRecipes.Enqueue(recipe);
  110. _qeRecipes.Enqueue(dechuckRecipe);
  111. break;
  112. case RecipeType.Chuck:
  113. ChuckRecipeName = recipeName;
  114. _qeRecipes.Enqueue(recipe);
  115. break;
  116. case RecipeType.DeChuck:
  117. DechuckRecipeNamae = recipeName;
  118. _qeRecipes.Enqueue(recipe);
  119. break;
  120. case RecipeType.Clean:
  121. CleanRecipeName = recipeName;
  122. _qeRecipes.Enqueue(recipe);
  123. break;
  124. }
  125. _tolerance = SC.GetValue<double>($"System.MaxTemperatureToleranceToTarget");
  126. _OffsetTemp = SC.GetValue<double>($"{Module}.Chiller.ChillerTemperatureOffset");
  127. return Runner.Start(Module, Name);
  128. }
  129. public RState Monitor()
  130. {
  131. Runner.Run((int)ProcessStep.kPreparePressure, PreparePressure, IsPressureReady)
  132. .Run((int)ProcessStep.kPrepareTemperature, PrepareTemp, IsTempReady)
  133. .Run((int)ProcessStep.kRunRecipes, StartNewRecipe, RunRecipes)
  134. .End((int)ProcessStep.kEnd, ProcessDone, _delay_1s);
  135. return Runner.Status;
  136. }
  137. private bool PreparePressure()
  138. {
  139. if(_chamber.ChamberPressure < BasePressure)
  140. {
  141. _needPumpDown = false;
  142. return true;
  143. }
  144. _needPumpDown = true;
  145. return _pumpDownRoutine.Start(BasePressure) == RState.Running;
  146. }
  147. private bool IsPressureReady()
  148. {
  149. if (_needPumpDown == false)
  150. return true;
  151. var status = _pumpDownRoutine.Monitor();
  152. if(status == RState.End)
  153. {
  154. return true;
  155. }
  156. else if (status == RState.Failed || status == RState.Timeout)
  157. {
  158. Runner.Stop($"Pump down to {BasePressure} failed.");
  159. return true;
  160. }
  161. return false;
  162. }
  163. private bool PrepareTemp()
  164. {
  165. return SetCoolantTemp(ChillerTemp, _OffsetTemp);
  166. //return true;
  167. }
  168. private bool IsTempReady()
  169. {
  170. return CheckCoolantTemp(ChillerTemp, _tolerance);
  171. }
  172. private bool StartNewRecipe()
  173. {
  174. if(_qeRecipes.Count > 0)
  175. {
  176. _currentStep = 0;
  177. _currentRecipe = _qeRecipes.Dequeue();
  178. CurrentRunningRecipe = _currentRecipe.Header.Name;
  179. _currentRecipe.Steps[_currentStep].Start();
  180. Notify($"Recipe:{CurrentRunningRecipe} start");
  181. return true;
  182. }
  183. return false;
  184. }
  185. private bool RunRecipes()
  186. {
  187. var step = _currentRecipe.Steps[_currentStep];
  188. var result = step.Run();
  189. if(result == RState.Failed)
  190. {
  191. Runner.Stop($"Recipe:{CurrentRunningRecipe}, Step:{_currentStep + 1} Failed");
  192. return true;
  193. }
  194. else if(result == RState.End)
  195. {
  196. if (_currentStep < _currentRecipe.Steps.Count - 1)
  197. {
  198. _currentStep++;
  199. _currentRecipe.Steps[_currentStep].Start();
  200. }
  201. else
  202. {
  203. Notify($"Recipe:{CurrentRunningRecipe} finished");
  204. return !StartNewRecipe();
  205. }
  206. }
  207. return false;
  208. }
  209. private bool ProcessDone()
  210. {
  211. return true;
  212. }
  213. public void Abort()
  214. {
  215. CloseAllValves();
  216. }
  217. }
  218. }