diff --git a/EDSEditorGUI/DeviceInfoView.Designer.cs b/EDSEditorGUI/DeviceInfoView.Designer.cs index ce68a85c..507fc7b2 100644 --- a/EDSEditorGUI/DeviceInfoView.Designer.cs +++ b/EDSEditorGUI/DeviceInfoView.Designer.cs @@ -60,6 +60,8 @@ private void InitializeComponent() this.label32 = new System.Windows.Forms.Label(); this.textBox_concretenodeid = new System.Windows.Forms.TextBox(); this.groupBox4 = new System.Windows.Forms.GroupBox(); + this.textBox_revisionnumber = new System.Windows.Forms.TextBox(); + this.label11 = new System.Windows.Forms.Label(); this.textBox_productnumber = new System.Windows.Forms.TextBox(); this.textBox_productname = new System.Windows.Forms.TextBox(); this.textBox_vendornumber = new System.Windows.Forms.TextBox(); @@ -142,7 +144,7 @@ private void InitializeComponent() this.groupBox5.Controls.Add(this.label31); this.groupBox5.Controls.Add(this.textBox_projectFileName); this.groupBox5.Controls.Add(this.textBox_deviceedsname); - this.groupBox5.Location = new System.Drawing.Point(12, 332); + this.groupBox5.Location = new System.Drawing.Point(12, 353); this.groupBox5.Name = "groupBox5"; this.groupBox5.Size = new System.Drawing.Size(377, 182); this.groupBox5.TabIndex = 63; @@ -283,7 +285,7 @@ private void InitializeComponent() this.groupBox6.Controls.Add(this.textBox_nodename); this.groupBox6.Controls.Add(this.label32); this.groupBox6.Controls.Add(this.textBox_concretenodeid); - this.groupBox6.Location = new System.Drawing.Point(395, 313); + this.groupBox6.Location = new System.Drawing.Point(395, 333); this.groupBox6.Name = "groupBox6"; this.groupBox6.Size = new System.Drawing.Size(339, 202); this.groupBox6.TabIndex = 5; @@ -414,6 +416,8 @@ private void InitializeComponent() // // groupBox4 // + this.groupBox4.Controls.Add(this.textBox_revisionnumber); + this.groupBox4.Controls.Add(this.label11); this.groupBox4.Controls.Add(this.textBox_productnumber); this.groupBox4.Controls.Add(this.textBox_productname); this.groupBox4.Controls.Add(this.textBox_vendornumber); @@ -424,11 +428,27 @@ private void InitializeComponent() this.groupBox4.Controls.Add(this.label26); this.groupBox4.Location = new System.Drawing.Point(12, 14); this.groupBox4.Name = "groupBox4"; - this.groupBox4.Size = new System.Drawing.Size(377, 126); + this.groupBox4.Size = new System.Drawing.Size(377, 147); this.groupBox4.TabIndex = 0; this.groupBox4.TabStop = false; this.groupBox4.Text = "Device Info"; // + // textBox_revisionnumber + // + this.textBox_revisionnumber.Location = new System.Drawing.Point(139, 124); + this.textBox_revisionnumber.Name = "textBox_revisionnumber"; + this.textBox_revisionnumber.Size = new System.Drawing.Size(226, 20); + this.textBox_revisionnumber.TabIndex = 38; + // + // label11 + // + this.label11.AutoSize = true; + this.label11.Location = new System.Drawing.Point(10, 127); + this.label11.Name = "label11"; + this.label11.Size = new System.Drawing.Size(48, 13); + this.label11.TabIndex = 39; + this.label11.Text = "Revision"; + // // textBox_productnumber // this.textBox_productnumber.Location = new System.Drawing.Point(139, 46); @@ -743,7 +763,7 @@ private void InitializeComponent() this.groupBox3.Controls.Add(this.label22); this.groupBox3.Controls.Add(this.label20); this.groupBox3.Controls.Add(this.label18); - this.groupBox3.Location = new System.Drawing.Point(12, 146); + this.groupBox3.Location = new System.Drawing.Point(12, 167); this.groupBox3.Name = "groupBox3"; this.groupBox3.Size = new System.Drawing.Size(377, 180); this.groupBox3.TabIndex = 1; @@ -949,5 +969,7 @@ private void InitializeComponent() private System.Windows.Forms.Label label10; private System.Windows.Forms.CheckBox checkBox_ngMaster; private System.Windows.Forms.CheckBox checkBox_ngSlave; + private System.Windows.Forms.TextBox textBox_revisionnumber; + private System.Windows.Forms.Label label11; } } diff --git a/EDSEditorGUI/DeviceInfoView.cs b/EDSEditorGUI/DeviceInfoView.cs index 20ef719d..7641f07d 100644 --- a/EDSEditorGUI/DeviceInfoView.cs +++ b/EDSEditorGUI/DeviceInfoView.cs @@ -23,6 +23,7 @@ You should have received a copy of the GNU General Public License using System.IO; using System.Runtime.CompilerServices; using System.Drawing; +using System.Linq; namespace ODEditor { @@ -44,6 +45,7 @@ public void populatedeviceinfo() textBox_productnumber.Text = eds.di.ProductNumber; textBox_vendorname.Text = eds.di.VendorName; textBox_vendornumber.Text = eds.di.VendorNumber; + textBox_revisionnumber.Text = eds.di.RevisionNumber.ToString(); textBox_fileversion.Text = eds.fi.FileVersion; textBox_di_description.Text = eds.fi.Description; @@ -140,6 +142,7 @@ private void update_devfile_info() eds.di.ProductNumber = textBox_productnumber.Text; eds.di.VendorName = textBox_vendorname.Text; eds.di.VendorNumber = textBox_vendornumber.Text; + uint.TryParse(textBox_revisionnumber.Text, out eds.di.RevisionNumber); eds.fi.FileVersion = textBox_fileversion.Text; eds.fi.Description = textBox_di_description.Text; diff --git a/EDSEditorGUI/DeviceODView.Designer.cs b/EDSEditorGUI/DeviceODView.Designer.cs index 11eb304d..7913ddb1 100644 --- a/EDSEditorGUI/DeviceODView.Designer.cs +++ b/EDSEditorGUI/DeviceODView.Designer.cs @@ -497,9 +497,9 @@ private void InitializeComponent() this.groupBox1.Controls.Add(this.comboBox_accessPDO); this.groupBox1.Dock = System.Windows.Forms.DockStyle.Bottom; this.groupBox1.Location = new System.Drawing.Point(0, 329); - this.groupBox1.Margin = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.groupBox1.Margin = new System.Windows.Forms.Padding(2); this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(2, 2, 2, 2); + this.groupBox1.Padding = new System.Windows.Forms.Padding(2); this.groupBox1.Size = new System.Drawing.Size(854, 188); this.groupBox1.TabIndex = 33; this.groupBox1.TabStop = false; @@ -507,6 +507,8 @@ private void InitializeComponent() // // checkBox_autosave // + this.checkBox_autosave.Checked = true; + this.checkBox_autosave.CheckState = System.Windows.Forms.CheckState.Checked; this.checkBox_autosave.Location = new System.Drawing.Point(634, 146); this.checkBox_autosave.Name = "checkBox_autosave"; this.checkBox_autosave.Size = new System.Drawing.Size(116, 21); diff --git a/EDSEditorGUI/DeviceODView.cs b/EDSEditorGUI/DeviceODView.cs index acb113da..4e3bba42 100644 --- a/EDSEditorGUI/DeviceODView.cs +++ b/EDSEditorGUI/DeviceODView.cs @@ -220,6 +220,10 @@ public void PopulateObjectLists(EDSsharp eds_target) }); lvi.Tag = od; + if ((index == 0x100C) || (index == 0x100D)) + { + od.prop.CO_disabled = !eds.di.NG_Slave; + } if (selectedObject != null && index == selectedObject.Index) lvi.Selected = true; if (od.prop.CO_disabled == true) diff --git a/EDSEditorGUI/EDSEditorGUI.csproj b/EDSEditorGUI/EDSEditorGUI.csproj index 42bc8815..a3422a70 100644 --- a/EDSEditorGUI/EDSEditorGUI.csproj +++ b/EDSEditorGUI/EDSEditorGUI.csproj @@ -99,9 +99,9 @@ - - - + + + diff --git a/EDSEditorGUI/Form1.Designer.cs b/EDSEditorGUI/Form1.Designer.cs index 6ef5774d..7f1e72f2 100644 --- a/EDSEditorGUI/Form1.Designer.cs +++ b/EDSEditorGUI/Form1.Designer.cs @@ -290,17 +290,20 @@ private void InitializeComponent() this.tabControl1.Multiline = true; this.tabControl1.Name = "tabControl1"; this.tabControl1.SelectedIndex = 0; + this.tabControl1.ShowToolTips = true; this.tabControl1.Size = new System.Drawing.Size(1599, 909); this.tabControl1.SizeMode = System.Windows.Forms.TabSizeMode.Fixed; this.tabControl1.TabIndex = 2; this.tabControl1.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.tabControl1_DrawItem); this.tabControl1.ControlAdded += new System.Windows.Forms.ControlEventHandler(this.tabControl1_ControlsChanged); - this.tabControl1.ControlRemoved += new System.Windows.Forms.ControlEventHandler(this.tabControl1_Controlsremoved); + this.tabControl1.ControlRemoved += new System.Windows.Forms.ControlEventHandler(this.tabControl1_ControlsChanged); this.tabControl1.DragDrop += new System.Windows.Forms.DragEventHandler(this.ODEditor_MainForm_DragDrop); this.tabControl1.DragEnter += new System.Windows.Forms.DragEventHandler(this.ODEditor_MainForm_DragEnter); this.tabControl1.DragOver += new System.Windows.Forms.DragEventHandler(this.ODEditor_MainForm_DragOver); this.tabControl1.DragLeave += new System.EventHandler(this.ODEditor_MainForm_DragLeave); this.tabControl1.QueryContinueDrag += new System.Windows.Forms.QueryContinueDragEventHandler(this.ODEditor_MainForm_QueryContinueDrag); + this.tabControl1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.tabControl1_MouseClick); + this.tabControl1.MouseHover += new System.EventHandler(this.tabControl1_MouseHover); // // ODEditor_MainForm // diff --git a/EDSEditorGUI/Form1.cs b/EDSEditorGUI/Form1.cs index 1e9d0ca9..2c4ce027 100644 --- a/EDSEditorGUI/Form1.cs +++ b/EDSEditorGUI/Form1.cs @@ -26,7 +26,6 @@ You should have received a copy of the GNU General Public License using System.Windows.Forms; using System.IO; using libEDSsharp; -using static System.Windows.Forms.VisualStyles.VisualStyleElement; namespace ODEditor { @@ -189,6 +188,12 @@ private void openEDSfile(string path,InfoSection.Filetype ft) { EDSsharp eds = new EDSsharp(); + if (!File.Exists(path)) + { + MessageBox.Show("File " +path + "\ndoes not exist."); + return; + } + eds.Loadfile(path); DeviceView device = new DeviceView(eds, network); @@ -327,6 +332,11 @@ private void openToolStripMenuItem_Click(object sender, EventArgs e) private void openXDDfile(string path) { + if (!File.Exists(path)) + { + MessageBox.Show("File " + path + "\ndoes not exist."); + return; + } try { EDSsharp eds; @@ -1329,34 +1339,52 @@ private void preferencesToolStripMenuItem_Click(object sender, EventArgs e) private void tabControl1_MouseClick(object sender, MouseEventArgs e) { - TabPage tp; if (e.Button == MouseButtons.Right) { for (int i = 0; i <= tabControl1.TabCount - 1; i++) { if (tabControl1.GetTabRect(i).Contains(e.Location)) { - tp = tabControl1.TabPages[i]; - DialogResult dialogResult = MessageBox.Show(tabControl1.TabPages[i].Text, "Close file?", MessageBoxButtons.YesNo); if (dialogResult == DialogResult.Yes) { - - DeviceView device = (DeviceView)tabControl1.TabPages[i].Controls[0]; - - if (device.eds.Dirty == true) - { - if (MessageBox.Show("All unsaved changes will be lost\n continue?", "Unsaved changes", MessageBoxButtons.YesNo) == DialogResult.No) - return; - } - - network.Remove(device.eds); - - tabControl1.TabPages.Remove(tabControl1.TabPages[i]); + DeviceView device = (DeviceView)tabControl1.TabPages[i].Controls[0]; + if (device.eds.Dirty == true) + { + if (MessageBox.Show("All unsaved changes will be lost\n continue?", "Unsaved changes", MessageBoxButtons.YesNo) == DialogResult.No) + return; + } + network.Remove(device.eds); + tabControl1.TabPages.Remove(tabControl1.TabPages[i]); } } } } } + private void tabControl1_MouseHover(object sender, EventArgs e) + { + + TabControl tabControl = sender as TabControl; + Point mousePosition = tabControl.PointToClient(Cursor.Position); + for (int i = 0; i < tabControl.TabCount; i++) + { + Rectangle tabRect = tabControl.GetTabRect(i); + if (tabRect.Contains(mousePosition)) + { + ToolTip toolTip = new ToolTip(); + // Set up the delays for the ToolTip. + + toolTip.AutoPopDelay = 5000; + toolTip.InitialDelay = 1000; + toolTip.ReshowDelay = 500; + // Force the ToolTip text to be displayed whether or not the form is active. + toolTip.ShowAlways = true; + DeviceView device = (DeviceView)tabControl1.TabPages[i].Controls[0]; + toolTip.SetToolTip(tabControl, device.eds.projectFilename); + break; + } + } + } + } } diff --git a/EDSEditorGUI/InsertObjects.cs b/EDSEditorGUI/InsertObjects.cs index 52d7509b..a2919d1a 100644 --- a/EDSEditorGUI/InsertObjects.cs +++ b/EDSEditorGUI/InsertObjects.cs @@ -159,24 +159,29 @@ private bool Verify(bool InitiallyDisableIfError = false) int j = 1; foreach (ODentry od in srcObjects.Values) { - String numpattern = @"(\w*\d+\Z)"; string newname; + string numpattern = @"^(.*?)(\d+)$"; + Regex regex = new Regex(numpattern); + Match match = regex.Match(od.parameter_name); - string[] words = Regex.Split(od.parameter_name, numpattern); - // MatchCollection nummatches = System.Text.RegularExpressions.Regex.Matches(od.parameter_name, numpattern); - if (words.Length > 1) + if (match.Success) { + // Extract the string part and the number part + string stringPart = match.Groups[1].Value; + int numberPart = int.Parse(match.Groups[2].Value); - // value1 = Int32.Parse(m.Groups[1].Value); - int nameidx = Int32.Parse(words[1]) + j++; - - newname = words[0] + nameidx;// nameidx.ToString ; + // Increment the number by 1 + numberPart++; + // Reassemble the string with the incremented number + newname = stringPart + numberPart.ToString(); } - else { - newname = od.parameter_name; + else + { + newname = od.parameter_name; } - int rowIdx = dataGridView.Rows.Add(enabled[odIdx], $"0x{od.Index:X4} - {newname}"); + + int rowIdx = dataGridView.Rows.Add(enabled[odIdx], $"0x{od.Index:X4} - {newname}"); int cellIdx = dataGridView_InitialColumnCount; foreach (int o in offsets) @@ -235,17 +240,23 @@ private void Button_create_Click(object sender, EventArgs e) UInt16 newIndex = (UInt16)(od.Index + o); ODentry newObject = od.Clone(); - String pattern = @"(\w*\d+\Z)"; + string pattern = @"^(.*?)(\d+)$"; - string[] words = Regex.Split(od.parameter_name, pattern); - // MatchCollection nummatches = System.Text.RegularExpressions.Regex.Matches(od.parameter_name, numpattern); - if (words.Length > 1) + Regex regex = new Regex(pattern); + Match match = regex.Match(od.parameter_name); + + if (match.Success) { - int nameidx = Int32.Parse(words[1]) + i++; - newObject.parameter_name = words[0] + nameidx;// nameidx.ToString ; + // Extract the string part and the number part + string stringPart = match.Groups[1].Value; + int numberPart = int.Parse(match.Groups[2].Value); - } + // Increment the number by 1 + numberPart++; + // Reassemble the string with the incremented number + newObject.parameter_name = stringPart + numberPart.ToString(); + } newObject.Index = newIndex; eds.ods.Add(newIndex, newObject); diff --git a/EDSEditorGUI2/EDSEditorGUI2.csproj b/EDSEditorGUI2/EDSEditorGUI2.csproj index ab887d37..0ad22a6d 100644 --- a/EDSEditorGUI2/EDSEditorGUI2.csproj +++ b/EDSEditorGUI2/EDSEditorGUI2.csproj @@ -15,16 +15,16 @@ - - - - + + + + - + - - - + + + diff --git a/GUITests/GUITests.csproj b/GUITests/GUITests.csproj index 499faeae..30130d0e 100644 --- a/GUITests/GUITests.csproj +++ b/GUITests/GUITests.csproj @@ -9,10 +9,16 @@ - - - - + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Tests/Tests.csproj b/Tests/Tests.csproj index 5fa46514..d8b94f2b 100644 --- a/Tests/Tests.csproj +++ b/Tests/Tests.csproj @@ -1,4 +1,4 @@ - + net481 net8.0 @@ -11,7 +11,7 @@ - + @@ -21,15 +21,18 @@ - - - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/libEDSsharp/CanOpenEDS.cs b/libEDSsharp/CanOpenEDS.cs index d4be60f6..ce431c62 100644 --- a/libEDSsharp/CanOpenEDS.cs +++ b/libEDSsharp/CanOpenEDS.cs @@ -387,7 +387,14 @@ public void Write(StreamWriter writer, InfoSection.Filetype ft, Odtype odt = Odt } writer.WriteLine(string.Format("ObjectType=0x{0:X}", (int)objecttype)); - writer.WriteLine(string.Format(";StorageLocation={0}", prop.CO_storageGroup)); + if (prop.CO_countLabel != "") + { + writer.WriteLine(string.Format(";CountLabel={0}", prop.CO_countLabel)); + } + if (prop.CO_storageGroup != "") + { + writer.WriteLine(string.Format(";StorageLocation={0}", prop.CO_storageGroup)); + } if (objecttype == ObjectType.ARRAY) { @@ -521,9 +528,9 @@ public void Parseline(string linex, int no) } } else - //Only allow our own extensions to populate the key/value pair { - if (key == "StorageLocation" || key == "TPDODetectCos") + //Only allow our own extensions to populate the key/value pair + if (key == "CountLabel" || key == "StorageLocation" || key == "TPDODetectCos") { try { @@ -618,6 +625,11 @@ public void ParseEDSentry(KeyValuePair> kvp) } //Access Type + if (kvp.Value.ContainsKey("CountLabel")) + { + od.prop.CO_countLabel = kvp.Value["CountLabel"]; + } + if (kvp.Value.ContainsKey("StorageLocation")) { od.prop.CO_storageGroup = kvp.Value["StorageLocation"]; @@ -825,8 +837,13 @@ public void Loadfile(string filename) int lineno = 1; foreach (string linex in System.IO.File.ReadLines(filename)) { - Parseline(linex, lineno); - lineno++; + try + { + Parseline(linex, lineno); + lineno++; + } + catch (Exception) { Warnings.warning_list.Add("Failed to open file \n" + filename);} + } di = new DeviceInfo(eds["DeviceInfo"]); diff --git a/libEDSsharp/CanOpenEDSMapping.cs b/libEDSsharp/CanOpenEDSMapping.cs index ce980ef3..8eef7c87 100644 --- a/libEDSsharp/CanOpenEDSMapping.cs +++ b/libEDSsharp/CanOpenEDSMapping.cs @@ -406,7 +406,6 @@ public OdSubObject.Types.AccessSDO Convert(EDSsharp.AccessType source, OdSubObje /// /// EDS accesstype /// protobuffer pdo access type - /// result object /// resolve context /// result public OdSubObject.Types.AccessPDO Convert(EDSsharp.AccessType source, OdSubObject.Types.AccessPDO destination, ResolutionContext context) diff --git a/libEDSsharp/CanOpenNodeExporter.cs b/libEDSsharp/CanOpenNodeExporter.cs index df728b8d..a5369c10 100644 --- a/libEDSsharp/CanOpenNodeExporter.cs +++ b/libEDSsharp/CanOpenNodeExporter.cs @@ -461,7 +461,24 @@ This file was automatically generated by CANopenEditor {0} https://github.com/CANopenNode/CANopenEditor DON'T EDIT THIS FILE MANUALLY !!!! -*******************************************************************************/", this.gitVersion)); +*******************************************************************************", this.gitVersion)); + file.WriteLine(" FILE INFO:"); + file.WriteLine(string.Format(" FileName: {0}", Path.GetFileName(eds.projectFilename))); + file.WriteLine(string.Format(" FileVersion: {0}", eds.fi.FileVersion)); + file.WriteLine(string.Format(" CreationTime: {0}", eds.fi.CreationTime)); + file.WriteLine(string.Format(" CreationDate: {0}", eds.fi.CreationDate)); + file.WriteLine(string.Format(" CreatedBy: {0}", eds.fi.CreatedBy)); + + file.WriteLine(""); + file.WriteLine(" DEVICE INFO:"); + file.WriteLine(string.Format(" VendorName: {0}", eds.di.VendorName)); + file.WriteLine(string.Format(" VendorNumber: {0}", eds.di.VendorNumber)); + file.WriteLine(string.Format(" ProductName: {0}", eds.di.ProductName)); + file.WriteLine(string.Format(" ProductNumber: {0}", eds.di.ProductNumber)); + file.WriteLine(string.Format(" RevisionNumber: {0}", eds.di.RevisionNumber)); + // file.WriteLine(string.Format(" OrderCode: {0}", eds.di.)); FixMe: Missing OrderCode + file.WriteLine("*******************************************************************************/"); + file.WriteLine(""); } private void export_h(string filename) @@ -503,28 +520,9 @@ CANopen DATA TYPES "); - file.WriteLine("/*******************************************************************************"); - file.WriteLine(" FILE INFO:"); - file.WriteLine(string.Format(" FileName: {0}", Path.GetFileName(eds.projectFilename))); - file.WriteLine(string.Format(" FileVersion: {0}", eds.fi.FileVersion)); - file.WriteLine(string.Format(" CreationTime: {0}", eds.fi.CreationTime)); - file.WriteLine(string.Format(" CreationDate: {0}", eds.fi.CreationDate)); - file.WriteLine(string.Format(" CreatedBy: {0}", eds.fi.CreatedBy)); - file.WriteLine("*******************************************************************************/"); - file.WriteLine(""); - file.WriteLine(""); - file.WriteLine("/*******************************************************************************"); - file.WriteLine(" DEVICE INFO:"); - file.WriteLine(string.Format(" VendorName: {0}", eds.di.VendorName)); - file.WriteLine(string.Format(" VendorNumber: {0}", eds.di.VendorNumber)); - file.WriteLine(string.Format(" ProductName: {0}", eds.di.ProductName)); - file.WriteLine(string.Format(" ProductNumber: {0}", eds.di.ProductNumber)); - file.WriteLine("*******************************************************************************/"); - file.WriteLine(""); - file.WriteLine(""); - file.WriteLine(@"/******************************************************************************* +file.WriteLine(@"/******************************************************************************* FEATURES *******************************************************************************/"); diff --git a/libEDSsharp/CanOpenNodeExporter_V4.cs b/libEDSsharp/CanOpenNodeExporter_V4.cs index 786bb9c1..ca359246 100644 --- a/libEDSsharp/CanOpenNodeExporter_V4.cs +++ b/libEDSsharp/CanOpenNodeExporter_V4.cs @@ -168,6 +168,7 @@ private void Prepare(EDSsharp eds) // Verify objects, if they have set correct "CO_countLabel", according to Object Dictionary Requirements By CANopenNode V4. // https://github.com/CANopenNode/CANopenNode/blob/master/doc/objectDictionary.md + VerifyCountLabel(od, 0x1000, 0x1000, "NMT"); VerifyCountLabel(od, 0x1001, 0x1001, "EM"); VerifyCountLabel(od, 0x1005, 0x1005, "SYNC"); @@ -198,7 +199,10 @@ private void VerifyCountLabel(ODentry od, ushort indexL, ushort indexH, string c { if (od.Index >= indexL && od.Index <= indexH && od.prop.CO_countLabel != countLabel) { - Warnings.AddWarning($"Error in 0x{od.Index:X4}: 'Count Label' must be '{countLabel}'", Warnings.warning_class.WARNING_BUILD); + Warnings.AddWarning($"Error in 0x{od.Index:X4}: missing 'Count Label' '{countLabel}', was added", Warnings.warning_class.WARNING_BUILD); + od.prop.CO_countLabel = countLabel; + + // ToDo Add "dirty" to indicate unsaved changes } } @@ -448,7 +452,7 @@ This file was automatically generated by CANopenEditor {0} gitVersion, odname, Path.GetFileName(eds.projectFilename), eds.fi.FileVersion, eds.fi.CreationDateTime, eds.fi.CreatedBy, eds.fi.ModificationDateTime, eds.fi.ModifiedBy, - eds.di.VendorName, eds.di.VendorNumber, eds.di.ProductName, eds.di.ProductNumber, + eds.di.VendorName, eds.di.VendorNumber, eds.di.ProductName, eds.di.ProductNumber, eds.di.RevisionNumber, eds.fi.Description)); file.WriteLine(string.Format(@" @@ -602,8 +606,33 @@ This file was automatically generated by CANopenEditor {0} https://github.com/CANopenNode/CANopenEditor DON'T EDIT THIS FILE MANUALLY, UNLESS YOU KNOW WHAT YOU ARE DOING !!!! -*******************************************************************************/ +******************************************************************************* + + File info: + File Names: {1}.h; {1}.c + Project File: {2} + File Version: {3} + + Created: {4} + Created By: {5} + Modified: {6} + Modified By: {7} + + Device Info: + Vendor Name: {8} + Vendor ID: {9} + Product Name: {10} + Product ID: {11} + Description: {12} +*******************************************************************************/", + gitVersion, odname, + Path.GetFileName(eds.projectFilename), eds.fi.FileVersion, + eds.fi.CreationDateTime, eds.fi.CreatedBy, eds.fi.ModificationDateTime, eds.fi.ModifiedBy, + eds.di.VendorName, eds.di.VendorNumber, eds.di.ProductName, eds.di.ProductNumber, eds.di.RevisionNumber, + eds.fi.Description)); + + file.WriteLine(string.Format(@" #define OD_DEFINITION #include ""301/CO_ODinterface.h"" #include ""{1}.h"" diff --git a/libEDSsharp/CanOpenXDD.cs b/libEDSsharp/CanOpenXDD.cs index 165036ca..96a515fc 100644 --- a/libEDSsharp/CanOpenXDD.cs +++ b/libEDSsharp/CanOpenXDD.cs @@ -310,6 +310,7 @@ public ISO15745ProfileContainer convert(EDSsharp eds) //device.DeviceIdentity.specificationRevision.value = device.DeviceIdentity.specificationRevision = new specificationRevision(); + device.DeviceIdentity.specificationRevision.Value = eds.di.RevisionNumber.ToHexString(); device.DeviceIdentity.specificationRevision.readOnly = true; device.DeviceIdentity.instanceName = new instanceName(); @@ -1160,6 +1161,7 @@ public EDSsharp convert(ISO15745ProfileContainer container) eds.di.ProductNumber = obj.DeviceIdentity.productID.Value; eds.di.VendorName = obj.DeviceIdentity.vendorName.Value; eds.di.VendorNumber = obj.DeviceIdentity.vendorID.Value; + uint.TryParse(obj.DeviceIdentity.specificationRevision.Value, out eds.di.RevisionNumber); foreach (object o in obj.DeviceIdentity.productText.Items) { diff --git a/libEDSsharp/CanOpenXDD_1_1.cs b/libEDSsharp/CanOpenXDD_1_1.cs index 5c682027..ac8e3df6 100644 --- a/libEDSsharp/CanOpenXDD_1_1.cs +++ b/libEDSsharp/CanOpenXDD_1_1.cs @@ -100,8 +100,16 @@ public EDSsharp ReadXML(string file) dev = (ISO15745ProfileContainer)serializer.Deserialize(reader); reader.Close(); } - catch (Exception) + catch (Exception e) { + if (e is System.InvalidOperationException) + { + Warnings.warning_list.Add(String.Format("{0} {1} Action aborted!", e.Message, e.InnerException.Message)); + } + else + { + Warnings.warning_list.Add(String.Format("{0} Action aborted!", e.ToString())); + } return null; } @@ -954,6 +962,7 @@ private ISO15745ProfileContainer Convert(EDSsharp eds, string fileName, bool dev body_device.DeviceIdentity = new DeviceIdentity(); body_device.DeviceIdentity.vendorName = new vendorName { Value = eds.di.VendorName }; body_device.DeviceIdentity.vendorID = new vendorID { Value = eds.di.VendorNumber }; + body_device.DeviceIdentity.specificationRevision = new specificationRevision { Value = eds.di.RevisionNumber.ToHexString()}; body_device.DeviceIdentity.productName = new productName { Value = eds.di.ProductName }; body_device.DeviceIdentity.productID = new productID { Value = eds.di.ProductNumber }; if (eds.fi.Description != null && eds.fi.Description != "") @@ -1256,6 +1265,8 @@ private EDSsharp Convert(ISO15745ProfileContainer container) eds.di.VendorName = body_device.DeviceIdentity.vendorName.Value ?? ""; if (body_device.DeviceIdentity.vendorID != null) eds.di.VendorNumber = body_device.DeviceIdentity.vendorID.Value ?? ""; + if (body_device.DeviceIdentity.specificationRevision != null) + uint.TryParse(body_device.DeviceIdentity.specificationRevision.Value , out eds.di.RevisionNumber) ; if (body_device.DeviceIdentity.productName != null) eds.di.ProductName = body_device.DeviceIdentity.productName.Value ?? ""; if (body_device.DeviceIdentity.productID != null) diff --git a/libEDSsharp/DocumentationGenMarkup.cs b/libEDSsharp/DocumentationGenMarkup.cs index 83fc7cd0..1b0d5804 100644 --- a/libEDSsharp/DocumentationGenMarkup.cs +++ b/libEDSsharp/DocumentationGenMarkup.cs @@ -104,7 +104,7 @@ Device Information | LSS Master | {8,-30} | | NG Slave | {9,-30} | | NG Master | {10,-30} | -", eds.di.VendorName, eds.di.VendorNumber, eds.di.ProductName, eds.di.ProductNumber, +", eds.di.VendorName, eds.di.VendorNumber, eds.di.ProductName, eds.di.ProductNumber, eds.di.RevisionNumber, eds.di.Granularity, eds.di.NrOfRXPDO.ToString(), eds.di.NrOfTXPDO.ToString(), eds.di.LSS_Supported, eds.di.LSS_Master, eds.di.NG_Slave, eds.di.NG_Master)); diff --git a/libEDSsharp/PDOHelper.cs b/libEDSsharp/PDOHelper.cs index 1b71d0db..181ae27e 100644 --- a/libEDSsharp/PDOHelper.cs +++ b/libEDSsharp/PDOHelper.cs @@ -366,8 +366,13 @@ void build_PDOlist(UInt16 startIdx, List slots) } else maptarget.entry = eds.ods[pdoindex].Getsubobject(pdosub); - - if ((maptarget.entry.prop.CO_disabled == false) && + // Check if mapped sub index was found in OD + if (maptarget.entry == null) + { + Console.WriteLine("MAPPING FAILED, OBJEKT NOT FOUND"); + continue; + } + else if ((maptarget.entry.prop.CO_disabled == false) && (datasize <= maptarget.entry.Sizeofdatatype()) && (datasize > 0)) { diff --git a/libEDSsharp/docs/libEDSsharp.xml b/libEDSsharp/docs/libEDSsharp.xml new file mode 100644 index 00000000..35b5c105 --- /dev/null +++ b/libEDSsharp/docs/libEDSsharp.xml @@ -0,0 +1,7054 @@ + + + + libEDSsharp + + + + + Section of info in EDS or DCF file + + + + + Write object to stream + + stream to write the data to + file type + + + + Returns a string that represents the current object. + + A string that represents the current object. + + + + Write object to stream + + stream to write the data to + + + + Returns a string that represents the current object. + + A string that represents the current object. + + + + Write object to stream + + stream to write the data to + + + + Returns a string that represents the current object. + + A string that represents the current object. + + + + FileInfo section as described in CiA 306 + + + FileInfo section as described in CiA 306 + + + + + indicate the file name (according to OS restrictions) + + + + + indicate the actual file version (Unsigned8) + + + + + indicate the actual file revision (Unsigned8) + + + + + indicate the version of the specification (3 characters) in the format x.y + + + + + file description (max 243 characters) + + + + + file creation time (characters in format hh:mm(AM|PM)), + + + + + provide the date of file creation (characters in format mm-dd-yyyy) + + + + + name or a description of the file creator (max. 245 characters) + + + + + time of last modification (characters in format hh:mm(AM|PM)) + + + + + date of the last file modification (characters in format mm-dd-yyyy) + + + + + name or a description of the creator (max. 244 characters) + + + + + DeviceInfo section as described in CiA 306 + + + + + vendor name (max. 244 characters) + + + + + unique vendor ID according to identity object sub-index 01h (Unsigned32) + + + + + product name (max. 243 characters) + + + + + product code according to identity object sub-index 02h (Unsigned32) + + + + + product revision number according to identity object sub-index 03h (Unsigned32) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the supported baud rates (Boolean, 0 = not supported, 1=supported) + + + + + indicate the simple boot-up master functionality (Boolean, 0 = not supported, 1 = supported), + + + + + indicate the simple boot-up slave functionality (Boolean, 0 = not supported, 1 = supported), + + + + + granularity allowed for the mapping on this device - + most of the existing devices support a granularity of 8 (Unsigned8; 0 - mapping not modifiable, 1-64 granularity) + + + + + Indicate the facility of dynamic variable generation. If the value is unequal to 0, the additional section DynamicChannels exists (CiA302 and CiA405) + + + + + indicate the facility of multiplexed PDOs. (Boolean, 0 = not supported, 1 = supported) + + + + + indicate the number of supported receive PDOs. (Unsigned16) + + + + + indicate the number of supported transmit PDOs. (Unsigned16) + + + + + indicate if LSS functionality is supported (Boolean, 0 = not supported, 1 = supported) + + + + + Represent object dictionary index and subindex objects + + + + + Write out this Object dictionary entry to an EDS/DCF file using correct formatting + + Handle to the stream writer to write to + File type being written + OD type to write + module + + + + The index of the object in the Object Dictionary + This cannot be set for child objects, if you read a child object you get the parents index + + + + + object type var,rec, array etc. + + + + + data type bool, integer etc. + + + + + access type + + + + + default value + + + + + low numeric limit + + + + + high numeric limit + + + + + actual value + + + + + true if it is PDO mapping object + + + + + Used when writing out objects to know if we are writing the normal or the module parts out + Two module parts subext and fixed are available. + + + + + Empty object constructor + + + + + ODentry constructor for a simple VAR type + + Name of Object Dictionary Entry + Index of object in object dictionary + Type of this objects data + Default value (always set as a string) + Allowed CANopen access permissions + Allowed PDO mapping options + + + + ODConstructor useful for subobjects + + + NOT USED + + + + + + + + + ODEntry constructor for array subobjects + + + + + + + + Make a deep clone of this ODentry + + + + + + Provide a simple string representation of the object, only parameters index, no subindexes/subindex parameter name and data type are included + Useful for debug and also appears in debugger when you inspect this object + + string summary of object + + + + Provide a simple string representation of the object type. Returns the string of the ENUM ObjectType.VAR if objecttype is not enumed + + string representation of object type + + + + Duplicate current sub entry and add it to parent + + true on successfull addition + + + + Remove current sub entry + + Renumber subentries + true on successfull removal + + + + If data type is an octet string we must remove all spaces when writing out to a EDS/DCF file + + Value to be processed + value if not octet string or value with spaces removed if octet string + + + + Returns a c compatible string that represents the name of the object, - is replaced with _ + words separated by a space are replaced with _ for a separator eg ONE TWO becomes ONE_TWO + + + + + + Return the size in bits for the given CANopen datatype of this object, eg the size of what ever the datatype field is set to + + no of bits + + + + This is the no of subindexes present in the object, it is NOT the maximum subobject index + + + + + Returns default value for a subindex + + subindex to get the default value for + default value for that subindex or "" if the subindex was not found + + + + Returns true if the object contains a subindex + + the subindex to look for + true if it contains the subindex + + + + Return max indicated subindex, or null if not array or record + + + + + + Subindex of this object if it is a subindex object, 0 if not + + + + + Look for a entry in the subindexs, return the index if found + + the OD entry to look for in the subindex objects + the subindex if found or 0 if not found + + + + Add an existing entry as a subobject of this OD + + + + + + + This function scans the PDO list and compares it to NrOfRXPDO and NrOfTXPDO + if these do not match in count then implicit PDOs are present and they are + filled in with default values from the lowest possible index + + + + + File name, when project is opened in xdd_v1.1 or project is saved + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Verify PDO mapping parameters in Object Dictionary. Every mapped OD entry must exist and mapping must be allowed + + List of error strings, empty if no errors found. + + + + Convert two bytes into Uint16 (big endian) + + bytes to convert to Uint16, only the 2 first will be used + value of the 2 bytes combined (big endian) + + + + Try to convert a string to UInt16 + + string containing a number + the value or 0 if unable to read it + + + + Try to convert a string to UInt32 + + string containing a number + the value or 0 if unable to read it + + + + Return number base of a string (10 for desimal, 16 for hex and 8 for octal) + + a string that will be read to try to find its base number + 16 if hex, 8 if octal else 10 + + + + Split on + , replace $NODEID with concrete value and add together + + input string containing a number maybe prefixed by $NODEID+ + if $NODEID is in the string + + + + + Try to get a OD entry + + the index + null if not found + true if found, false if not + + + + Return the number of enabled objects + + Include subindexes in the counting + + + + + Conversion class to/from EDS to protobuffer + + + + + Converts from protobuffer to EDS + + protobuffer device + new EDS device containing data from protobuffer device + + + + Converts from EDS to protobuffer + + EDS device + protobuffer device containing data from EDS + + + + Helper class to convert EDS date and time into datetime used in the protobuffer timestand (datetime) + + + + + Resolver to convert eds date and time into protobuffer timestamp (datetime) + + source EDS fileinfo object + protobuffer fileinfo object + result object + resolve context + result + + + + Helper class to convert object type enum + + Checkout AutoMapper.Extensions.EnumMapping when .net framework is gone + + + + Resolver to convert object types + + EDS object type object + protobuffer object type + result object + resolve context + result + + + + Resolver to convert object types + + EDS object type object + protobuffer object type + result object + resolve context + result + + + + Helper class to convert Access types + + Checkout AutoMapper.Extensions.EnumMapping when .net framework is gone + + + + Resolver to convert eds access into SDO access type + + EDS accesstype + protobuffer sdo access type + result object + resolve context + result + + + + Resolver to convert eds access into PDO access type + + EDS accesstype + protobuffer pdo access type + result object + resolve context + result + + + + Resolver to convert SDO access type into eds access into + + protobuffer sdo access type + EDS accesstype + result object + resolve context + result + + + + + Export .c and .h files for CanOpenNode v1-3 + + + + + The eds file set when calling export + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Register names of index and subindex that need to have standard names to be able to work with CanOpenNode + + + + + Export eds into CanOpenNode v1-3 source files (.h and .c) + + filepath, .c and .h will be added to this to make the mulitiple files + the eds data to be exported + + + + Fixes TPDO compatibility subindex + + Handle the TPDO communication parameters in a special way, because of + sizeof(OD_TPDOCommunicationParameter_t) != sizeof(CO_TPDOCommPar_t) in CANopen.c + the existing CO_TPDOCommPar_t has a compatibility entry so we must export one regardless of if its in the OD or not + + + + + + + + + + + Returns true of object is not disabled + + index to check + true if index object is not disabled + + + + Return the header part of one object dictionary entry + + the OD entry + part of the C header file that impliments the od entry + + + + Returns the c code related to a single object dictionary entry + + the OD entry + string containing c code for the OD entry + + + + Get the CANopenNode specific flags, these flags are used internally in CANopenNode to determine details about the object variable + + An odentry to access + byte containing the flag value + + + + Generates a valid C language variable name using input + + base name that will be used to make a variable name + the OD entry for the variable + + + + + Export the record type objects in the CO_OD.c file + + string + + + + Exports a sub object line in a record object + + sub ODentry object to export + string forming current array level or empty string for none + string forming one line of CO_OD.c record objects + + + + Exporter for CanOpenNode_V4 + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + export the current data set in the CanOpen Node format V4 + + filepath, .c and .h will be added to this to make the mulitiple files + + + + + Generate ODStorage, ODObjs, ODList, ODDefines and ODCnt entries + + EDS object + + + + Verify "Count Label" of the object and raise warning if uncorrect. + + + + + + + + + + Generate ODStorage and ODObjs entries for VAR + + + + + + + + + + Generate ODStorage and ODObjs entries for ARRAY + + + + + + + + + + Generate ODStorage and ODObjs entries for RECORD + + + + + + + + + + Export the header file + + path to folder that will contain the file + filename + git version that will be added to file comment + data that contain the data that will be exported + + + + Export the c file + + path to folder that will contain the file + filename + git version that will be added to file comment + data that contain the data that will be exported + + + + Take a paramater name from the object dictionary and make it acceptable + for use in c variables/structs etc + + string, name to convert + string + + + + Return from Get_dataProperties + + + + + Get the correct c data type, length and default value, based on CANopen data type + + + + + + Structure filled with data + + + + Get attributes from OD entry or sub-entry + + + + + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Convert to/from EDSsharp and CanOpenXDD v1.1, it uses the generated source file CanOpenXSD_1_1 + + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Read XDD file into EDSsharp object + + Name of the xdd file + EDSsharp object + + + + Read custom multi xdd file (multiple standard xdd files inside one xml container) + + Name of the multi xdd file + List of EDSsharp objects + + + + Write custom multi xdd file (multiple standard xdd files inside one xml container) + + Name of the multi xdd file + List of EDSsharp objects + If true, device commisioning, denotations and actual values will be included + + + + Write XDD file from EDSsharp object + + Name of the xdd file + EDSsharp object + If true, device commisioning, denotations and actual values will be included + If true, then all CANopenNode specific parameters and all disabled objects will be stripped + + + + Read protobuffer file into EDSsharp object + + Name of the protobuffer file + read as JSON string or binary wireformat + EDSsharp object + + + + Write protobuffer file from EDSsharp object + + Name of the protobuffer file + EDSsharp object + write as JSON string or binary wireformat + + + + Documentation generator + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Generate html documentation + + where the documentation should be saved + data to generate the documentation from + + + + Write a object dictionary html entry to file + + Object dictionary entry + + + + Write a html table row with 2 elements to file + + element a + element b + + + + Write a html table header with 2 elements to file + + + + + + + Returns the datatype of a object dictionary + + the object dictionary entry + datatype of the OD entry + + + + Documentation generator + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Generate markup documentation + + where the documentation should be created + data to generate the documentation from + + + + Write a all PDO information in markup + + data containing the information + skip disabled PDOs + + + + Write a object dictionary markup entry to file + + Object dictionary entry + + + + Returns the datatype of a object dictionary + + the object dictionary entry + datatype of the OD entry + + + + Object dictionary data types from CiA 301 + + + + + Object Dictionary object definitions from CiA 301 + + + + + An object with no data fields + + + + + Large variable amount of data e.g. executable program code + + + + + Denotes a type definition such as a BOOLEAN, UNSIGNED16, FLOAT and so on + + + + + Defines a new record type e.g. the PDO mapping structure at 21h + + + + + A single value such as an UNSIGNED8, BOOLEAN, FLOAT, INTEGER16, VISIBLE STRING etc. + + + + + A multiple data field object where each data field is a + simple variable of the SAME basic data type e.g. array of UNSIGNED16 etc. + Sub-index 0 is of UNSIGNED8 and therefore not part of the ARRAY data + + + + + A multiple data field object where the data fields may be any combination of + simple variables. Sub-index 0 is of UNSIGNED8 and sub-index 255 is of UNSIGNED32 and + therefore not part of the RECORD data + + + + + Defines how the object can be changed from SDO + + + + + no access + + + + + read only access + + + + + write only access + + + + + read and write access + + + + + Defines how the object can be changed from PDO + + + + + no access + + + + + TPDO access + + + + + RPDO access + + + + + TPDO and RPDO access + + + + + Custom properties for OD entry or sub-entry, which are saved into xdd file v1.1 + + + + + If true, object is completelly skipped by CANopenNode exporters, etc. + + + + + CanOpenNode storage group + + + + + Minimum length of a string that can be stored + + + + + Deep clone + + a deep clone + + + + Convert from XSD to EDS + + raw custom properties from XSD + + + + Convert custom properties from EDS to XSD + + XSD properties ready to use + + + + List of multiple CO_storageGroup strings available in project + + + + + Indicate that it should be exported in EDS files and may have some data about how + + + + + Max length of the string when exported + + + + + default constructor + + + + + contstructor with max string length + + max length of the string when exported + + + + Indicate that it should be exported in DCF files + + + + + Factory for making different canopennode exporter + + + + + CanOpenNode exporter types + + + + + CanOpenNode exporter v4 (latest) + + + + + CanOpenNode exporter for v1-3 (legacy) + + + + + Returns exporter based on ex parameter + + what exporter version you want. Default is CANOPENNODE_LEGACY + A exporter + + + + Helper functions to convert integral values into hexadecimal string + + + + + returns a string containing the value as hexadecimal + + the value + hexadecimal string representing the value + + + + returns a string containing the value as hexadecimal + + the value + hexadecimal string representing the value + + + + returns a string containing the value as hexadecimal + + the value + hexadecimal string representing the value + + + + String extension methodes + + + + + Performs a case insensitive Contain function + + the string to look in + the string to look for + comparison methode + true if substring is found in str + substring was null + comp methode was not a valid argument + This can be replaced with native .net function in .net core + + + + + Unified interface to all filetypes supported by the library + + + + + Returns description of all the different filetypes that can be exported to + + optional filter to filter out different types of exporters + list of file exporter that matches the filter + + + + Interface for exporting CanOpenNode OD files + + + + + Export file(s) + + filepath, .c and .h will be added to this to make the mulitiple files + The eds that will be exported + + + + Includes all info about a exporter that is needed to show user and call it + + + + + Export eds(s) to file(s) + + path path that should indicate where and what name the outputed file(s) should have + list of eds(s) not all support multiple edss, in that case use the first + + + + True if exporter will expect multiple edss + + + + + Documentation related + + + + + CanOpenNode related + + + + + short human readable description + + + + + What file extension the exported file(s) will have + + + + + Used to indicated different types of exporters + + + + + The function that is exporting to file + + + + + constructor that sets all the values + + short human readable description + What file extension the exported file(s) will have + Used to indicated different types of exporters + The function that is exporting to file + + + + Interface for exporters + + + + + Fetches all the different fileexporter types the class supports + + List of the different exporters the class supports + + + + Generate a PDO network report + + + + + Generate a PDO network report + + where the doc should be saved + Data from the different nodes in the network + + + + Write a html table row with 2 elements to file + + element a + element b + + + + Write a html table header with 2 elements to file + + + + + + + Represent a PDO slot (mapping + communication index) + + + + + Indicate that $NODEID is present and the COB-ID should added to the node id when deployed + + + + + The OD index of the PDO configuration (aka. communication parameter) + + + + + The OD index of the PDO mapping + + + + + PDO Mapping access + + + + + PDO Configuration (aka. communication parameter) access + + + + + PDO mapping CanOpenNode storage group + + + + + PDO config CanOpenNode storage group + + + + + PDO COB-ID + + + + + Returns if true the PDO is a TxPDO (aka TPDO) + + true if TXPDO + + + + Returns if true the PDO is a RxPDO (aka RPDO) + + true if RxPDO + + + + PDO invalid bit value + + + + + PDO mapping + + + + + PDO inhibit time,multiple of 100us + + + + + PDO event time,multiple of 1ms + + + + + PDO sync start value + + + + + PDO transmission type + + + + + Description of PDO communication index (aka configuration) + + + + + Description of PDO mapping index + + + + + default constructor + + + + + Returns name of a OD entry (including dummy) + + object dictionary entry + name of entry with index and subindex prefixed, or blank string if not found + + + + Insert a OD entry into the mapping table + + The zero-based index at which item should be inserted + OD entry to be mapped + + + + PDO helper class, control all TPDO and RPDO in a node + + + + + Constructor + + eds data to interact with + + + + List of all T/R PDO + + + + + Why is this not called from constructor? + + + + + Look through the OD and register PDO + + OD index to to start looking from, it will stop after 0x1ff indexes + list to add found pdo into + + + + Rebuild the communication and mapping paramaters from the + lists the PDOhelper currently has. These live in the list pdoslots + + + + + Add a PDO slot as set by index + + + + + + This finds a gap in the PDO slots + + + + + Remove existing PDO slot as set by index + + + + + + Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. + + + + + Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. + + + + + Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle + Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden. + + + + + Provides string escape and unescape functions + + + + + Convert litteral special characters like null and tab etc. into there escape sequence '\0' '\t' + + the spesial character to convert into escape sequence + a string containing the escape sequence or c if noe escape sequence was found + + + + Logger class used to report problems with import/export + + + + + type of warnings + + + + + Generic warning + + + + + index/subindex rename warnings + + + + + problem with index/subindexes that are needed to make canopennode functions work + + + + + Problem with strings variable export + + + + + Problem with struct/record export + + + + + List of warnings + + + + + bit mask used to stop messages being added to the list + + + + + Add warning to the list of warnings + + string to report + type of warning (filter usage) + + + + XDD version + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Holder for reflection information generated from CanOpen.proto + + + File descriptor for CanOpen.proto + + + + File information related properties. + + + + Field number for the "fileVersion" field. + + + + Actual file version (as string). + + + + Field number for the "description" field. + + + + File description. + + + + Field number for the "creationTime" field. + + + + File creation time. + + + + Field number for the "createdBy" field. + + + + Name or a description of the file creator. + + + + Field number for the "modificationTime" field. + + + + Time of the last modification. + + + + Field number for the "modifiedBy" field. + + + + Name or a description of the creator. + + + + + CANopen device information related properties. + + + + Field number for the "vendorName" field. + + + + Vendor name. + + + + Field number for the "productName" field. + + + + Product name. + + + + Field number for the "baudRate10" field. + + + + Support of the baud rate 10 kbit/s. + + + + Field number for the "baudRate20" field. + + + + Support of the baud rate 20 kbit/s. + + + + Field number for the "baudRate50" field. + + + + Support of the baud rate 50 kbit/s. + + + + Field number for the "baudRate125" field. + + + + Support of the baud rate 125 kbit/s. + + + + Field number for the "baudRate250" field. + + + + Support of the baud rate 250 kbit/s. + + + + Field number for the "baudRate500" field. + + + + Support of the baud rate 500 kbit/s. + + + + Field number for the "baudRate800" field. + + + + Support of the baud rate 800 kbit/s. + + + + Field number for the "baudRate1000" field. + + + + Support of the baud rate 1000 kbit/s. + + + + Field number for the "baudRateAuto" field. + + + + Support of the auto baud rate. + + + + Field number for the "lssSlave" field. + + + + Support of the LSS slave functionality. + + + + Field number for the "lssMaster" field. + + + + Support of the LSS master functionality. + + + + + Actual CANopen device properties. + + + + Field number for the "nodeId" field. + + + + CANopen device’s address. + + + + Field number for the "nodeName" field. + + + + Node name. + + + + Field number for the "baudrate" field. + + + + CANopen device’s baudrate. + + + + + Object Dictionary SubEntry on specific Subindex. Sorted dictionary of them is part of the OdEntry. If OdEntry + ObjectType is "record", then each SubEntry in the dictionary may be unique. If OdEntry ObjectType is "array", + then some properties of all SubEntries must be equal. If OdEntry ObjectType is "var", then one SubEntry exists. + + + + Field number for the "name" field. + + + + Name of the sub entry. If OdEntry is "VAR", this property is not relevant. + + + + Field number for the "alias" field. + + + + Additonal sub parameter name, for the actual device. If OdEntry is "VAR", this property is not relevant. + + + + Field number for the "dataType" field. + + + + CANopen data type + + + + Field number for the "sdo" field. + + + + CANopen SDO access permissions + + + + Field number for the "pdo" field. + + + + CANopen PDO access permissions + + + + Field number for the "srdo" field. + + + + CANopen SRDO access permissions. + + + + Field number for the "defaultValue" field. + + + + Default value of the sub object. + + + + Field number for the "actualValue" field. + + + + Actual value of the sub object, for the actual device. + + + + Field number for the "lowLimit" field. + + + + Low limit for the value. + + + + Field number for the "highLimit" field. + + + + High limit for the value. + + + + Field number for the "stringLengthMin" field. + + + + CanOpenNode OD exporter V4: Minimum length of a string that can be stored. + + + + Container for nested types declared in the OdSubObject message type. + + + + Object dictionary basic data types from CiA 301. + + + + + Unspecified, should not be used. + + + + + Boolean. + + + + + 8-bit signed integer. + + + + + 16-bit signed integer. + + + + + 32-bit signed integer. + + + + + 8-bit unsigned integer. + + + + + 16-bit unsigned integer. + + + + + 32-bit unsigned integer. + + + + + 32-bit floating point number. + + + + + Null terminated string (8-bit chars). It may contain control characters and UTF-8 + characters. StringLengthMin specifies minimum buffer length for the string. + + + + + Fixed length array of bytes. + + + + + Null terminated string (16-bit chars). Not recommended to use. + StringLengthMin specifies minimum buffer length for the string. + + + + + 48 bit long structure. + + + + + 48 bit long structure. + + + + + Data block of any length, don't have default value. + + + + + 24-bit signed integer, should not be used. + + + + + 64-bit floating point number. + + + + + 40-bit signed integer, should not be used. + + + + + 48-bit signed integer, should not be used. + + + + + 56-bit signed integer, should not be used. + + + + + 64-bit signed integer. + + + + + 24-bit unsigned integer, should not be used. + + + + + 40-bit unsigned integer, should not be used. + + + + + 48-bit unsigned integer, should not be used. + + + + + 56-bit unsigned integer, should not be used. + + + + + 64-bit unsigned integer. + + + + + CANopen SDO access permissions. + + + + + No access. + + + + + Read only access. + + + + + Write only access. + + + + + Read and write access. + + + + + CANopen PDO access permissions. + + + + + No access. + + + + + TPDO access. + + + + + RPDO access. + + + + + TPDO and RPDO access. + + + + + CANopen SRDO access permissions. + + + + + no access. + + + + + SRDO TX access. + + + + + SRDO RX access. + + + + + SRDO TX or RX access. + + + + + Object Dictionary Entry on specific Index. Sorted dictionary of them is part of CanOpenDevice - CANopen Object Dictionary. + + + + Field number for the "disabled" field. + + + + If true, object is completelly skipped by CANopenNode exporters, etc. + + + + Field number for the "name" field. + + + + Name of the entry. + + + + Field number for the "alias" field. + + + + Additonal parameter name, for the actual device. + + + + Field number for the "description" field. + + + + Description of the Entry. + + + + Field number for the "objectType" field. + + + + CANopen Object Type. + + + + Field number for the "countLabel" field. + + + + CanOpenNode OD exporter V4: it will generate a macro for each different CO_countLabel. For example, if four + OD objects have "CO_countLabel" set to "TPDO", then macro "#define ODxyz_CNT_TPDO 4" will be generated by the OD exporter. + + + + Field number for the "storageGroup" field. + + + + CanOpenNode OD exporter V4: storage group into which the C variable will belong. If not defined, it will default to "RAM". + + + + Field number for the "flagsPDO" field. + + + + CanOpenNode OD exporter V1.3: Flags for the PDO. + + + + Field number for the "subObjects" field. + + + + Sorted dictionary of sub entries + + + + Container for nested types declared in the OdObject message type. + + + + Type of Object Dictionary entry, similar as Object Code from CiA 301. + + + + + Not defined, default + + + + + A single value such as an UNSIGNED8, BOOLEAN, FLOAT, INTEGER16, VISIBLE STRING etc. + + + + + A multiple data field object where each data field is a simple variable of the SAME basic data type e.g. array + of UNSIGNED16 etc. Sub-index 0 is of UNSIGNED8. + + + + + A multiple data field object where the data fields may be any combination of + simple variables. Sub-index 0 is of UNSIGNED8 and sub-index 255 is of UNSIGNED32. + + + + + CANopen Device description object. + + + + Field number for the "fileInfo" field. + + + + File information related properties. + + + + Field number for the "deviceInfo" field. + + + + CANopen device information related properties. + + + + Field number for the "deviceCommissioning" field. + + + + Parameters of the actual CANopen device. + + + + Field number for the "objects" field. + + + + CANopen Object Dictionary as sorted dictionary. + + + + diff --git a/libEDSsharp/eds.cs b/libEDSsharp/eds.cs index 0530d652..d5885bb8 100644 --- a/libEDSsharp/eds.cs +++ b/libEDSsharp/eds.cs @@ -1281,7 +1281,32 @@ public void AccessPDO(AccessPDO accessPDO) break; } } + /// + /// Incremement number at end of string by given increment + /// + /// SubObject name as string to increment + /// increment for next SubObject + /// incremented name or the original string if no number is found at the end + public static string IncrementNumberAtEnd(string input, int increment) + { + // Regex to match the last token if it's a number + Regex regex = new Regex(@"(\d+)$"); + Match match = regex.Match(input); + + if (match.Success) + { + // Extract the number and increment it + int number = int.Parse(match.Value); + number += increment; + // Replace the old number with the new number + string result = regex.Replace(input, number.ToString()); + return result; + } + + // Return the original string if no number is found at the end + return input; + } /// /// Duplicate current sub entry and add it to parent /// @@ -1341,8 +1366,11 @@ public ODentry AddSubEntry() newSubObjects.Add(newSubIndex++, subOd); - if (originalOd == subOd) - newSubObjects.Add(newSubIndex++, newOd); + if (lastSubOd == subOd) { + newSubObjects.Add(newSubIndex, newOd); + // Auto increment if the parameter name has a number at the end + newSubObjects[newSubIndex].parameter_name = IncrementNumberAtEnd(newSubObjects[(ushort)(newSubIndex-1)].parameter_name, 1); + } } if (originalOd == null) newSubObjects.Add(newSubIndex++, newOd); diff --git a/libEDSsharp/libEDSsharp.csproj b/libEDSsharp/libEDSsharp.csproj index 3e443832..04edf6ee 100644 --- a/libEDSsharp/libEDSsharp.csproj +++ b/libEDSsharp/libEDSsharp.csproj @@ -18,7 +18,7 @@ - + @@ -44,9 +44,9 @@ - - - + + +