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 @@
-
-
-
+
+
+