VpwManualPrepareRoutine.cs 9.2 KB

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