using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using MECF.Framework.Common.Equipment; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using MECF.Framework.Common.SubstrateTrackings; using PunkHPX8_Core; using PunkHPX8_RT.Devices.AXIS; using PunkHPX8_RT.Devices.VpwCell; using PunkHPX8_RT.Devices.VpwMain; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Modules.VpwCell { public class VpwPrepareRoutine : RoutineBase, IRoutine { private enum PrepareStep { CheckPreCondition, Purge, WaitPurge, RotationPositionOffset, WaitRotation, CloseDrip, Delay, End } #region 内部变量 /// /// recipe /// private VpwRecipe _recipe; /// /// 电机 /// private JetAxisBase _rotationAxis; /// /// 设备 /// private VpwCellDevice _vpwCellDevice; /// /// 延迟时间 /// private int _putDownAfterDripClose = 2000; /// /// 等待Wafer放入时间 /// private int _waitForWaferTime = 300000; /// /// Main设备 /// private VpwMainDevice _mainDevice; #endregion /// /// 构造函数 /// /// public VpwPrepareRoutine(string module) : base(module) { } /// /// 中止 /// public void Abort() { Runner.Stop("Manual abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.Run(PrepareStep.CheckPreCondition,CheckPreCondition,_delay_1ms) .RunIf(PrepareStep.Purge,_recipe.PurgeEnable,Purge,_delay_1ms) .WaitWithStopConditionIf(PrepareStep.WaitPurge,_recipe.PurgeEnable,CheckPurgeStatus,CheckPurgeStopStatus) .Run(PrepareStep.RotationPositionOffset,RotationPositionOffset,_delay_1ms) .WaitWithStopCondition(PrepareStep.WaitRotation,CheckRotationStatus,CheckRotationStopStatus) .Run(PrepareStep.CloseDrip,()=>_vpwCellDevice.FlowDripOff(),_delay_1ms) .Delay(PrepareStep.Delay,_putDownAfterDripClose) .End(PrepareStep.End,NullFun,_delay_1ms); return Runner.Status; } /// /// Purge routine /// /// private bool Purge() { return true; } /// /// 检验Purge执行是否结束 /// /// private bool CheckPurgeStatus() { return true; } /// /// 检验Purger执行是否出现异常 /// /// private bool CheckPurgeStopStatus() { return false; } /// /// Position运行至offset /// /// private bool RotationPositionOffset() { bool result= _rotationAxis.PositionStation("ChuckPlaceOffset"); if (!result) { NotifyError(eEvent.ERR_VPW, "rotation start position to ChuckPlaceOffset failed", -1); } return result; } /// /// 检验电机是否完成运动 /// /// private bool CheckRotationStatus() { return _rotationAxis.Status == RState.End; } /// /// 检验电机运动是否出现异常 /// /// private bool CheckRotationStopStatus() { bool result= _rotationAxis.Status == RState.Failed; if (result) { NotifyError(eEvent.ERR_VPW, "rotation position to ChuckPlaceOffset failed", -1); } return result; } /// /// 检验是否存在Wafer /// /// private bool CheckWaferExsit() { return WaferManager.Instance.CheckHasWafer(Module, 0); } /// /// chamber up /// /// private bool ChamberUp() { bool result=_mainDevice.ChamberUp(); if (!result) { NotifyError(eEvent.ERR_VPW, "chamber up failed", -1); } return result; } /// /// 检验Chamber是否关闭 /// /// private bool CheckChamberClosed() { return _mainDevice.CommonData.ChamberClosed && !_mainDevice.CommonData.ChamberOpened; } /// /// Check LoopDO数值 /// /// private bool CheckLoopDO() { double loopDoValue = _vpwCellDevice.LoopDOValue; bool result = loopDoValue < _recipe.DiwLoopDoSet; if (!result) { NotifyError(eEvent.ERR_VPW, $"LoopDO value {loopDoValue} is less than {_recipe.DiwLoopDoSet}", -1); } return result; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _recipe=(VpwRecipe)objs[0]; _rotationAxis = DEVICE.GetDevice($"{Module}.Rotation"); _vpwCellDevice = DEVICE.GetDevice(Module); _mainDevice = DEVICE.GetDevice(ModuleName.VPWMain1.ToString()); _putDownAfterDripClose = SC.GetValue($"{Module}.PutDownAfterDripClose"); _waitForWaferTime = SC.GetValue($"{Module}.WaitForWaferTime") * 1000; return Runner.Start(Module, $"{Module} prepare"); } /// /// 检验前置条件 /// /// private bool CheckPreCondition() { if (!_rotationAxis.IsSwitchOn) { NotifyError(eEvent.ERR_VPW,"rotaion is not switch on",-1); return false; } if (!_rotationAxis.IsHomed) { NotifyError(eEvent.ERR_VPW, "rotaion is not homed", -1); return false; } return false; } /// /// 重试 /// /// public RState Retry(int step) { if (_recipe == null) { NotifyError(eEvent.ERR_RINSE, "recipe is null", -1); return RState.Failed; } List preStepIds = new List(); return Runner.Retry(PrepareStep.CheckPreCondition, preStepIds, Module, "Prepare Retry"); } } }