瀏覽代碼

Recipe 添加bias step ramp设值功能

lixiang 1 年之前
父節點
當前提交
a2426eb90b

+ 8 - 11
Venus/Venus_Core/ProcessUnitDefine.cs

@@ -20,13 +20,7 @@ namespace Venus_Core
     ///     配置文件里面没有列出的工艺单元, 表明本机台不支持此Recipe, 并报警提示用户
     /// </summary>
 
-    public enum Suspect
-    {
-        Origin,
-        Position1,
-        Position2,
-        Position3
-    }
+    
     public enum VenusUnits
     {
         PressureByPressureModeUnit,
@@ -68,6 +62,7 @@ namespace Venus_Core
     {
        
     }
+   
     public partial class PressureByPressureModeUnit : ProcessUnitBase
     {
         public string UnitName { get; set; } = "PressureModeUnit";
@@ -126,8 +121,8 @@ namespace Venus_Core
             get { return m_EnableRamp;}
             set { m_EnableRamp = value; }
         }       
-        public int StartPower { get; set; }
-        public int TargetPower { get; set; }       
+        //public int StartPower { get; set; }
+        public int TargetRFPower { get; set; }       
     }
 
 
@@ -148,8 +143,10 @@ namespace Venus_Core
         public int PulseRateFreq { get; set; }
         public int PulseDutyCycle { get; set; }
         [IsCanConfigIgnore]
-        public bool EnableRamp { get; set; }    
-        public int StartBiasRFPower { get; set; } 
+        public bool EnableRamp { get; set; }
+        [JsonConverter(typeof(StringEnumConverter))]
+        public TargetMode TargetMode { get; set; }
+        //public int StartBiasRFPower { get; set; } 
         public int TargetBiasRFPower { get; set; }            
     }
 

+ 32 - 93
Venus/Venus_Core/Recipe.cs

@@ -47,7 +47,18 @@ namespace Venus_Core
         Pressure,
         Valve
     }
-
+    public enum Suspect
+    {
+        Origin,
+        Position1,
+        Position2,
+        Position3
+    }
+    public enum TargetMode
+    {
+        Step,
+        Cycle
+    }
     public class RecipeHead : INotifyPropertyChanged
     {
         private string m_name;
@@ -364,6 +375,26 @@ namespace Venus_Core
 
             return RState.Running;
         }
+        public RState Start(int steps,int currentstep)
+        {
+            starter(this);
+
+            foreach (var unit in lstUnit)
+            {
+                var processUnit = unit as ProcessUnitBase;
+                if (processUnit != null)
+                {
+                    var state = processUnit.Start(this);
+                    if (state != RState.Running)
+                        return state;
+                }
+                else
+                    return RState.Failed;
+
+            }
+
+            return RState.Running;
+        }
         public RState Run()
         {
             if (checker(this) == RState.End)
@@ -460,28 +491,13 @@ namespace Venus_Core
             foreach (var step in recipe.Steps)
             {
                 ObservableCollection<ProcessUnitBase> unit = new ObservableCollection<ProcessUnitBase>();
-                //int count = step.LstUnit.Count / 2;
-                //for (int i = 0; i < count; i++)
-                //{
-                //    Type t = Type.GetType(step.LstUnit[i].ToString());
-                //    //unit.Add(JsonConvert.DeserializeObject<t>(step.LstUnit[i+count].ToString()));
-                //    unit.Add(JsonConvert.DeserializeObject<ProcessUnitBase>(step.LstUnit[i + count].ToString()));
-
-                //}
-                //var item = step.LstUnit[0];
 
                 for (int i = 0; i < step.LstUnit.Count; i++)
                 {
-                    //object item=step.LstUnit[i];
-                    //step.LstUnit[i].
                     string value = step.LstUnit[i].ToString();
                     string[] striparr = value.Split(new string[] { "\r\n" }, StringSplitOptions.None);
                     string item1 = striparr[1].Remove(0, 15);
                     string item2 = item1.Remove(item1.Length - 2, 2);
-                    //var item= value.Substring(value.IndexOf("UnitName"));
-
-                    //Type t = Type.GetType(value);
-
 
                     switch (item2)
                     {
@@ -514,8 +530,6 @@ namespace Venus_Core
                         case "GasUnit":
                             unit.Add(JsonConvert.DeserializeObject<Kepler2200GasControlUnit>(step.LstUnit[i].ToString()));
                             break;
-
-
                     }
                 }
                 step.LstUnit.Clear();
@@ -523,8 +537,6 @@ namespace Venus_Core
                 {
                     step.LstUnit.Add(x);
                 });
-
-
             }
             return recipe;
         }
@@ -595,79 +607,6 @@ namespace Venus_Core
             recipe.Steps = new ObservableCollection<RecipeStep>();
             RecipeStep recipeStep = new RecipeStep();
             recipeStep.LstUnit = GetAllUnits(currentChamber,recipeType);
-            //switch (currentChamber)
-            //{
-            //    case JetChamber.Venus:
-            //        foreach (var item in Enum.GetValues(typeof(VenusUnits)))
-            //        {
-            //            Type t = Type.GetType($"Venus_Core.{item.ToString()}");
-            //            var obj = System.Activator.CreateInstance(t);
-            //            recipeStep.LstUnit.Add(obj);
-            //        }
-            //        break;
-
-            //    case JetChamber.Kepler2300:
-            //        foreach (var item in Enum.GetValues(typeof(Kepler2300Uints)))
-            //        {
-            //            Type t = Type.GetType($"Venus_Core.{item.ToString()}");
-            //            var obj = System.Activator.CreateInstance(t);
-            //            recipeStep.LstUnit.Add(obj);
-            //        }
-            //        break;
-            //    case JetChamber.Kepler2200A:
-            //        foreach (var item in Enum.GetValues(typeof(Kepler2200AUnits)))
-            //        {
-            //            Type t = Type.GetType($"Venus_Core.{item.ToString()}");
-            //            var obj = System.Activator.CreateInstance(t);
-            //            recipeStep.LstUnit.Add(obj);
-            //        }
-            //        break;
-                    //case JetChamber.Venus:
-                    //    recipe.Steps.Add(new RecipeStep()
-                    //    {
-                    //        //StepNo = 1,
-                    //        LstUnit = new ObservableCollection<Object>()
-                    //       {
-                    //        new PressureByPressureModeUnit(),
-                    //        new TCPUnit(),
-                    //        new BiasUnit(),
-                    //        new GasControlUnit(),
-                    //        new ESCHVUnit(),
-                    //        new ProcessKitUnit()
-                    //        }
-                    //    });
-                    //    break;
-                    //case JetChamber.Kepler2300:
-                    //    recipe.Steps.Add(new RecipeStep()
-                    //    {
-                    //        //StepNo = 1,
-                    //        LstUnit = new ObservableCollection<Object>()
-                    //       {
-                    //        new PressureByPressureModeUnit(),
-                    //        new TCPUnit(),
-                    //        new BiasUnit(),
-                    //        new GasControlUnit(),
-                    //        new ProcessKitUnit()
-                    //        }
-                    //    });
-                    //    break;
-
-                    //case JetChamber.Kepler2200A:
-                    //    recipe.Steps.Add(new RecipeStep()
-                    //    {
-                    //        //StepNo = 1,
-
-
-                    //        LstUnit = new ObservableCollection<Object>()
-                    //       {
-                    //    new Kepler2200GasControlUnit(),
-                    //    new HeaterUnit(),
-                    //    new Kepler2200RFUnit()
-                    //        }
-                    //    });
-
-                    //    break;
-            //}
             recipe.Steps.Add(recipeStep);
 
             var recipeString = JsonConvert.SerializeObject(recipe);

+ 3 - 3
Venus/Venus_MainPages/Views/OverKepler2200AView.xaml

@@ -613,7 +613,7 @@
             </ctrls:FlowPipe>-->
             <!--<ctrls:FlowPipe   Height="8"  Width="17"  Canvas.Left="1055"  Canvas.Top="659" RotateTransformValue="90" IsFlowing="{Binding PVHe2ValveIsOpen}"/>-->
             <!--<ctrls:FlowPipe   Height="8"  Width="208" Canvas.Left="1057"  Canvas.Top="680" IsFlowing="{Binding PVHe2ValveIsOpen}"/>-->
-            <ctrls:FlowPipe   Height="8"  Width="20" Canvas.Left="1266"  Canvas.Top="682" RotateTransformValue="90">
+            <!--<ctrls:FlowPipe   Height="8"  Width="20" Canvas.Left="1266"  Canvas.Top="682" RotateTransformValue="90">
                 <ctrls:FlowPipe.IsFlowing>
                     <MultiBinding Converter="{StaticResource toBoolMultiValueConverter2}">
                         <Binding Path="SoftPumpValveIsOpen"/>
@@ -623,12 +623,12 @@
 
                     </MultiBinding>
                 </ctrls:FlowPipe.IsFlowing>
-            </ctrls:FlowPipe>
+            </ctrls:FlowPipe>-->
             <ctrls:FlowPipe   Height="8"  Width="40" Canvas.Left="1265"  Canvas.Top="658" />
             <ctrls:FlowPipe   Height="8"  Width="192" Canvas.Left="1266"  Canvas.Top="446" RotateTransformValue="90" IsFlowing="{Binding TurboPumpPumpingValveIsOpen}">
 
             </ctrls:FlowPipe>
-            <ctrls:FlowPipe   Height="8"  Width="45" Canvas.Left="1266"  Canvas.Top="638" RotateTransformValue="90" >
+            <ctrls:FlowPipe   Height="8"  Width="65" Canvas.Left="1266"  Canvas.Top="638" RotateTransformValue="90" >
                 <ctrls:FlowPipe.IsFlowing>
                     <MultiBinding Converter="{StaticResource toBoolMultiValueConverter2}">
                         <Binding Path="SoftPumpValveIsOpen"/>

+ 3 - 3
Venus/Venus_RT/Devices/JetKepler2300PM.cs

@@ -459,9 +459,9 @@ namespace Venus_RT.Devices
             _foreline_interlock_pressure = SC.GetValue<double>($"{Module}.ForelineInterlockPressure");
 
 
-            DATA.Subscribe($"{Module}.ChillerInnerTemp", () => _chillerInnerTemp,SubscriptionAttribute.FLAG.IgnoreSaveDB);
-            DATA.Subscribe($"{Module}.ChillerOuterTemp", () => _chillerOuterTemp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
-            DATA.Subscribe($"{Module}.ChillerTopTemp",   () => _chillerTopTemp, SubscriptionAttribute.FLAG.IgnoreSaveDB);
+            DATA.Subscribe($"{Module}.ChillerInnerTemp", () => _chillerInnerTemp);
+            DATA.Subscribe($"{Module}.ChillerOuterTemp", () => _chillerOuterTemp);
+            DATA.Subscribe($"{Module}.ChillerTopTemp",   () => _chillerTopTemp);
 
             //DATA.Subscribe($"{Module}.InnerChiller.IsRunning", () => innerChillerIsRunning);
             //DATA.Subscribe($"{Module}.OuterChiller.IsRunning", () => outerChillerIsRunning);

+ 70 - 56
Venus/Venus_RT/Modules/PMs/PMProcessRoutine.cs

@@ -11,9 +11,6 @@ using Venus_Core;
 using System.Diagnostics;
 using MECF.Framework.Common.DBCore;
 using Venus_RT.FAs;
-using MECF.Framework.Common.RecipeCenter;
-using Venus_Unity;
-using System.Threading.Tasks;
 
 namespace Venus_RT.Modules.PMs
 {
@@ -41,7 +38,7 @@ namespace Venus_RT.Modules.PMs
 
         string Guidall;
 
-        int Timeall;
+        //int Timeall;
         private Stopwatch Processtime = new Stopwatch();
         private readonly PumpDownRoutine _pumpDownRoutine;
         private readonly ProcessHelper _processHelper;
@@ -108,29 +105,27 @@ namespace Venus_RT.Modules.PMs
             _pumpDownRoutine = pdRoutine;
             _processHelper = new ProcessHelper(chamber);
             _faCallback = new RecipeFACallback();
-            
+
             _jetChamber = (JetChamber)SC.GetValue<int>($"{chamber.Module}.ChamberType");
         }
 
         private bool AssignFuns(Recipe recipe)
         {
-            foreach(var step in recipe.Steps)
+            foreach (var step in recipe.Steps)
             {
                 if (_processHelper.LoadStepFuns(step) == false)
 
                     return false;
 
-                foreach(ProcessUnitBase unit in step.LstUnit)
+                foreach (ProcessUnitBase unit in step.LstUnit)
                 {
                     if (_processHelper.LoadMethods(unit) == false)
                     {
                         Stop($"Cannot find the process routine for unit:{unit.GetType()}");
                         return false;
-                    }                      
+                    }
                 }
             }
-
-            
             return true;
         }
 
@@ -161,10 +156,10 @@ namespace Venus_RT.Modules.PMs
             string recipeName = (string)objs[0];
             currentRecipeResult = new RecipeResult();
             currentRecipeResult.RecipeName = recipeName;
-            
+
             string recipeContent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipeName, false);
             Recipe recipe = Recipe.Load(recipeContent);
-            currentRecipeResult.RecipeStepCount=recipe.Steps.Count;
+            currentRecipeResult.RecipeStepCount = recipe.Steps.Count;
             if (recipe == null)
             {
                 Stop($"Load Recipe:{recipeName} failed");
@@ -177,11 +172,11 @@ namespace Venus_RT.Modules.PMs
             switch (recipe.Header.Type)
             {
                 case RecipeType.Process:
-                   if(_recipeRunningMode == 1 && recipe.Header.ChuckRecipe != null && !string.IsNullOrEmpty(recipe.Header.ChuckRecipe))
+                    if (_recipeRunningMode == 1 && recipe.Header.ChuckRecipe != null && !string.IsNullOrEmpty(recipe.Header.ChuckRecipe))
                     {
-                        string chuckcontent= RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.ChuckRecipe, false);
+                        string chuckcontent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.ChuckRecipe, false);
                         var chuckRecipe = Recipe.Load(chuckcontent);
-                        if(chuckRecipe != null)
+                        if (chuckRecipe != null)
                         {
                             ChuckRecipeName = recipe.Header.ChuckRecipe;
                             _qeRecipes.Enqueue(chuckRecipe);
@@ -189,16 +184,16 @@ namespace Venus_RT.Modules.PMs
                     }
 
                     ProcessRecipeHead = recipe.Header;
-                   
+
                     ProcessRecipeName = recipeName;
                     _qeRecipes.Enqueue(recipe);
 
-                    if(_recipeRunningMode == 1 && recipe.Header.DechuckRecipe != null && !string.IsNullOrEmpty(recipe.Header.DechuckRecipe))
+                    if (_recipeRunningMode == 1 && recipe.Header.DechuckRecipe != null && !string.IsNullOrEmpty(recipe.Header.DechuckRecipe))
                     {
 
                         string dechuckcontent = RecipeFileManager.Instance.LoadRecipe(_chamber.Name, recipe.Header.DechuckRecipe, false);
                         var dechuckRecipe = Recipe.Load(dechuckcontent);
-                        if(dechuckRecipe != null)
+                        if (dechuckRecipe != null)
                         {
                             DechuckRecipeName = recipe.Header.DechuckRecipe;
                             _qeRecipes.Enqueue(dechuckRecipe);
@@ -220,7 +215,7 @@ namespace Venus_RT.Modules.PMs
                     break;
             }
 
-            foreach(Recipe rcp in _qeRecipes)
+            foreach (Recipe rcp in _qeRecipes)
             {
                 if (AssignFuns(rcp) == false)
                 {
@@ -234,6 +229,10 @@ namespace Venus_RT.Modules.PMs
             _loopStartStep = 0;
             _loopCounter = 0;
 
+            _processHelper.isLoop = false;
+            _processHelper.loopsteps = 0;
+            _processHelper.currentStepIndex = 0;
+
             _tolerance = SC.GetValue<double>($"System.MaxTemperatureToleranceToTarget");
             _OffsetTemp = SC.GetValue<double>($"{Module}.Chiller.ChillerTemperatureOffset");
             _faCallback.RecipeStart(_chamber.Module.ToString(), recipeName);
@@ -242,10 +241,10 @@ namespace Venus_RT.Modules.PMs
         }
         public RState Monitor()
         {
-            Runner.Run(ProcessStep.kPreparePressure,   PreparePressure,    IsPressureReady)
-                .Run(ProcessStep.kPrepareTemperature,  PrepareTemp,        IsTempReady)
-                .Run(ProcessStep.kRunRecipes,          StartNewRecipe,     RunRecipes,5*60*60*1000)
-                .End(ProcessStep.kEnd,                 ProcessDone,        _delay_1s);
+            Runner.Run(ProcessStep.kPreparePressure, PreparePressure, IsPressureReady)
+                .Run(ProcessStep.kPrepareTemperature, PrepareTemp, IsTempReady)
+                .Run(ProcessStep.kRunRecipes, StartNewRecipe, RunRecipes, 5 * 60 * 60 * 1000)
+                .End(ProcessStep.kEnd, ProcessDone, _delay_1s);
 
             return Runner.Status;
         }
@@ -269,12 +268,12 @@ namespace Venus_RT.Modules.PMs
             //    return true;          
 
             var status = _pumpDownRoutine.Monitor();
-            if(status == RState.End)
+            if (status == RState.End)
             {
                 return true;
             }
             else if (status == RState.Failed || status == RState.Timeout)
-            {             
+            {
                 Runner.Stop($"Pump down to {BasePressure} failed.");
                 FaEvent.FaPostAlarm(Module.ToString(), $"Pump down to {BasePressure} failed.");
                 return true;
@@ -291,8 +290,8 @@ namespace Venus_RT.Modules.PMs
                 return SetCoolantTemp(ChillerTemp, _OffsetTemp);
             }
             else
-            { 
-            return true;
+            {
+                return true;
             }
 
         }
@@ -316,27 +315,38 @@ namespace Venus_RT.Modules.PMs
             var state = _currentRecipe.Steps[_currentStep].Start();
             if (state != RState.Running)
                 return state;
-                
 
+
+            //if (_bLoopMode == true)
+            //{
+            //}
             if (_currentRecipe.Steps[_currentStep].CycleStart)
             {
                 if (!_bLoopMode)
                 {
                     _bLoopMode = true;
                     _loopStartStep = _currentStep;
-                    _loopCounter = _currentRecipe.Steps[_currentStep].CycleNumber-1;
+                    _loopCounter = _currentRecipe.Steps[_currentStep].CycleNumber - 1;
 
                     currentRecipeResult.RecipeAllCounters = _currentRecipe.Steps[_currentStep].CycleNumber;
                     currentRecipeResult.RecipeCurrentCounter = _loopCounter == 0 ? 0 : 1;
+
+                    _processHelper.isLoop = true;
+                    _processHelper.loopsteps= _currentRecipe.Steps[_currentStep].CycleNumber;
+                }
+                else
+                {
+                    _processHelper.currentStepIndex += 1;
                 }
             }
 
+
             return RState.Running;
         }
 
         private bool StartNewRecipe()
         {
-            if(_qeRecipes.Count > 0)
+            if (_qeRecipes.Count > 0)
             {
                 _currentStep = 0;
                 _currentRecipe = _qeRecipes.Dequeue();
@@ -354,26 +364,26 @@ namespace Venus_RT.Modules.PMs
                 _chamber.EPDRecipeStart(CurrentRunningRecipe);
                 return StartNewStep() == RState.Running;
             }
-            
+
             return false;
         }
         private bool RunRecipes()
-        {     
+        {
             var step = _currentRecipe.Steps[_currentStep];
             currentRecipeResult.RecipeStepCount = _currentRecipe.Steps.Count;
             currentRecipeResult.RecipeName = _currentRecipe.Header.Name;
             currentRecipeResult.RecipeType = _currentRecipe.Header.Type.ToString();
             currentRecipeResult.RecipeStepNumber = step.StepNo;
-            currentRecipeResult.RecipeStepType=step.Type.ToString();
-            currentRecipeResult.RecipeStepDescription=string.IsNullOrEmpty(step.Description)? "": step.Description;
-            currentRecipeResult.RecipeStepSetTime=step.Time;
-            currentRecipeResult.RecipeType=_currentRecipe.Header.Type.ToString();
+            currentRecipeResult.RecipeStepType = step.Type.ToString();
+            currentRecipeResult.RecipeStepDescription = string.IsNullOrEmpty(step.Description) ? "" : step.Description;
+            currentRecipeResult.RecipeStepSetTime = step.Time;
+            currentRecipeResult.RecipeType = _currentRecipe.Header.Type.ToString();
             //currentRecipeResult.RecipeStepDuringTime = (int)_stepTime.ElapsedMilliseconds/1000;
-            currentRecipeResult.RecipeStepDuringTime = new System.TimeSpan(0, 0, System.Convert.ToInt32(_stepTime.ElapsedMilliseconds/1000));
-            
+            currentRecipeResult.RecipeStepDuringTime = new System.TimeSpan(0, 0, System.Convert.ToInt32(_stepTime.ElapsedMilliseconds / 1000));
+
 
             var result = step.Run();
-            if(result == RState.Failed)
+            if (result == RState.Failed)
             {
                 WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Completed);
                 WaferInfo waferInfo = WaferManager.Instance.GetWafer(ModuleHelper.Converter(Module.ToString()), 0);
@@ -393,14 +403,15 @@ namespace Venus_RT.Modules.PMs
                 FaEvent.FaPostAlarm(Module.ToString(), $"Recipe:{CurrentRunningRecipe}, Step:{_currentStep + 1} Failed");
                 return true;
             }
-            else if(result == RState.End || isMaualEndStep == true)
+            else if (result == RState.End || isMaualEndStep == true)
             {
-                if(_currentRecipe.Steps.Count > _currentStep + 1 && _currentRecipe.Steps[_currentStep + 1].Type != StepType.OverEtch)
+                if (_currentRecipe.Steps.Count > _currentStep + 1 && _currentRecipe.Steps[_currentStep + 1].Type != StepType.OverEtch)
+                {
                     _currentRecipe.Steps[_currentStep].End();
-
-                if(_currentRecipe.Steps[_currentStep].CycleEnd)
+                }
+                if (_currentRecipe.Steps[_currentStep].CycleEnd)
                 {
-                    if(_loopCounter > 0)
+                    if (_loopCounter > 0)
                     {
                         _loopCounter--;
                         currentRecipeResult.RecipeCurrentCounter += 1;
@@ -412,13 +423,18 @@ namespace Venus_RT.Modules.PMs
                     {
                         _bLoopMode = false;
                         _loopStartStep = 0;
+                        //_processHelper.loopStep(false, 0, 0);
+
+                        _processHelper.isLoop = false;
+                        _processHelper.loopsteps = 0;
+                        _processHelper.currentStepIndex = 0;
                     }
                 }
 
-                if (_currentStep < _currentRecipe.Steps.Count - 1|| isMaualEndStep==true)
+                if (_currentStep < _currentRecipe.Steps.Count - 1 || isMaualEndStep == true)
                 {
                     result = RState.End;
-                    isMaualEndStep =false;
+                    isMaualEndStep = false;
                     _currentStep++;
                     return StartNewStep() != RState.Running;
                 }
@@ -439,13 +455,13 @@ namespace Venus_RT.Modules.PMs
         private bool ProcessDone()
         {
             _currentRecipe.Steps[_currentStep].End();
-            //RecipeClient.Instance.Service.SaveAsRecipe(Module, CurrentRunningRecipe, RecipeUnity.RecipeToString(_currentRecipe));
-            //SerializeHelper.Instance.WriteToJsonFile<Recipe>(_currentRecipe, $"Recipe/{Module}/{CurrentRunningRecipe}.json");
-            //SaveRecipe(string chamId, string recipeName, string recipeContent, bool clearBarcode, bool notifyUI)
+
             RecipeFileManager.Instance.SaveAsRecipe(Module.ToString(), CurrentRunningRecipe, RecipeUnity.RecipeToString(_currentRecipe));
             _stepTime.Stop();
             WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Idle);
             CloseAllValves();
+            _chamber.GeneratorSetpower(0);
+            _chamber.GeneratorBiasSetpower(0);
             _chamber.GeneratorBiasPowerOn(false);
             _chamber.GeneratorPowerOn(false);
             _chamber.OpenValve(ValveType.TurboPumpPumping, true);
@@ -463,23 +479,23 @@ namespace Venus_RT.Modules.PMs
             }
             Processtime.Stop();
             RecipeEndTime = RecipeStartTime + Processtime.Elapsed;
-            ProcessDataRecorder.RecordPrecess(Guidall, RecipeStartTime, RecipeEndTime, FullRecipeName,"Success", WaferId, _chamber.Name, LotID, SlotID);
+            ProcessDataRecorder.RecordPrecess(Guidall, RecipeStartTime, RecipeEndTime, FullRecipeName, "Success", WaferId, _chamber.Name, LotID, SlotID);
             Guidall = null;
             return true;
         }
 
         private void UpdateWaferStatus(bool bDone = true)
         {
-            if(bDone == false)
+            if (bDone == false)
             {
                 WaferManager.Instance.UpdateWaferProcessStatus(Module, 0, EnumWaferProcessStatus.Failed);
-                if(_currentRecipe.Header.Type == RecipeType.Chuck)
+                if (_currentRecipe.Header.Type == RecipeType.Chuck)
                 {
                     // set wafer chucked flag even if the chuck recipe failed.
                     WaferManager.Instance.UpdateWaferChuckStatus(Module, 0, EnumWaferChuckStatus.Chucked);
                 }
             }
-            switch(_currentRecipe.Header.Type)
+            switch (_currentRecipe.Header.Type)
             {
                 case RecipeType.Process:
                     break;
@@ -493,7 +509,7 @@ namespace Venus_RT.Modules.PMs
             }
         }
 
-        public  void Abort()
+        public void Abort()
         {
             WaferInfo waferInfo = WaferManager.Instance.GetWafer(ModuleHelper.Converter(Module.ToString()), 0);
             if (!waferInfo.IsEmpty)
@@ -513,8 +529,6 @@ namespace Venus_RT.Modules.PMs
             CloseAllValves();
             _chamber.OpenValve(ValveType.TurboPumpPumping, true);
             _chamber.OpenValve(ValveType.TurboPumpPurge, true);
-            //await Task.Delay(3000);
-            //_chamber.OnOffSetESCHV(false);
 
         }
     }

+ 94 - 58
Venus/Venus_RT/Modules/PMs/ProcessDefine.cs

@@ -9,6 +9,7 @@ using Aitex.Core.RT.SCCore;
 using System.Reflection;
 using System.Diagnostics;
 using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.Robot;
+using Aitex.Core.Common.DeviceData;
 //#pragma warning disable 0436
 
 namespace Venus_RT.Modules.PMs
@@ -31,50 +32,56 @@ namespace Venus_RT.Modules.PMs
         private List<float> biasRfMatchC2 = new List<float>();
         private int biasRfMatchC1C2Index = 0;
 
+        public bool isLoop = false;
+        public int loopsteps = 0;
+        public int currentStepIndex = 0;
+
+        //private int cycleIndex = 0;
+        private bool biasRFSetPointFlag = true;
         public ProcessHelper(JetPMBase pm)
         {
             Chamber = pm;
-            Module = pm.Module.ToString() ;
+            Module = pm.Module.ToString();
             Init();
         }
 
         private void Init()
         {
-            startHelper     [$"{Module}.PressureByPressureModeUnit"]  = (ProcessUnitBase unit, RecipeStep step) => PressureByPressureModeUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.PressureByPressureModeUnit"]  = (ProcessUnitBase unit, RecipeStep step) => PressureByPressureModeUnit_Check(unit, step);
-            endHelper       [$"{Module}.PressureByPressureModeUnit"]  = (ProcessUnitBase unit, RecipeStep step) => PressureByPressureModeUnit_End(unit, step);
+            startHelper[$"{Module}.PressureByPressureModeUnit"] = (ProcessUnitBase unit, RecipeStep step) => PressureByPressureModeUnit_Start(unit, step);
+            checkerHelper[$"{Module}.PressureByPressureModeUnit"] = (ProcessUnitBase unit, RecipeStep step) => PressureByPressureModeUnit_Check(unit, step);
+            endHelper[$"{Module}.PressureByPressureModeUnit"] = (ProcessUnitBase unit, RecipeStep step) => PressureByPressureModeUnit_End(unit, step);
 
             //startHelper     [$"{Module}.PressureByValveModeUnit"]     = (ProcessUnitBase unit, RecipeStep step) => PressureByValveModeUnit_Start(unit, step);
             //checkerHelper   [$"{Module}.PressureByValveModeUnit"]     = (ProcessUnitBase unit, RecipeStep step) => PressureByValveModeUnit_Check(unit, step);
             //endHelper       [$"{Module}.PressureByValveModeUnit"]     = (ProcessUnitBase unit, RecipeStep step) => PressureByValveModeUnit_End(unit, step);
 
-            startHelper     [$"{Module}.TCPUnit"]                     = (ProcessUnitBase unit, RecipeStep step) => TCPUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.TCPUnit"]                     = (ProcessUnitBase unit, RecipeStep step) => TCPUnit_Check(unit, step);
-            endHelper       [$"{Module}.TCPUnit"]                     = (ProcessUnitBase unit, RecipeStep step) => TCPUnit_End(unit, step);
+            startHelper[$"{Module}.TCPUnit"] = (ProcessUnitBase unit, RecipeStep step) => TCPUnit_Start(unit, step);
+            checkerHelper[$"{Module}.TCPUnit"] = (ProcessUnitBase unit, RecipeStep step) => TCPUnit_Check(unit, step);
+            endHelper[$"{Module}.TCPUnit"] = (ProcessUnitBase unit, RecipeStep step) => TCPUnit_End(unit, step);
 
-            startHelper     [$"{Module}.BiasUnit"]                    = (ProcessUnitBase unit, RecipeStep step) => BiasUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.BiasUnit"]                    = (ProcessUnitBase unit, RecipeStep step) => BiasUnit_Check(unit, step);
-            endHelper       [$"{Module}.BiasUnit"]                    = (ProcessUnitBase unit, RecipeStep step) => BiasUnit_End(unit, step);
+            startHelper[$"{Module}.BiasUnit"] = (ProcessUnitBase unit, RecipeStep step) => BiasUnit_Start(unit, step);
+            checkerHelper[$"{Module}.BiasUnit"] = (ProcessUnitBase unit, RecipeStep step) => BiasUnit_Check(unit, step);
+            endHelper[$"{Module}.BiasUnit"] = (ProcessUnitBase unit, RecipeStep step) => BiasUnit_End(unit, step);
 
-            startHelper     [$"{Module}.GasControlUnit"]              = (ProcessUnitBase unit, RecipeStep step) => GasControlUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.GasControlUnit"]              = (ProcessUnitBase unit, RecipeStep step) => GasControlUnit_Check(unit, step);
-            endHelper       [$"{Module}.GasControlUnit"]              = (ProcessUnitBase unit, RecipeStep step) => GasControlUnit_End(unit, step);
+            startHelper[$"{Module}.GasControlUnit"] = (ProcessUnitBase unit, RecipeStep step) => GasControlUnit_Start(unit, step);
+            checkerHelper[$"{Module}.GasControlUnit"] = (ProcessUnitBase unit, RecipeStep step) => GasControlUnit_Check(unit, step);
+            endHelper[$"{Module}.GasControlUnit"] = (ProcessUnitBase unit, RecipeStep step) => GasControlUnit_End(unit, step);
 
-            startHelper     [$"{Module}.ESCHVUnit"]                   = (ProcessUnitBase unit, RecipeStep step) => ESCHVUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.ESCHVUnit"]                   = (ProcessUnitBase unit, RecipeStep step) => ESCHVUnit_Check(unit, step);
-            endHelper       [$"{Module}.ESCHVUnit"]                   = (ProcessUnitBase unit, RecipeStep step) => ESCHVUnit_End(unit, step);
+            startHelper[$"{Module}.ESCHVUnit"] = (ProcessUnitBase unit, RecipeStep step) => ESCHVUnit_Start(unit, step);
+            checkerHelper[$"{Module}.ESCHVUnit"] = (ProcessUnitBase unit, RecipeStep step) => ESCHVUnit_Check(unit, step);
+            endHelper[$"{Module}.ESCHVUnit"] = (ProcessUnitBase unit, RecipeStep step) => ESCHVUnit_End(unit, step);
 
-            startHelper     [$"{Module}.ProcessKitUnit"]              = (ProcessUnitBase unit, RecipeStep step) => ProcessKitUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.ProcessKitUnit"]              = (ProcessUnitBase unit, RecipeStep step) => ProcessKitUnit_Check(unit, step);
-            endHelper       [$"{Module}.ProcessKitUnit"]              = (ProcessUnitBase unit, RecipeStep step) => ProcessKitUnit_End(unit, step);
+            startHelper[$"{Module}.ProcessKitUnit"] = (ProcessUnitBase unit, RecipeStep step) => ProcessKitUnit_Start(unit, step);
+            checkerHelper[$"{Module}.ProcessKitUnit"] = (ProcessUnitBase unit, RecipeStep step) => ProcessKitUnit_Check(unit, step);
+            endHelper[$"{Module}.ProcessKitUnit"] = (ProcessUnitBase unit, RecipeStep step) => ProcessKitUnit_End(unit, step);
 
-            startHelper     [$"{Module}.Kepler2200GasControlUnit"]    = (ProcessUnitBase unit, RecipeStep step) => Kepler2200GasControlUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.Kepler2200GasControlUnit"]    = (ProcessUnitBase unit, RecipeStep step) => Kepler2200GasControlUnit_Check(unit, step);
-            endHelper       [$"{Module}.Kepler2200GasControlUnit"]    = (ProcessUnitBase unit, RecipeStep step) => Kepler2200GasControlUnit_End(unit, step);
+            startHelper[$"{Module}.Kepler2200GasControlUnit"] = (ProcessUnitBase unit, RecipeStep step) => Kepler2200GasControlUnit_Start(unit, step);
+            checkerHelper[$"{Module}.Kepler2200GasControlUnit"] = (ProcessUnitBase unit, RecipeStep step) => Kepler2200GasControlUnit_Check(unit, step);
+            endHelper[$"{Module}.Kepler2200GasControlUnit"] = (ProcessUnitBase unit, RecipeStep step) => Kepler2200GasControlUnit_End(unit, step);
 
-            startHelper     [$"{Module}.HeaterUnit"]                  = (ProcessUnitBase unit, RecipeStep step) => HeaterUnit_Start(unit, step);
-            checkerHelper   [$"{Module}.HeaterUnit"]                  = (ProcessUnitBase unit, RecipeStep step) => HeaterUnit_Check(unit, step);
-            endHelper       [$"{Module}.HeaterUnit"]                  = (ProcessUnitBase unit, RecipeStep step) => HeaterUnit_End(unit, step);
+            startHelper[$"{Module}.HeaterUnit"] = (ProcessUnitBase unit, RecipeStep step) => HeaterUnit_Start(unit, step);
+            checkerHelper[$"{Module}.HeaterUnit"] = (ProcessUnitBase unit, RecipeStep step) => HeaterUnit_Check(unit, step);
+            endHelper[$"{Module}.HeaterUnit"] = (ProcessUnitBase unit, RecipeStep step) => HeaterUnit_End(unit, step);
         }
 
         private RState PressureByPressureModeUnit_Start(ProcessUnitBase unit, RecipeStep step)
@@ -91,21 +98,21 @@ namespace Venus_RT.Modules.PMs
             else if (ProcessUnit.PressureUnitMode == PressureUnitMode.Valve)
             {
                 if (Chamber.SetPVPostion(ProcessUnit.StartValue))
-                { 
+                {
                     return RState.Running;
                 }
-            }            
+            }
             return RState.Failed;
         }
 
         private RState PressureByPressureModeUnit_Check(ProcessUnitBase unit, RecipeStep step)
         {
             var ProcessUnit = unit as PressureByPressureModeUnit;
-            if(ProcessUnit.EnableRamp)
+            if (ProcessUnit.EnableRamp)
             {
                 if (ProcessUnit.PressureUnitMode == PressureUnitMode.Pressure)
                 {
-                    if (Chamber.SetPVPressure(ProcessUnit.StartValue+ (int)((ProcessUnit.TargetValue - ProcessUnit.StartValue) * step.RampFactor())))
+                    if (Chamber.SetPVPressure(ProcessUnit.StartValue + (int)((ProcessUnit.TargetValue - ProcessUnit.StartValue) * step.RampFactor())))
                         return RState.Running;
                     else
                         return RState.Failed;
@@ -126,15 +133,15 @@ namespace Venus_RT.Modules.PMs
                     return RState.End;
                 }
             }
-            else if (ProcessUnit.PressureUnitMode == PressureUnitMode.Valve )
+            else if (ProcessUnit.PressureUnitMode == PressureUnitMode.Valve)
             {
-                if (step.Type == StepType.Stable &&  Chamber.GetPVPosition() == ProcessUnit.StartValue)
+                if (step.Type == StepType.Stable && Chamber.GetPVPosition() == ProcessUnit.StartValue)
                 {
                     return RState.End;
                 }
-               
+
             }
-               
+
 
             return RState.Running;
         }
@@ -196,7 +203,7 @@ namespace Venus_RT.Modules.PMs
                 p1 = ProcessUnit.TuneCapPreset;
             }
             else
-            { 
+            {
                 p1 = ProcessUnit.AutoTuneCapPreset;
             }
             if (ProcessUnit.LoadCapPreset > 0)
@@ -216,9 +223,9 @@ namespace Venus_RT.Modules.PMs
 
         private RState TCPUnit_Check(ProcessUnitBase unit, RecipeStep step)
         {
-            var _scPowerAlarmTime= SC.GetValue<double>($"{Chamber.Name}.Rf.PowerAlarmTime");
+            var _scPowerAlarmTime = SC.GetValue<double>($"{Chamber.Name}.Rf.PowerAlarmTime");
             var ProcessUnit = unit as TCPUnit;
-            if(ProcessUnit.MaxReflectedPower > 0 && Chamber.ReflectPower > ProcessUnit.MaxReflectedPower && step.ElapsedTime() > _scPowerAlarmTime*1000)
+            if (ProcessUnit.MaxReflectedPower > 0 && Chamber.ReflectPower > ProcessUnit.MaxReflectedPower && step.ElapsedTime() > _scPowerAlarmTime * 1000)
             {
                 LOG.Write(eEvent.ERR_PROCESS, Chamber.Module, $"Step:{step.StepNo} failed, RF Reflect Power:{Chamber.ReflectPower} exceeds the Max Limit:{ProcessUnit.MaxReflectedPower}");
                 return RState.Failed;
@@ -238,20 +245,20 @@ namespace Venus_RT.Modules.PMs
             }
 
 
-                return RState.Running;
+            return RState.Running;
         }
 
         private void TCPUnit_End(ProcessUnitBase unit, RecipeStep step)
         {
             var ProcessUnit = unit as TCPUnit;
-            if (rfMatchC1.Count >=6)
+            if (rfMatchC1.Count >= 6)
             {
                 float allValue = 0;
                 for (int i = 4; i < rfMatchC1.Count; i++)
                 {
                     allValue += rfMatchC1[i];
                 }
-                var average=allValue/ (rfMatchC1.Count-4);
+                var average = allValue / (rfMatchC1.Count - 4);
                 ProcessUnit.AutoTuneCapPreset = (int)average;
             }
             if (rfMatchC2.Count >= 6)
@@ -275,8 +282,11 @@ namespace Venus_RT.Modules.PMs
             var ProcessUnit = unit as BiasUnit;
             if (ProcessUnit.BiasRFPower > 5)
             {
-                Chamber.GeneratorBiasSetpower(ProcessUnit.BiasRFPower);
                 Chamber.GeneratorBiasPowerOn(true);
+                if ((ProcessUnit.EnableRamp == false))
+                {
+                    Chamber.GeneratorBiasSetpower(ProcessUnit.BiasRFPower);
+                }
             }
             int p1;
             int p2;
@@ -297,7 +307,7 @@ namespace Venus_RT.Modules.PMs
                 p2 = ProcessUnit.AutoBiasLoadCapPreset;
             }
             Chamber.SetBiasMatchPosition(p1, p2);
-            if(ProcessUnit.BiasGeneratorMode == GeneratorMode.Pulsing)
+            if (ProcessUnit.BiasGeneratorMode == GeneratorMode.Pulsing)
             {
                 Chamber.SetBiasPulseMode(true);
                 Chamber.SetBiasPulseRateFreq(ProcessUnit.PulseRateFreq);
@@ -331,6 +341,30 @@ namespace Venus_RT.Modules.PMs
                 biasRfMatchC2.Add(Chamber.BiasRFMatchC2);
                 biasRfMatchC1C2Index += 1;
             }
+            if (ProcessUnit.EnableRamp)
+            {
+                //if (step.ElapsedTime() <= 500*cycleIndex)
+                //{
+                //    return RState.Running;
+                //}
+                //cycleIndex += 1;
+                if (ProcessUnit.TargetMode == TargetMode.Cycle)
+                {
+                    if (currentStepIndex == 0 && biasRFSetPointFlag==true)
+                    {
+                        biasRFSetPointFlag = false;
+                        Chamber.GeneratorBiasSetpower((float)((ProcessUnit.BiasRFPower + (float)((ProcessUnit.TargetBiasRFPower - ProcessUnit.BiasRFPower) / (loopsteps - 1) * currentStepIndex))));
+                    }
+                    //float rampFactor = (float)currentStepIndex / (float)(loopsteps-1);
+                    //double rampFactor = step.RampFactor();                                 
+                    //Chamber.GeneratorBiasSetpower((float)((ProcessUnit.BiasRFPower+  (ProcessUnit.TargetBiasRFPower - ProcessUnit.BiasRFPower)/(loopsteps)*currentStepIndex) +  ((double)(ProcessUnit.TargetBiasRFPower - ProcessUnit.BiasRFPower) / ((double)loopsteps)) * rampFactor));
+                }
+                else
+                {
+                    //double rampFactor = step.RampFactor();                 
+                    //Chamber.GeneratorBiasSetpower((float)(ProcessUnit.BiasRFPower + (ProcessUnit.TargetBiasRFPower - ProcessUnit.BiasRFPower) * rampFactor));
+                }
+            }
             return RState.Running;
         }
 
@@ -362,6 +396,8 @@ namespace Venus_RT.Modules.PMs
             biasRfMatchC1.Clear();
             biasRfMatchC1.Clear();
             biasRfMatchC1C2Index = 0;
+            //cycleIndex = 0;
+            biasRFSetPointFlag = true;
         }
 
         private RState GasControlUnit_Start(ProcessUnitBase unit, RecipeStep step)
@@ -381,7 +417,7 @@ namespace Venus_RT.Modules.PMs
             Chamber.FlowGas(2, ProcessUnit.Gas3);
             if (ProcessUnit.Gas3 >= 1)
             {
-                Chamber.OpenValve(ValveType.PV31,true);
+                Chamber.OpenValve(ValveType.PV31, true);
             }
             Chamber.FlowGas(3, ProcessUnit.Gas4);
             if (ProcessUnit.Gas4 >= 1)
@@ -398,7 +434,7 @@ namespace Venus_RT.Modules.PMs
         private RState GasControlUnit_Check(ProcessUnitBase unit, RecipeStep step)
         {
             var ProcessUnit = unit as GasControlUnit;
-            if(ProcessUnit.EnableRamp)
+            if (ProcessUnit.EnableRamp)
             {
                 double rampFactor = step.RampFactor();
                 Chamber.FlowGas(0, ProcessUnit.Gas1 + (ProcessUnit.Gas1Target - ProcessUnit.Gas1) * rampFactor);
@@ -428,7 +464,7 @@ namespace Venus_RT.Modules.PMs
         private RState ESCHVUnit_Start(ProcessUnitBase unit, RecipeStep step)
         {
             var ProcessUnit = unit as ESCHVUnit;
-            
+
             Chamber.SetESCClampVoltage(ProcessUnit.ESCClampValtage);
 
             Chamber.SetBacksideHePressure(ProcessUnit.BacksideHelum);
@@ -438,7 +474,7 @@ namespace Venus_RT.Modules.PMs
 
         private RState ESCHVUnit_Check(ProcessUnitBase unit, RecipeStep step)
         {
-            if(Chamber.BackSideHeOutOfRange)
+            if (Chamber.BackSideHeOutOfRange)
             {
                 LOG.Write(eEvent.ERR_PROCESS, Chamber.Module, $"Step:{step.StepNo} failed, Backside Helium out of range.");
                 return RState.Failed;
@@ -516,7 +552,7 @@ namespace Venus_RT.Modules.PMs
         }
 
         private RState HeaterUnit_Start(ProcessUnitBase unit, RecipeStep step)
-        {          
+        {
             return RState.Running;
         }
 
@@ -527,12 +563,12 @@ namespace Venus_RT.Modules.PMs
 
         private void HeaterUnit_End(ProcessUnitBase unit, RecipeStep step)
         {
-            
+
         }
         public bool LoadMethods(ProcessUnitBase unit)
         {
             var className = $"{Module}.{unit.GetType().Name}";
-            if(startHelper.ContainsKey(className) && checkerHelper.ContainsKey(className) && endHelper.ContainsKey(className))
+            if (startHelper.ContainsKey(className) && checkerHelper.ContainsKey(className) && endHelper.ContainsKey(className))
             {
                 unit.starter = startHelper[className];
                 unit.checker = checkerHelper[className];
@@ -543,6 +579,12 @@ namespace Venus_RT.Modules.PMs
 
             return false;
         }
+        //public void loopStep(bool isloop,int loopCount,int loopIndex)
+        //{ 
+        //    isLoop = isloop;
+        //    loopsteps=loopCount;
+        //    currentStepIndex = loopIndex;
+        //}
 
         private RState stepStarter(RecipeStep step)
         {
@@ -558,7 +600,7 @@ namespace Venus_RT.Modules.PMs
 
         private RState stepChecker(RecipeStep step)
         {
-            switch(step.Type)
+            switch (step.Type)
             {
                 case StepType.Time:
                     return step.ElapsedTime() >= step.Time * 1000 ? RState.End : RState.Running;
@@ -571,8 +613,9 @@ namespace Venus_RT.Modules.PMs
                         return RState.End;
                     }
                     else
+                    {
                         return Chamber.EPDCaptured ? RState.End : RState.Running;
-                
+                    }
             }
 
             return RState.Running;
@@ -580,17 +623,10 @@ namespace Venus_RT.Modules.PMs
 
         private RState stepEnder(RecipeStep step)
         {
-            if(step.Type == StepType.EndPoint)
+            if (step.Type == StepType.EndPoint)
             {
                 Chamber.EPDStepStop();
             }
-
-            //Chamber.GeneratorBiasPowerOn(false);
-            //Chamber.GeneratorPowerOn(false);
-            //Chamber.TurnPendulumValve(false);
-            //Chamber.CloseValves();
-            //Chamber.OpenValve(ValveType.TurboPumpPumping, true);
-            //Chamber.OpenValve(ValveType.TurboPumpPurge, true);
             return RState.End;
         }
 

+ 3 - 3
Venus/Venus_Themes/UserControls/Chamber.xaml

@@ -40,7 +40,7 @@
         </LinearGradientBrush>
     </UserControl.Resources>
     <Canvas >
-        
+
         <Grid Width="240" Height="190" Canvas.Top="80">
             <Grid.RowDefinitions>
                 <RowDefinition Height="160"/>
@@ -70,7 +70,7 @@
                     </LinearGradientBrush>
                 </Rectangle.Fill>
             </Rectangle>
-            <Rectangle x:Name="BG_Status" Margin="9,19" Visibility="{Binding BiasRfPowerOnChamberVisibility}" >
+            <Rectangle x:Name="BG_Status" Margin="9,19" Visibility="{Binding BiasRfPowerOnChamberVisibility}" Cursor="Hand">
                 <Rectangle.ContextMenu >
                     <ContextMenu>
                         <MenuItem Header="Create Wafer"  Click="CreateWafer_Click"     IsChecked="{Binding IsHasWafer}" IsEnabled="{Binding IsHasWafer,Converter={StaticResource BoolToBool}}"/>
@@ -88,7 +88,6 @@
                     </Style>
                 </Rectangle.Style>
             </Rectangle>
-
             <Rectangle Stroke="#FF747474" Height="11" VerticalAlignment="Bottom" Margin="12,0,12,8">
                 <Rectangle.Fill>
                     <LinearGradientBrush EndPoint="0.243,1" StartPoint="0.757,0">
@@ -331,6 +330,7 @@
                 </Grid>
             </Grid>
         </Grid>
+
     </Canvas>