using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.Routine; using Aitex.Core.Util; using CyberX8_Core; using CyberX8_RT.Devices.Metal; using CyberX8_RT.Modules.Metal; using MECF.Framework.Common.CommonData; using MECF.Framework.Common.CommonData.Metal; using MECF.Framework.Common.CommonData.PowerSupplier; using MECF.Framework.Common.CommonData.SRD; using MECF.Framework.Common.Device.PowerSupplier; using MECF.Framework.Common.RecipeCenter; using MECF.Framework.Common.Routine; using MECF.Framework.Common.Utilities; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace CyberX8_RT.Modules.Metal { public class StandardHotRunRecipeRoutine : RoutineBase, IRoutine { private enum RecipeStep { LoopStart, WaferHolderClampOn, RunRecipe, RunRecipeWait, WaferHolderUnclampOn, LoopEnd, End } #region 常量 private const int ALL_DAY_MILLOSECONDS = 24 * 60 * 60 * 1000; #endregion #region 内部变量 /// /// recipe /// private DepRecipe _recipe; /// /// cycle次数 /// private int _cycle; /// /// 当前完成的Cycle次数 /// private int _currentCycle; /// /// 单面 /// private string _side; /// /// Metal设备 /// private StandardHotMetalDevice _device; /// /// RunRecipe routine /// private ReservoirRunRecipeRoutine _runRecipeRoutine; #endregion #region 属性 /// /// A面电量 /// public double AnodeAUsage { get { return _runRecipeRoutine.AnodeAUsage; } } /// /// B面电量 /// public double AnodeBUsage { get { return _runRecipeRoutine.AnodeBUsage; } } /// /// LotTrack数据 /// public List MetalLotTrackDatas { get { return _runRecipeRoutine.MetalLotTrackDatas; } } /// /// LotTrack文件头数据 /// public LotTrackFileHeaderCommonData MetalLotTrackHeaderDatas { get { return _runRecipeRoutine.MetalLotTrackHeaderDatas; } } #endregion /// /// 构造函数 /// /// public StandardHotRunRecipeRoutine(string module) : base(module) { _runRecipeRoutine = new ReservoirRunRecipeRoutine(module); } /// /// 中止 /// public void Abort() { _runRecipeRoutine.Abort(); Runner.Stop("Manual Abort"); } /// /// 监控 /// /// public RState Monitor() { Runner.LoopStart(RecipeStep.LoopStart, "Loop Start Cycle StandardHotRunRecipeRoutine", _cycle, NullFun, _delay_1ms) .LoopRun(RecipeStep.WaferHolderClampOn, () => _device.WaferHolderClampOn("", null), () => _device.MetalDeviceData.WaferHolderClamp, _delay_1s) .LoopRun(RecipeStep.RunRecipe, () => _runRecipeRoutine.Start(new object[] { _recipe, _side }) == RState.Running, _delay_1ms) .LoopRunWithStopStatus(RecipeStep.RunRecipeWait, () => CommonFunction.CheckRoutineEndState(_runRecipeRoutine), CheckRunRecipeStopStatus, ALL_DAY_MILLOSECONDS) .LoopRun(RecipeStep.WaferHolderUnclampOn, () => _device.WaferHolderClampOff("", null), () => !_device.MetalDeviceData.WaferHolderClamp, _delay_1s) .LoopEnd(RecipeStep.LoopEnd, UpdateCycleCount, _delay_1ms) .End(RecipeStep.End, NullFun, _delay_1ms); return Runner.Status; } /// /// 统计完成的Cycle次数 /// /// private bool UpdateCycleCount() { _currentCycle += 1; return true; } /// /// 获取当前Cycle次数 /// /// public int GetCurrentCycle() { return _currentCycle; } /// /// 启动 /// /// /// public RState Start(params object[] objs) { _recipe = (DepRecipe)objs[0]; if (objs.Length > 1) { _side = objs[1].ToString(); } if (objs.Length > 2) { _cycle = (int)objs[2]; } _device = DEVICE.GetDevice(Module); if (!CheckPreCondition()) { return RState.Failed; } _currentCycle = 0; _runRecipeRoutine.clearLotTrack();//清除loaTrack里面的历史数据 _runRecipeRoutine.resetMetalUsage();//清除usage历史数据 return Runner.Start(Module, "Start run recipe"); } /// /// 检验前置条件 /// /// private bool CheckPreCondition() { if (_recipe == null) { LOG.WriteLog(eEvent.ERR_METAL, Module, "Recipe is null"); return false; } if (_recipe.CurrentRampProfileSteps.Count == 0) { LOG.WriteLog(eEvent.ERR_METAL, Module, "Recipe RampProfileSteps count is 0"); return false; } MetalEntity metalEntity = Singleton.Instance.GetModule(Module); if (metalEntity != null && metalEntity.WaferHolderInfo == null) { LOG.WriteLog(eEvent.ERR_METAL, Module, $"there is no waferShuttle in {Module}"); return false; } return true; } /// /// RunRecipe停止状态 /// /// public bool CheckRunRecipeStopStatus() { bool result = CommonFunction.CheckRoutineStopState(_runRecipeRoutine); if (result) { AddLotTrackData(); if (_device.SideAPowerSupplier != null) { _device.SideAPowerSupplier.DisableOperation("", null); } if (_device.SideBPowerSupplier != null) { _device.SideBPowerSupplier.DisableOperation("", null); } } return result; } /// /// 获取Lot Track数据 /// /// public void AddLotTrackData() { _runRecipeRoutine.AddLotTrackData(); } } }