Browse Source

增加Adtec AMVG系列match

JET-YDB\JET-YANGDB 3 days ago
parent
commit
e8685130f6

+ 4 - 0
VirgoRT/Config/System.sccfg

@@ -233,6 +233,7 @@
 			<config default="192.168.10.21:502" name="IPAddress" nameView="IP Address" description="EFEM IP,default 127.0.0.1:502" max="" min="" paramter="" tag="" unit="" type="String" />
 			<config default="1" name="MatchMode" nameView="Match Mode" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 			<config default="false" name="EnableC1C2Position" nameView="Enable Source C1 C2 Position" description="" max="10" min="0" paramter="" tag="" unit="" type="Bool" />
+      <config default="0" name="AdTecSourceMatchModel" nameView="Source Match Model(0:default 1:AMVG)" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 			<!--<config default="10" name="MatchPositionC1" nameView="CycleCount" description="" max="100" min="0" paramter="" tag="" unit="" type="Double" />
       <config default="10" name="MatchPositionC2" nameView="CycleCount" description="" max="100" min="0" paramter="" tag="" unit="" type="Double" />-->
 		</configs>
@@ -275,6 +276,7 @@
 			<config default="127.0.0.1:502" name="IPAddress" nameView="IP Address" description="EFEM IP,default 127.0.0.1:502" max="" min="" paramter="" tag="" unit="" type="String" />
 			<config default="1" name="MatchMode" nameView="Match Mode" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 			<config default="false" name="EnableBiasC1C2Position" nameView="Enable Bias C1 C2 Position" description="" max="10" min="0" paramter="" tag="" unit="" type="Bool" />
+      <config default="0" name="AdTecBiasMatchModel" nameView="Bias Match Model(0:default 1:AMVG)" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 		</configs>
 		<configs name="MfcGas1" nameView="MFC Gas1" >
 			<config default="true" name="Enable" nameView="Enable" description="Enable gas 1 or not" tag="" unit="" type="Bool" />
@@ -617,6 +619,7 @@
 			<config default="127.0.0.1:502" name="IPAddress" nameView="IP Address" description="EFEM IP,default 127.0.0.1:502" max="" min="" paramter="" tag="" unit="" type="String" />
 			<config default="1" name="MatchMode" nameView="Match Mode" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 			<config default="false" name="EnableC1C2Position" nameView="Enable Source C1 C2 Position" description="" max="10" min="0" paramter="" tag="" unit="" type="Bool" />
+      <config default="0" name="AdTecSourceMatchModel" nameView="Source Match Model(0:default 1:AMVG)" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 			<!--<config default="10" name="MatchPositionC1" nameView="Match Position C1" description="" max="100" min="0" paramter="" tag="" unit="" type="Double" />
       <config default="10" name="MatchPositionC2" nameView="Match Position C2" description="" max="100" min="0" paramter="" tag="" unit="" type="Double" />-->
 		</configs>
@@ -658,6 +661,7 @@
 			<config default="192.168.10.22:502" name="IPAddress" nameView="IP Address" description="EFEM IP,default 127.0.0.1:502" max="" min="" paramter="" tag="" unit="" type="String" />
 			<config default="1" name="MatchMode" nameView="Match Mode" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 			<config default="false" name="EnableBiasC1C2Position" nameView="Enable Bias C1 C2 Position" description="" max="10" min="0" paramter="" tag="" unit="" type="Bool" />
+      <config default="0" name="AdTecBiasMatchModel" nameView="Bias Match Model(0:default 1:AMVG)" description="" max="10" min="0" paramter="" tag="" unit="" type="Integer" />
 		</configs>
 		<configs name="MfcGas1" nameView="MFC Gas1" >
 			<config default="true" name="Enable" nameView="Enable" description="Enable gas 1 or not" tag="" unit="" type="Bool" />

+ 402 - 0
VirgoRT/Devices/AdTecMatchAMVG.cs

@@ -0,0 +1,402 @@
+using System;
+using System.Collections;
+using System.Text.RegularExpressions;
+using Aitex.Core.Common.DeviceData;
+using Aitex.Core.RT.DataCenter;
+using Aitex.Core.RT.Event;
+using Aitex.Core.RT.IOCore;
+using Aitex.Core.RT.Log;
+using Aitex.Core.RT.OperationCenter;
+using Aitex.Core.RT.SCCore;
+using Aitex.Core.RT.Tolerance;
+using Aitex.Core.Util;
+using MECF.Framework.Common.Communications;
+using MECF.Framework.Common.DataCenter;
+using MECF.Framework.Common.Device.Bases;
+using MECF.Framework.Common.Equipment;
+using VirgoCommon;
+using VirgoRT.Modules;
+
+namespace VirgoRT.Devices
+{
+    static class AdTecMatchAMVGMessage
+    {
+        public const string PRESET = "G";
+        public const string AUTO = "L";
+        public const string MANUAL = "M";
+        public const string PRESET_MEM = "P";
+        public const string START_QUERY = "S3";
+        public const string STOP_QUERY = "SP";
+        public const string WRITE_POS = "$APGR";
+        public const string READ_POS = "$APRR";
+
+        public const string Read_VPPMUL = "R48";
+        public const string Read_VPPDIV = "R49";
+
+        public const string Read_LD_MIN = "R00";
+        public const string Read_LD_MAX = "R01";
+
+        public const string Read_PH_MIN = "R02";
+        public const string Read_PH_MAX = "R03";
+    }
+    class AdTecMatchAMVG : RfMatchBase
+    {
+        // ----------------------------Fields--------------------------
+        //
+        private readonly AsyncSerialPort _serial;
+        private const ushort S3_HEAD_LENGTH = 2;
+        private readonly DeviceTimer _timerQueryStatus = new DeviceTimer();
+        private int QUERY_INTERVAL = 1000;
+        private float VPP_MUL_R48 = 1;
+        private float VPP_DIV_R49 = 1;
+        private float LD_MIN = 0;
+        private float LD_MAX = 0;
+        private float PH_MIN = 0;
+        private float PH_MAX = 0;
+        //private int                      _scMatchPresetMode;
+        //private int                      _scMatchMode;
+        //private readonly SCConfigItem    _scMatchPositionC1;
+        //private readonly SCConfigItem    _scMatchPositionC2;
+        //private readonly bool            _scEnableC1C2Position;
+
+        // --------------------------Properties------------------------
+        //
+        [Subscription("MatchWorkMode")]
+        public EnumRfMatchTuneMode WorkMode { get; set; }
+        public float C1 { get; set; }
+        public float C2 { get; set; }
+
+        [Subscription("VPP")]
+        public ushort VPP { get; set; }
+
+        public override AITRfMatchData DeviceData
+        {
+            get
+            {
+                return new AITRfMatchData
+                {
+                };
+            }
+        }
+
+        // --------------------------Constructor-----------------------
+        //
+        public AdTecMatchAMVG(ModuleName mod, string name) : base(mod.ToString(), name)
+        {
+            string test = VirgoDevice.Match.ToString();
+
+            var portNum = SC.GetStringValue($"{mod}.{name}.Port");
+
+            //if (name == "Match")
+            //{
+            //    portNum = SC.GetStringValue($"{mod}.match.Port");
+            //}
+
+            _serial = new AsyncSerialPort(portNum, 9600, 8);
+
+            EV.PostInfoLog(Module, $"Get AdTec(AMVG) {name},{portNum}");
+
+
+
+            //_scMatchPresetMode    = SC.GetValue<int>($"{Module}.Rf.PresetMode");
+            //_scMatchMode          = SC.GetValue<int>($"{Module}.Rf.MatchMode");
+            //_scMatchPositionC1    = SC.GetConfigItem($"{Module}.Rf.MatchPositionC1");
+            //_scMatchPositionC2    = SC.GetConfigItem($"{Module}.Rf.MatchPositionC2");
+            //_scEnableC1C2Position = SC.GetValue<bool>($"{Module}.Rf.EnableC1C2Position");
+        }
+
+        ~AdTecMatchAMVG()
+        {
+            _serial?.Close();
+        }
+
+        public override bool Initialize()
+        {
+            base.Initialize();
+
+            if (_serial.Open())
+            {
+                _serial.OnDataChanged += SerialPortDataReceived;
+                _serial.OnErrorHappened += SerialPortErrorOccurred;
+            }
+            else
+            {
+                EV.PostAlarmLog(Module, "Match 串口无法打开");
+                return false;
+            }
+
+            DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
+            DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
+            DATA.Subscribe($"{Module}.{Name}.MatchProcessMode", () => ((int)WorkMode));
+
+            OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
+            {
+                return true;
+            });
+            OP.Subscribe($"{Module}.{Name}.SetC2", (func, args) =>
+            {
+                return true;
+            });
+
+            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC1}", (out string reason, int time, object[] param) =>
+            {
+                SetMatchPositionC1((float)Convert.ToDouble(param[0]), out reason);
+                return true;
+            });
+
+            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPositionC2}", (out string reason, int time, object[] param) =>
+            {
+                SetMatchPositionC2((float)Convert.ToDouble(param[0]), out reason);
+                return true;
+            });
+            OP.Subscribe($"{Module}.{Name}.SetMatchPositionC1AndC2", (out string reason, int time, object[] param) =>
+            {
+                var cValue = param[0].ToString().Split('_');
+                SetMatchPosition((float)Convert.ToDouble(cValue[0]), (float)Convert.ToDouble(cValue[1]), out reason);
+                return true;
+            });
+            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchPosition}", (out string reason, int time, object[] param) =>
+            {
+                SetMatchPosition((float)Convert.ToDouble(param[0]), (float)Convert.ToDouble(param[1]), out reason);
+                return true;
+            });
+
+            EV.PostInfoLog(Module, $"注册 {Name}的SetMatchProcessMode");
+            OP.Subscribe($"{Module}.{Name}.{AITRfOperation.SetMatchProcessMode}", (out string reason, int time, object[] param) =>
+            {
+                var mode = (string)param[0];
+                var modeValue = EnumRfMatchTuneMode.Auto.ToString();
+                if(!string.IsNullOrWhiteSpace(mode))
+                {
+                    LOG.Info($"SetMatchProcessMode {Module} {Name} mode={mode}");
+                    modeValue = mode == "Hold" ? EnumRfMatchTuneMode.Manual.ToString() : EnumRfMatchTuneMode.Auto.ToString();
+                }
+                SetMatchMode(modeValue, out reason);
+                return true;
+            });
+
+            _timerQueryStatus.Start(QUERY_INTERVAL);
+            SetWorkMode(EnumRfMatchTuneMode.Auto);
+            this.SendCmd(AdTecMatchAMVGMessage.START_QUERY);
+            return true;
+        }
+
+        public override void Monitor()
+        {
+            try
+            {
+                if (_timerQueryStatus.IsTimeout())
+                {
+                    this.SendCmd(AdTecMatchAMVGMessage.Read_VPPDIV);
+                    this.SendCmd(AdTecMatchAMVGMessage.Read_VPPMUL);
+                    this.SendCmd(AdTecMatchAMVGMessage.Read_LD_MAX);
+                    this.SendCmd(AdTecMatchAMVGMessage.Read_LD_MIN);
+                    this.SendCmd(AdTecMatchAMVGMessage.Read_PH_MAX);
+                    this.SendCmd(AdTecMatchAMVGMessage.Read_PH_MIN);
+
+                    _timerQueryStatus.Start(QUERY_INTERVAL);
+                }
+            }
+            catch (Exception ex)
+            {
+                LOG.Write(ex);
+            }
+        }
+
+        public override void Terminate()
+        {
+            this.SendCmd(AdTecMatchAMVGMessage.STOP_QUERY);
+        }
+
+        public override void Reset()
+        {
+            //SendCmd(AdTecMatchAMVGMessage.STOP_QUERY);
+        }
+
+        /// <summary>
+        ///
+        /// </summary>
+        /// <param name="c1,c2">百分比数字</param>
+        /// <param name="c2"></param>
+        public override void SetMatchPosition(float c1, float c2, out string reason)
+        {
+            LOG.Info($"SetMatchPosition {Module} {Name} c1={c1} c2={c2}");
+            base.SetMatchPosition(c1, c2, out reason);
+            //this.SetWorkMode(EnumRfMatchTuneMode.Auto);
+            this.SetPosition(c1, c2);
+        }
+
+        public override bool SetMatchMode(string mode, out string reason)
+        {
+            reason = string.Empty;
+            LOG.Info($"SetMatchMode {Module} {Name} mode={mode}");
+            if (mode == EnumRfMatchTuneMode.Manual.ToString())
+                SetWorkMode(EnumRfMatchTuneMode.Manual);
+            else
+                SetWorkMode(EnumRfMatchTuneMode.Auto);
+            return true;
+        }
+
+        public override void SetMatchPositionC1(float c1, out string reason)
+        {
+            LOG.Info($"SetMatchPositionC1 {Module} {Name} c1={c1} ");
+            base.SetMatchPositionC1(c1, out reason);
+            reason = string.Empty;
+            LoadPosition1 = c1;
+            ushort val1 = (ushort)(c1 * 10);
+
+            string cmd = AdTecMatchMessage.WRITE_POS + val1.ToString("X3");
+            this.SendCmd(cmd);
+        }
+
+        public override void SetMatchPositionC2(float c2, out string reason)
+        {
+            LOG.Info($"SetMatchPositionC2 {Module} {Name} c2={c2} ");
+            base.SetMatchPositionC2(c2, out reason);
+            reason = string.Empty;
+            LoadPosition2 = c2;
+            ushort val2 = (ushort)(c2 * 10);
+
+            string cmd = AdTecMatchMessage.WRITE_POS + val2.ToString("X3");
+            this.SendCmd(cmd);
+        }
+
+        public void SetPresetMode(RfMatchPresetMode mode)
+        {
+        }
+
+        // -----------------------Private Method-------------------------
+        //
+        private void SerialPortDataReceived(string strOrg)
+        {
+            if (string.IsNullOrWhiteSpace(strOrg))
+            {
+                EV.PostAlarmLog(Module, "收到 AdTec(AMVG) Match 数据为空");
+                return;
+            }
+
+            string[] sContent = strOrg.Split('\r');
+
+            foreach (var sItem in sContent)
+            {
+                string sItem1 = sItem.TrimStart('\n');
+
+                if (sItem1.Contains(AdTecMatchAMVGMessage.START_QUERY))
+                {
+                    // BYTE 3,4; bit 7
+                    string s0 = sItem1.Substring(2 + S3_HEAD_LENGTH, 2);
+                    ushort status0 = Convert.ToUInt16(s0, 16);
+                    byte[] a1 = BitConverter.GetBytes(status0);
+
+                    BitArray ba1 = new BitArray(a1);
+
+                    this.WorkMode = ba1[7] ? EnumRfMatchTuneMode.Manual : EnumRfMatchTuneMode.Auto;
+
+                    TuneMode1 = WorkMode;
+                    TuneMode2 = WorkMode;
+
+                    string sVpp = sItem1.Substring(42 + S3_HEAD_LENGTH - 1, 3);
+                    var tmpVpp = Convert.ToUInt16(sVpp, 16);
+                    if (VPP_DIV_R49 != 0)
+                    {
+                        tmpVpp = Convert.ToUInt16((tmpVpp * VPP_MUL_R48) / VPP_DIV_R49);
+                    }
+                    this.VPP = tmpVpp;
+
+                    string sLoad = sItem1.Substring(27 + S3_HEAD_LENGTH - 1, 3);
+                    string sPhase = sItem1.Substring(30 + S3_HEAD_LENGTH - 1, 3);
+
+                    var sLoad1 = Convert.ToUInt64(sLoad, 16);
+                    var sPhase2 = Convert.ToUInt64(sPhase, 16);
+
+                    if (LD_MAX - LD_MIN != 0)
+                    {
+                        sLoad1 = Convert.ToUInt64((sLoad1 - LD_MIN) * 100 / (LD_MAX - LD_MIN));
+                    }
+                    if (PH_MAX - PH_MIN != 0)
+                    {
+                        sPhase2 = Convert.ToUInt64((sPhase2 - PH_MIN) * 100 / (PH_MAX - PH_MIN));
+                    }
+                    this.TunePosition1 = sLoad1;
+                    this.TunePosition2 = sPhase2;
+                }
+                //else if (sItem1.Contains(AdTecMatchAMVGMessage.READ_POS))
+                //{
+                //    string s1 = sItem1.Substring(5);
+                //    string sLoad = s1.Substring(0, 3);
+                //    string sPhase = s1.Substring(3, 3);
+
+
+                //    this.TunePosition1 = Convert.ToUInt64(sLoad, 16) * 0.1f;
+                //    this.TunePosition2 = Convert.ToUInt64(sPhase, 16) * 0.1f;
+
+                //}
+                else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_VPPMUL))
+                {
+                    VPP_MUL_R48 = Convert.ToUInt16(sItem1.Substring(3), 16);
+                }
+                else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_VPPDIV))
+                {
+                    VPP_DIV_R49 = Convert.ToUInt16(sItem1.Substring(3), 16);
+                }
+                else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_LD_MIN))
+                {
+                    LD_MIN = Convert.ToUInt16(sItem1.Substring(3), 16);
+                }
+                else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_LD_MAX))
+                {
+                    LD_MAX = Convert.ToUInt16(sItem1.Substring(3), 16);
+                }
+                else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_PH_MIN))
+                {
+                    PH_MIN = Convert.ToUInt16(sItem1.Substring(3), 16);
+                }
+                else if (sItem1.Contains(AdTecMatchAMVGMessage.Read_PH_MAX))
+                {
+                    PH_MAX = Convert.ToUInt16(sItem1.Substring(3), 16);
+                }
+            }
+        }
+
+        private void SerialPortErrorOccurred(string str)
+        {
+            EV.PostAlarmLog(Module, $"AdTec(AMVG)  Match error [{str}]");
+        }
+
+        private void SendCmd(string str)
+        {
+            if (!str.Contains(AdTecMatchAMVGMessage.Read_VPPMUL) &&
+                !str.Contains(AdTecMatchAMVGMessage.Read_VPPDIV) &&
+                !str.Contains(AdTecMatchAMVGMessage.Read_LD_MIN) &&
+                !str.Contains(AdTecMatchAMVGMessage.Read_LD_MAX) &&
+                !str.Contains(AdTecMatchAMVGMessage.Read_PH_MIN) &&
+                !str.Contains(AdTecMatchAMVGMessage.Read_PH_MAX)
+                )
+            {
+                LOG.Info($"{Module} {Name} AdTec(AMVG) match send:{str}");
+            }
+            _serial?.Write(str + "\r");
+            //EV.PostInfoLog(Module.ToString(), $"Match send [{str}]");
+        }
+
+        private void SetPosition(float c1val, float c2val)
+        {
+            ushort val1 = (ushort)(c1val * 10);
+            ushort val2 = (ushort)(c2val * 10);
+
+            string cmd = AdTecMatchAMVGMessage.WRITE_POS + val1.ToString("X3") + val2.ToString("X3");
+            this.SendCmd(cmd);
+        }
+
+        private void SetWorkMode(EnumRfMatchTuneMode mode)
+        {
+            this.SendCmd(mode == EnumRfMatchTuneMode.Auto ? AdTecMatchAMVGMessage.AUTO :
+                mode == EnumRfMatchTuneMode.Manual ? AdTecMatchAMVGMessage.MANUAL : "");
+        }
+
+        private void SetPresetMemory(byte gear)
+        {
+            this.SendCmd(AdTecMatchAMVGMessage.PRESET_MEM + gear.ToString());
+        }
+    }
+}

+ 5 - 6
VirgoRT/Devices/AdTecRF.cs

@@ -1,7 +1,4 @@
-using System;
-using System.Collections;
-using System.Text.RegularExpressions;
-using Aitex.Core.Common.DeviceData;
+using Aitex.Core.Common.DeviceData;
 using Aitex.Core.RT.DataCenter;
 using Aitex.Core.RT.Event;
 using Aitex.Core.RT.IOCore;
@@ -14,8 +11,10 @@ using MECF.Framework.Common.Communications;
 using MECF.Framework.Common.DataCenter;
 using MECF.Framework.Common.Device.Bases;
 using MECF.Framework.Common.Equipment;
+using System;
+using System.Collections;
+using System.Text.RegularExpressions;
 using VirgoCommon;
-using VirgoRT.Modules;
 
 namespace VirgoRT.Devices
 {
@@ -187,7 +186,7 @@ namespace VirgoRT.Devices
                 PowerOnElapsedTime = PowerOnTime,
                 IsInterlockOk      = RFInterlock,
                 WorkMode           = (int)RfMode.ContinuousWaveMode,
-                DisplayName        ="Source RF",
+                DisplayName        =$"{(Name == "Rf"?"Source" : "Bias")} RF",
             };
 
         // --------------------------Constructor-----------------------

+ 16 - 2
VirgoRT/Devices/DeviceManager.cs

@@ -94,7 +94,14 @@ namespace VirgoRT.Instances
                 SC.GetValue<int>($"{mod}.match.CommunicationType") == (int)CommunicationType.RS232 &&
                 SC.GetValue<int>($"{mod}.match.MFG") == (int)MatchMFG.AdTec)
             {
-                AddCustomModuleDevice(new AdTecMatch(mod, "match"));
+                if (SC.GetValue<int>($"{mod}.match.AdTecSourceMatchModel") == 0)
+                {
+                    AddCustomModuleDevice(new AdTecMatch(mod, "match"));
+                }
+                else if (SC.GetValue<int>($"{mod}.match.AdTecSourceMatchModel") == 1)
+                {
+                    AddCustomModuleDevice(new AdTecMatchAMVG(mod, "match"));
+                }
             }
 
             if (SC.GetValue<bool>($"{mod}.match.EnableMatch") &&
@@ -127,7 +134,14 @@ namespace VirgoRT.Instances
                 SC.GetValue<int>($"{mod}.BiasMatch.CommunicationType") == (int)CommunicationType.RS232 &&
                 SC.GetValue<int>($"{mod}.BiasMatch.MFG") == (int)MatchMFG.AdTec)
             {
-                AddCustomModuleDevice(new AdTecMatch(mod, "BiasMatch"));
+                if (SC.GetValue<int>($"{mod}.BiasMatch.AdTecBiasMatchModel") == 0)
+                {
+                    AddCustomModuleDevice(new AdTecMatch(mod, "BiasMatch"));
+                }
+                else if (SC.GetValue<int>($"{mod}.BiasMatch.AdTecBiasMatchModel") == 1)
+                {
+                    AddCustomModuleDevice(new AdTecMatchAMVG(mod, "BiasMatch"));
+                }
             }
 
             if (SC.GetValue<int>($"{mod}.DryPump.CommunicationType") == (int)CommunicationType.RS232)

+ 24 - 1
VirgoRT/Devices/JetPM.cs

@@ -375,7 +375,14 @@ namespace VirgoRT.Devices
             if (SC.GetValue<int>($"{mod}.match.CommunicationType") == (int)CommunicationType.RS232 &&
                 SC.GetValue<int>($"{mod}.match.MFG") == (int)MatchMFG.AdTec)
             {
-                _Match = DEVICE.GetDevice<AdTecMatch>($"{Module}.{VirgoDevice.Match}");
+                if (SC.GetValue<int>($"{mod}.match.AdTecSourceMatchModel") == 0)
+                {
+                    _Match = DEVICE.GetDevice<AdTecMatch>($"{Module}.{VirgoDevice.Match}");
+                }
+                if (SC.GetValue<int>($"{mod}.match.AdTecSourceMatchModel") == 1)
+                {
+                    _Match = DEVICE.GetDevice<AdTecMatchAMVG>($"{Module}.{VirgoDevice.Match}");
+                }
             }
 
             if (SC.GetValue<bool>($"{mod}.match.EnableMatch") &&
@@ -404,6 +411,22 @@ namespace VirgoRT.Devices
                 }
             }
 
+            if (SC.GetValue<bool>($"{mod}.BiasMatch.EnableBiasMatch") &&
+              SC.GetValue<int>($"{mod}.BiasMatch.MFG") == (int)MatchMFG.AdTec)
+            {
+                if (SC.GetValue<int>($"{mod}.BiasMatch.CommunicationType") == (int)CommunicationType.RS232)
+                {
+                    if (SC.GetValue<int>($"{mod}.BiasMatch.AdTecBiasMatchModel") == 0)
+                    {
+                        _BiasMatch = DEVICE.GetDevice<AdTecMatch>($"{Module}.{VirgoDevice.BiasMatch}");
+                    }
+                    if (SC.GetValue<int>($"{mod}.BiasMatch.AdTecBiasMatchModel") == 1)
+                    {
+                        _BiasMatch = DEVICE.GetDevice<AdTecMatchAMVG>($"{Module}.{VirgoDevice.BiasMatch}");
+                    }
+                }
+            }
+
             // RS232 Dry pump, SKY
             if (SC.GetValue<int>($"{mod}.DryPump.CommunicationType") == (int)CommunicationType.RS232)
             {

+ 1 - 1
VirgoRT/Devices/RevtechMatch.cs

@@ -72,7 +72,7 @@ namespace VirgoRT.Devices
 
             DATA.Subscribe($"{Module}.{Name}.C1", () => TunePosition1);
             DATA.Subscribe($"{Module}.{Name}.C2", () => TunePosition2);
-            DATA.Subscribe($"{Module}.{Name}.MatchProcessMode", () => (int)WorkMode);
+            DATA.Subscribe($"{Module}.{Name}.MatchProcessMode", () => ((int)WorkMode));
 
             OP.Subscribe($"{Module}.{Name}.SetC1", (func, args) =>
             {

+ 28 - 0
VirgoRT/Modules/PMs/Recipe.cs

@@ -187,6 +187,28 @@ namespace VirgoRT.Modules
                         int rfPowerBias = (int)Convert.ToDouble(dic["BiasRf.SetPower"]);
                         dic.Add("BiasRf.SetPowerOnOff", rfPowerBias > 0 ? "true" : "false");
 
+                        if(SC.GetValue<bool>($"{chamberId}.BiasMatch.EnableBiasMatch"))
+                        {
+                            dic["BiasMatch.SetMatchProcessMode"] = dic["BiasRf.SetMatchProcessMode"];
+                            if (SC.GetValue<int>($"{chamberId}.BiasMatch.MFG") == (int)MatchMFG.Revtech)
+                            {
+                                dic["BiasMatch.SetMatchPositionC1"] = dic["BiasRf.SetMatchPositionC1"];
+                                dic["BiasMatch.SetMatchPositionC2"] = dic["BiasRf.SetMatchPositionC2"];
+                            }
+                            if (SC.GetValue<int>($"{chamberId}.BiasMatch.MFG") == (int)MatchMFG.AdTec)
+                            {
+                                if (SC.GetValue<int>($"{chamberId}.BiasMatch.AdTecBiasMatchModel") == 0)
+                                {
+                                    dic["BiasMatch.SetMatchPositionC1"] = dic["BiasRf.SetMatchPositionC1"];
+                                    dic["BiasMatch.SetMatchPositionC2"] = dic["BiasRf.SetMatchPositionC2"];
+                                }
+                                if (SC.GetValue<int>($"{chamberId}.BiasMatch.AdTecBiasMatchModel") == 1)
+                                {
+                                    dic["BiasMatch.SetMatchPositionC1AndC2"] = dic["BiasRf.SetMatchPositionC1"] + "_" + dic["BiasRf.SetMatchPositionC2"];
+                                }  
+                            }
+                        }
+
                         // RS232 AdTec match
                         if (SC.GetValue<int>($"{chamberId}.match.CommunicationType") == (int)CommunicationType.RS232 &&
                             SC.GetValue<int>($"{chamberId}.match.MFG") == (int)MatchMFG.AdTec)
@@ -200,6 +222,12 @@ namespace VirgoRT.Modules
 
                             dic["match.SetMatchPositionC2"] = dic["BiasRf.SetMatchPositionC2"];
                             dic.Remove("BiasRf.SetMatchPositionC2");
+                            if (SC.GetValue<int>($"{chamberId}.match.AdTecSourceMatchModel") == 1)
+                            {
+                                dic["match.SetMatchPositionC1AndC2"] = dic["match.SetMatchPositionC1"] + "_" + dic["match.SetMatchPositionC2"];
+                                dic.Remove("match.SetMatchPositionC1");
+                                dic.Remove("match.SetMatchPositionC2");
+                            }
                         }
 
                     }

+ 1 - 1
VirgoRT/Properties/AssemblyInfo.cs

@@ -51,5 +51,5 @@ using System.Windows;
 // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
 // 方法是按如下所示使用“*”: :
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.0.8")]
+[assembly: AssemblyVersion("2.0.0.9")]
 //[assembly: AssemblyFileVersion("1.0.4")]

+ 1 - 0
VirgoRT/VirgoRT.csproj

@@ -89,6 +89,7 @@
     <Compile Include="Backends\IOMonitorView.xaml.cs">
       <DependentUpon>IOMonitorView.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Devices\AdTecMatchAMVG.cs" />
     <Compile Include="Devices\AdTecRF.cs" />
     <Compile Include="Devices\CometRF.cs" />
     <Compile Include="Devices\ComRevtechMatch.cs" />

+ 1 - 1
VirgoUI/Models/PMs/PmOverviewViewModel.cs

@@ -1198,7 +1198,7 @@ namespace VirgoUI.Client.Models.PMs
         {
             get
             {
-                return RfBias != null && RfBias.IsRfOn && RfBias.IsMatchOn;
+                return RfBias != null && RfBias.IsRfOn && (RfBias.IsMatchOn || RfBias.ForwardPower > 0);
             }
         }
 

+ 1 - 1
VirgoUI/Properties/AssemblyInfo.cs

@@ -51,5 +51,5 @@ using System.Windows;
 // You can specify all the values or you can default the Build and Revision Numbers 
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("2.0.0.8")]
+[assembly: AssemblyVersion("2.0.0.9")]
 //[assembly: AssemblyFileVersion("1.0.0.0")]