using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; 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 PunkHPX8_RT.Modules.VpwMain; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace PunkHPX8_RT.Modules.VpwCell { public class VpwManualPrepareRoutine : RoutineBase, IRoutine { private enum PrepareStep { CheckPreCondition, Purge, PurgeDelay, WaitPurge, RotationPositionOffset, WaitRotation, CloseDrip, Delay, WaitWafer, ChamberUp, CloseDrain, CheckLoopDO, End } #region 内部变量 /// /// recipe /// private VpwRecipe _recipe; /// /// 电机 /// private JetAxisBase _rotationAxis; /// /// 设备 /// private VpwCellDevice _vpwCellDevice; /// /// Main设备 /// private VpwMainDevice _mainDevice; /// /// VPW Entity /// private VpwMainEntity _vpwMainEntity; /// /// 延迟时间 /// private int _putDownAfterDripClose = 2000; /// /// 等待Wafer放入时间 /// private int _waitForWaferTime = 300000; #endregion /// /// 构造函数 /// /// public VpwManualPrepareRoutine(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) .DelayIf(PrepareStep.PurgeDelay, _recipe.PurgeEnable, 500) .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) .Wait(PrepareStep.WaitWafer,CheckWaferExsit,_waitForWaferTime) .Run(PrepareStep.ChamberUp,ChamberUp,CheckChamberClosed) .Run(PrepareStep.CloseDrain,_vpwCellDevice.DrainValveOff,_delay_1ms) .Run(PrepareStep.CheckLoopDO,CheckLoopDO,_delay_1ms) .End(PrepareStep.End,NullFun,_delay_1ms); return Runner.Status; } /// /// Purge routine /// /// private bool Purge() { if (_vpwMainEntity == null) { NotifyError(eEvent.ERR_VPW, "VPW Main not exist", -1); return false; } if (_vpwMainEntity.IsIdle) { return _vpwMainEntity.CheckToPostMessage(eEvent.ERR_VPW, Module, (int)VPWMainMsg.Purge); } else if (_vpwMainEntity.State == VPWMainState.Purgeing) { return true; } else { NotifyError(eEvent.ERR_VPW, $"State {_vpwMainEntity.State} cannot purge", -1); return false; } } /// /// 检验Purge执行是否结束 /// /// private bool CheckPurgeStatus() { return _vpwMainEntity.IsIdle; } /// /// 检验Purger执行是否出现异常 /// /// private bool CheckPurgeStopStatus() { return _vpwMainEntity.IsError; } /// /// 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() { // todo 临时注释,后面需要改回来 //return WaferManager.Instance.CheckHasWafer(Module, 0); return true; } /// /// 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; _vpwMainEntity = Singleton.Instance.GetModule(ModuleName.VPWMain1.ToString()); 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 true; } /// /// 重试 /// /// 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"); } } }