using System; using Aitex.Core.Common.DeviceData; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using VirgoCommon; using VirgoRT.Devices; namespace VirgoRT.Modules.PMs { class RfPowerRoutine : PMRoutineBase, IRoutine { private enum RoutineStep { kRFPowerOn, kRFPowerOFF, MatchOn, End, }; private bool _enableBias; private readonly bool _ON; private double _rfPower; private double _rfPowerBias; private BiasRfMatchMode _matchMode; private double _matchC1; private double _matchC2; private double _rfPowerOnTime; public RfPowerRoutine(JetPM chamber, bool bON) : base(chamber) { Name = "RF Power"; _ON = bON; } public Result Start(params object[] objs) { if (!_chamber.IsFastPumpOpened) { Stop("Pump 阀没有打开"); return Result.FAIL; } //if (_chamber.TotalGasSetpoint <= 0) //{ // Stop("No gas flowing for RF power on"); // return Result.FAIL; //} Reset(); _enableBias = SC.GetValue($"{_chamber.Module}.BiasRf.EnableBiasRF"); if (_ON) { if (objs == null || objs.Length < 3) throw new ArgumentException("RF routine argument error"); _rfPower = Convert.ToDouble(objs[0]); _rfPowerBias = Convert.ToDouble(objs[1]); _rfPowerOnTime = Convert.ToDouble(objs[2]); _matchMode = Convert.ToInt32(objs[3]) == 1 ? BiasRfMatchMode.Preset : BiasRfMatchMode.Hold; _matchC1 = Convert.ToDouble(objs[4]); _matchC2 = Convert.ToDouble(objs[5]); } else { _rfPower = 0.0; _rfPowerBias = 0.0; _matchMode = BiasRfMatchMode.Preset; _matchC1 = 0.0; _matchC2 = 0.0; _rfPowerOnTime = 0.0; } return Result.RUN; } public Result Monitor() { try { if (_ON) { RFPowerOn((int)RoutineStep.kRFPowerOn, "RF Power On"); } else { RFPowerOFF((int)RoutineStep.kRFPowerOFF, "RF Power OFF"); } //MatchOn((int)RoutineStep.MatchOn, "Match On"); End((int)RoutineStep.End); } catch (RoutineBreakException) { return Result.RUN; } catch (RoutineFaildException) { return Result.FAIL; } catch (Exception ex) { Stop(ex.Message); return Result.FAIL; } return Result.DONE; } public void RFPowerOn(int id, string name) { Tuple ret = ExecuteAndWait(id, () => { if (_enableBias) Notify($"放电开始, 源射频设定值 {_rfPower}, 偏压射频设定值 {_rfPowerBias}"); else Notify($"放电开始, 源射频设定值 {_rfPower}"); if (Math.Abs(_rfPower) > 0.01 && Math.Abs(_rfPowerBias) > 0.01) { _chamber.GeneratorSetpower((float)_rfPower); _chamber.GeneratorBiasSetpower((float)_rfPowerBias); if (_matchMode == BiasRfMatchMode.Preset) { _chamber.GeneratorBiasSetMatchMode(true); Notify($"Bias RF Match C1设定值 {_matchC1}, Bias RF Match C2设定值 {_matchC2}"); _chamber.SetBiasMatchPosition((float)_matchC1, (float)_matchC2); } else if (_matchMode == BiasRfMatchMode.Hold) { _chamber.GeneratorBiasSetMatchMode(false); } return _chamber.GeneratorPowerOn(true) && _chamber.GeneratorBiasPowerOn(true); } else if (Math.Abs(_rfPower) < 0.01 && Math.Abs(_rfPowerBias) > 0.01) { if (_matchMode == BiasRfMatchMode.Preset) { _chamber.GeneratorBiasSetMatchMode(true); Notify($"Bias RF Match C1设定值 {_matchC1}, Bias RF Match C2设定值 {_matchC2}"); _chamber.SetBiasMatchPosition((float)_matchC1, (float)_matchC2); } else if (_matchMode == BiasRfMatchMode.Hold) { _chamber.GeneratorBiasSetMatchMode(false); } _chamber.GeneratorBiasSetpower((float)_rfPowerBias); return _chamber.GeneratorBiasPowerOn(true); } else if (Math.Abs(_rfPower) > 0.01 && Math.Abs(_rfPowerBias) < 0.01) { _chamber.GeneratorSetpower((float)_rfPower); return _chamber.GeneratorPowerOn(true); } else { Notify("放电结束"); return false; } }, () => { if (Elapsed >= _rfPowerOnTime) { Notify("放电结束"); _chamber.StopAllGases(); _chamber.SetValveOnOff(ValveType.PROCESS, false); _chamber.GeneratorPowerOn(false); _chamber.GeneratorBiasPowerOn(false); return true; } return false; }, _rfPowerOnTime * 1000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { _chamber.StopAllGases(); _chamber.SetValveOnOff(ValveType.PROCESS, false); _chamber.GeneratorPowerOn(false); _chamber.GeneratorBiasPowerOn(false); throw new RoutineFaildException(); } throw new RoutineBreakException(); } } public void RFPowerOFF(int id, string name) { Tuple ret = ExecuteAndWait(id, () => { Notify("放电停止"); if (!_enableBias) return _chamber.GeneratorPowerOn(false); return _chamber.GeneratorPowerOn(false) && _chamber.GeneratorBiasPowerOn(false); }, () => true, 2000); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { _chamber.StopAllGases(); _chamber.SetValveOnOff(ValveType.PROCESS, false); throw new RoutineFaildException(); } throw new RoutineBreakException(); } } public void MatchOn(int id, string name) { bool Func() { Notify($"Match C1设定值 {_matchC1}, Match C2设定值 {_matchC2}"); if (_chamber.SetMatchPosition((float)_matchC1, (float)_matchC2)) { return true; } return false; } bool? Check1() { return true; } Tuple ret = ExecuteAndWait(id, Func, Check1, 0); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } throw new RoutineBreakException(); } } public void BiasMatchOn(int id, string name) { bool Func() { Notify($"Bias RF Match C1设定值 {_matchC1}, Bias RF Match C2设定值 {_matchC2}"); if (_chamber.SetBiasMatchPosition((float)_matchC1, (float)_matchC2)) { return true; } return false; } bool? Check1() { return true; } Tuple ret = ExecuteAndWait(id, Func, Check1, 0); if (ret.Item1) { if (ret.Item2 == Result.FAIL) { throw new RoutineFaildException(); } throw new RoutineBreakException(); } } public override void Abort() { _chamber.GeneratorSetpower(0); _chamber.GeneratorBiasSetpower(0); _chamber.GeneratorPowerOn(false); _chamber.GeneratorBiasPowerOn(false); } } }