VpwManualPrepareRoutine.cs 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. using Aitex.Core.RT.Device;
  2. using Aitex.Core.RT.Log;
  3. using Aitex.Core.RT.Routine;
  4. using Aitex.Core.RT.SCCore;
  5. using Aitex.Core.Util;
  6. using MECF.Framework.Common.Equipment;
  7. using MECF.Framework.Common.RecipeCenter;
  8. using MECF.Framework.Common.Routine;
  9. using MECF.Framework.Common.SubstrateTrackings;
  10. using PunkHPX8_Core;
  11. using PunkHPX8_RT.Devices.AXIS;
  12. using PunkHPX8_RT.Devices.VpwCell;
  13. using PunkHPX8_RT.Devices.VpwMain;
  14. using PunkHPX8_RT.Modules.VpwMain;
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Threading.Tasks;
  20. namespace PunkHPX8_RT.Modules.VpwCell
  21. {
  22. public class VpwManualPrepareRoutine : RoutineBase, IRoutine
  23. {
  24. private enum PrepareStep
  25. {
  26. CheckPreCondition=0,
  27. Purge,
  28. WaitPurge,
  29. RotationPositionOffset=1,
  30. WaitRotation,
  31. CloseDrip,
  32. Delay,
  33. WaitWafer,
  34. ChamberUp,
  35. CloseDrain,
  36. CheckLoopDO,
  37. End
  38. }
  39. #region 内部变量
  40. /// <summary>
  41. /// recipe
  42. /// </summary>
  43. private VpwRecipe _recipe;
  44. /// <summary>
  45. /// 电机
  46. /// </summary>
  47. private JetAxisBase _rotationAxis;
  48. /// <summary>
  49. /// 设备
  50. /// </summary>
  51. private VpwCellDevice _vpwCellDevice;
  52. /// <summary>
  53. /// Main设备
  54. /// </summary>
  55. private VpwMainDevice _mainDevice;
  56. /// <summary>
  57. /// VPW Entity
  58. /// </summary>
  59. private VpwMainEntity _vpwMainEntity;
  60. /// <summary>
  61. /// 延迟时间
  62. /// </summary>
  63. private int _putDownAfterDripClose = 2000;
  64. /// <summary>
  65. /// 等待Wafer放入时间
  66. /// </summary>
  67. private int _waitForWaferTime = 300000;
  68. #endregion
  69. /// <summary>
  70. /// 构造函数
  71. /// </summary>
  72. /// <param name="module"></param>
  73. public VpwManualPrepareRoutine(string module) : base(module)
  74. {
  75. }
  76. /// <summary>
  77. /// 中止
  78. /// </summary>
  79. public void Abort()
  80. {
  81. Runner.Stop("Manual abort");
  82. }
  83. /// <summary>
  84. /// 监控
  85. /// </summary>
  86. /// <returns></returns>
  87. public RState Monitor()
  88. {
  89. Runner.Run(PrepareStep.CheckPreCondition,CheckPreCondition,_delay_1ms)
  90. .RunIf(PrepareStep.Purge,_recipe.PurgeEnable,Purge,_delay_1ms)
  91. .WaitWithStopConditionIf(PrepareStep.WaitPurge,_recipe.PurgeEnable,CheckPurgeStatus,CheckPurgeStopStatus)
  92. .Run(PrepareStep.RotationPositionOffset,RotationPositionOffset,_delay_1ms)
  93. .WaitWithStopCondition(PrepareStep.WaitRotation,CheckRotationStatus,CheckRotationStopStatus)
  94. .Run(PrepareStep.CloseDrip,()=>_vpwCellDevice.FlowDripOff(),_delay_1ms)
  95. .Delay(PrepareStep.Delay,_putDownAfterDripClose)
  96. .Wait(PrepareStep.WaitWafer,CheckWaferExsit,_waitForWaferTime)
  97. .Run(PrepareStep.ChamberUp,ChamberUp,CheckChamberClosed)
  98. .Run(PrepareStep.CloseDrain,_vpwCellDevice.DrainValveOff,_delay_1ms)
  99. .Run(PrepareStep.CheckLoopDO,CheckLoopDO,_delay_1ms)
  100. .End(PrepareStep.End,NullFun,_delay_1ms);
  101. return Runner.Status;
  102. }
  103. /// <summary>
  104. /// Purge routine
  105. /// </summary>
  106. /// <returns></returns>
  107. private bool Purge()
  108. {
  109. if (_vpwMainEntity == null)
  110. {
  111. NotifyError(eEvent.ERR_VPW, "VPW Main not exist", -1);
  112. return false;
  113. }
  114. if (_vpwMainEntity.IsIdle)
  115. {
  116. return _vpwMainEntity.CheckToPostMessage<VPWMainState, VPWMainMsg>(eEvent.ERR_VPW, Module, (int)VPWMainMsg.Purge);
  117. }
  118. else if (_vpwMainEntity.State == VPWMainState.Purgeing)
  119. {
  120. return true;
  121. }
  122. else
  123. {
  124. NotifyError(eEvent.ERR_VPW, $"State {_vpwMainEntity.State} cannot purge", -1);
  125. return false;
  126. }
  127. }
  128. /// <summary>
  129. /// 检验Purge执行是否结束
  130. /// </summary>
  131. /// <returns></returns>
  132. private bool CheckPurgeStatus()
  133. {
  134. return _vpwMainEntity.IsIdle;
  135. }
  136. /// <summary>
  137. /// 检验Purger执行是否出现异常
  138. /// </summary>
  139. /// <returns></returns>
  140. private bool CheckPurgeStopStatus()
  141. {
  142. return _vpwMainEntity.IsError;
  143. }
  144. /// <summary>
  145. /// Position运行至offset
  146. /// </summary>
  147. /// <returns></returns>
  148. private bool RotationPositionOffset()
  149. {
  150. bool result= _rotationAxis.PositionStation("ChuckPlaceOffset");
  151. if (!result)
  152. {
  153. NotifyError(eEvent.ERR_VPW, "rotation start position to ChuckPlaceOffset failed", -1);
  154. }
  155. return result;
  156. }
  157. /// <summary>
  158. /// 检验电机是否完成运动
  159. /// </summary>
  160. /// <returns></returns>
  161. private bool CheckRotationStatus()
  162. {
  163. return _rotationAxis.Status == RState.End;
  164. }
  165. /// <summary>
  166. /// 检验电机运动是否出现异常
  167. /// </summary>
  168. /// <returns></returns>
  169. private bool CheckRotationStopStatus()
  170. {
  171. bool result= _rotationAxis.Status == RState.Failed;
  172. if (result)
  173. {
  174. NotifyError(eEvent.ERR_VPW, "rotation position to ChuckPlaceOffset failed", -1);
  175. }
  176. return result;
  177. }
  178. /// <summary>
  179. /// 检验是否存在Wafer
  180. /// </summary>
  181. /// <returns></returns>
  182. private bool CheckWaferExsit()
  183. {
  184. return WaferManager.Instance.CheckHasWafer(Module, 0);
  185. }
  186. /// <summary>
  187. /// chamber up
  188. /// </summary>
  189. /// <returns></returns>
  190. private bool ChamberUp()
  191. {
  192. bool result=_mainDevice.ChamberUp();
  193. if (!result)
  194. {
  195. NotifyError(eEvent.ERR_VPW, "chamber up failed", -1);
  196. }
  197. return result;
  198. }
  199. /// <summary>
  200. /// 检验Chamber是否关闭
  201. /// </summary>
  202. /// <returns></returns>
  203. private bool CheckChamberClosed()
  204. {
  205. return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened;
  206. }
  207. /// <summary>
  208. /// Check LoopDO数值
  209. /// </summary>
  210. /// <returns></returns>
  211. private bool CheckLoopDO()
  212. {
  213. double loopDoValue = _vpwCellDevice.LoopDOValue;
  214. bool result = loopDoValue < _recipe.DiwLoopDoSet;
  215. if (!result)
  216. {
  217. NotifyError(eEvent.ERR_VPW, $"LoopDO value {loopDoValue} is less than {_recipe.DiwLoopDoSet}", -1);
  218. }
  219. return result;
  220. }
  221. /// <summary>
  222. /// 启动
  223. /// </summary>
  224. /// <param name="objs"></param>
  225. /// <returns></returns>
  226. public RState Start(params object[] objs)
  227. {
  228. _recipe=(VpwRecipe)objs[0];
  229. _rotationAxis = DEVICE.GetDevice<JetAxisBase>($"{Module}.Rotation");
  230. _vpwCellDevice = DEVICE.GetDevice<VpwCellDevice>(Module);
  231. _mainDevice = DEVICE.GetDevice<VpwMainDevice>(ModuleName.VPWMain1.ToString());
  232. _putDownAfterDripClose = SC.GetValue<int>($"{Module}.PutDownAfterDripClose");
  233. _waitForWaferTime = SC.GetValue<int>($"{Module}.WaitForWaferTime") * 1000;
  234. _vpwMainEntity = Singleton<RouteManager>.Instance.GetModule<VpwMainEntity>(ModuleName.VPWMain1.ToString());
  235. return Runner.Start(Module, $"{Module} prepare");
  236. }
  237. /// <summary>
  238. /// 检验前置条件
  239. /// </summary>
  240. /// <returns></returns>
  241. private bool CheckPreCondition()
  242. {
  243. if (!_rotationAxis.IsSwitchOn)
  244. {
  245. NotifyError(eEvent.ERR_VPW,"rotaion is not switch on",-1);
  246. return false;
  247. }
  248. if (!_rotationAxis.IsHomed)
  249. {
  250. NotifyError(eEvent.ERR_VPW, "rotaion is not homed", -1);
  251. return false;
  252. }
  253. return true;
  254. }
  255. /// <summary>
  256. /// 重试
  257. /// </summary>
  258. /// <param name="step"></param>
  259. public RState Retry(int step)
  260. {
  261. if (_recipe == null)
  262. {
  263. NotifyError(eEvent.ERR_RINSE, "recipe is null", -1);
  264. return RState.Failed;
  265. }
  266. List<Enum> preStepIds = new List<Enum>();
  267. return Runner.Retry(PrepareStep.CheckPreCondition, preStepIds, Module, "Prepare Retry");
  268. }
  269. }
  270. }