public void TestArrays() { ODentry od = new ODentry { objecttype = ObjectType.ARRAY, datatype = DataType.VISIBLE_STRING, parameter_name = "Test Array", accesstype = EDSsharp.AccessType.ro, Index = 0x2000 }; eds = new EDSsharp { ods = new System.Collections.Generic.SortedDictionary <ushort, ODentry>() }; eds.ods.Add(0x2000, od); prewalkArrays(); od.subobjects.Add(0x00, new ODentry("No Entries", 0x00, DataType.UNSIGNED8, "4", EDSsharp.AccessType.ro, PDOMappingType.no)); od.subobjects.Add(0x01, new ODentry("LINE1", 0x01, DataType.VISIBLE_STRING, new string('*', 1), EDSsharp.AccessType.ro, PDOMappingType.optional)); od.subobjects.Add(0x02, new ODentry("LINE1", 0x02, DataType.VISIBLE_STRING, new string('*', 10), EDSsharp.AccessType.ro, PDOMappingType.optional)); od.subobjects.Add(0x03, new ODentry("LINE1", 0x03, DataType.VISIBLE_STRING, new string('*', 16), EDSsharp.AccessType.ro, PDOMappingType.optional)); od.subobjects.Add(0x04, new ODentry("LINE1", 0x04, DataType.VISIBLE_STRING, new string('*', 32), EDSsharp.AccessType.ro, PDOMappingType.optional)); string test = print_h_entry(od); if (test != "/*2000 */ VISIBLE_STRING testArray[32][4];" + Environment.NewLine) { throw (new Exception("TestArrays() test 1 failed")); } }
private void addSubItemToolStripMenuItem_Click(object sender, EventArgs e) { if (selecteditemsub.Tag != null) { ODentry od = (ODentry)selecteditemsub.Tag; if (od.parent != null) { od = od.parent; } if (od.objecttype == ObjectType.ARRAY) { ODentry newsub = new ODentry(); newsub.parent = od; newsub.datatype = od.datatype; newsub.accesstype = od.accesstype; newsub.PDOtype = od.PDOtype; newsub.index = od.index; newsub.objecttype = ObjectType.VAR; newsub.subindex = (UInt16)od.subobjects.Count; od.subobjects.Add((UInt16)(od.subobjects.Count), newsub); UInt16 def = EDSsharp.ConvertToUInt16(od.subobjects[0].defaultvalue); def++; od.subobjects[0].defaultvalue = def.ToString(); } if (od.objecttype == ObjectType.REC) { DataType dt = od.datatype; NewIndex ni = new NewIndex(eds, dt, od.objecttype, od); if (ni.ShowDialog() == DialogResult.OK) { ODentry newsub = new ODentry(); newsub.parent = od; newsub.datatype = ni.dt; newsub.accesstype = od.accesstype; newsub.PDOtype = od.PDOtype; newsub.index = od.index; newsub.objecttype = ObjectType.VAR; newsub.subindex = (UInt16)od.subobjects.Count; newsub.parameter_name = ni.name; od.subobjects.Add((UInt16)(od.subobjects.Count), newsub); UInt16 def = EDSsharp.ConvertToUInt16(od.subobjects[0].defaultvalue); def++; od.subobjects[0].defaultvalue = def.ToString(); } } eds.dirty = true; updateselectedindexdisplay(selectedobject.index); validateanddisplaydata(); } }
public void Test_record_objects() { ODentry od = new ODentry { objecttype = ObjectType.REC, parameter_name = "Test Record", accesstype = EDSsharp.AccessType.ro, Index = 0x2000 }; ODentry subod = new ODentry("Test String 1", 0x2000, DataType.VISIBLE_STRING, "abcdefg", EDSsharp.AccessType.rw, PDOMappingType.optional, od); string test = export_one_record_type(subod, ""); if (test != " {(void*)&CO_OD_RAM.testRecord.testString1, 0x3e, 0x7 }," + Environment.NewLine) { throw (new Exception("export_one_record_type() error test 1")); } subod = new ODentry("Test String 2", 0x01, DataType.VISIBLE_STRING, new string('*', 255), EDSsharp.AccessType.ro, PDOMappingType.optional, od); test = export_one_record_type(subod, ""); if (test != " {(void*)&CO_OD_RAM.testRecord.testString2, 0x26, 0xff }," + Environment.NewLine) { throw (new Exception("export_one_record_type() error test 2")); } }
private void updateselectedindexdisplay(UInt16 index, UInt16 mod) { selectedindexod = getOD(index, mod); currentmodule = mod; updateselectedindexdisplay(); }
public void Test_compact_array_object_loader() { List <string> AlwaysSet = new List <string>(); List <string> MandatorySet = new List <string>(); List <string> OptionalSet = new List <string>(); AlwaysSet.Add("CompactSubObj=5"); MandatorySet.Add("ParameterName=My Test Object"); MandatorySet.Add("ObjectType=0x0008"); MandatorySet.Add("DataType=0x0007"); MandatorySet.Add("AccessType=rw"); test_object_coverage(AlwaysSet, MandatorySet, OptionalSet); if (!ods.ContainsKey(0x2000)) { throw (new Exception("parseEDSentry() failed no object")); } ODentry od = ods[0x2000]; if (od.PDOMapping != false) { throw (new Exception("Default PDO not false")); } if (od.ObjFlags != 0) { throw (new Exception("Default objectflags not 0")); } }
private void listViewDetails_MouseClick(object sender, MouseEventArgs e) { ListViewItem lvi = listViewDetails.SelectedItems[0]; if (listViewDetails.SelectedItems.Count == 0) { return; } if (checkdirty()) { return; } selecteditemsub = lvi; ODentry od = (ODentry)lvi.Tag; if (e.Button == MouseButtons.Right) { ODentry parent = od; if (od.parent != null) { parent = od.parent; } if (parent.objecttype == ObjectType.ARRAY || parent.objecttype == ObjectType.REC) { if (od.subindex == 0 || od.parent == null) { contextMenu_array.Items[2].Enabled = false; } else { contextMenu_array.Items[2].Enabled = true; } //Only show the special subindex adjust menu for subindex 0 of arrays if ((od.parent != null) && (parent.objecttype == ObjectType.ARRAY) && (od.subindex == 0)) { contextMenu_array.Items[0].Enabled = true; contextMenu_array.Items[0].Visible = true; } else { contextMenu_array.Items[0].Enabled = false; contextMenu_array.Items[0].Visible = false; } if (listViewDetails.FocusedItem.Bounds.Contains(e.Location) == true) { contextMenu_array.Show(Cursor.Position); } } } selectedobject = od; validateanddisplaydata(); }
private void disableObjectToolStripMenuItem_Click(object sender, EventArgs e) { ListViewItem item = selecteditem; ODentry od = (ODentry)item.Tag; eds.dirty = true; od.Disabled = !od.Disabled; populateindexlists(); }
void addtolist(ODentry od, bool dcf, bool isemptydcf) { if (!dcf || isemptydcf) { string[] items = new string[7]; items[0] = string.Format("0x{0:x4}", od.Index); items[1] = string.Format("0x{0:x2}", od.Subindex); if (od.parent == null) { items[2] = od.parameter_name; } else { items[2] = od.parent.parameter_name + " -- " + od.parameter_name; } if (od.datatype == DataType.UNKNOWN && od.parent != null) { items[3] = od.parent.datatype.ToString(); } else { items[3] = od.datatype.ToString(); } items[4] = od.defaultvalue; items[5] = ""; // items[6] = od.actualvalue; ListViewItem lvi = new ListViewItem(items); // SDO sdo = lco.SDOread((byte)numericUpDown_node.Value, (UInt16)od.index, (byte)od.subindex, gotit); sdocallbackhelper help = new sdocallbackhelper(); help.sdo = null; help.od = od; lvi.Tag = help; listView1.Items.Add(lvi); } if (dcf) { adddcfvalue(od); } }
private void listView_TXCOBmap_MouseClick(object sender, MouseEventArgs e) { if (listView_TXCOBmap.SelectedItems.Count != 1) { return; } UInt16 index = Convert.ToUInt16(listView_TXCOBmap.SelectedItems[0].SubItems[1].Text, 16); UInt32 COB = Convert.ToUInt32(listView_TXCOBmap.SelectedItems[0].SubItems[0].Text, 16); ODentry od = eds.ods[index]; textBox_slot.Text = string.Format("0x{0:x4}", od.index); if (od.nosubindexes > 1) { textBox_cob.Text = od.subobjects[1].defaultvalue; } if (od.nosubindexes > 2) { textBox_type.Text = od.subobjects[2].defaultvalue; } if (od.nosubindexes > 3) { textBox_inhibit.Text = od.subobjects[3].defaultvalue; } if (od.nosubindexes > 5) { textBox_eventtimer.Text = od.subobjects[5].defaultvalue; } if (od.nosubindexes > 6) { textBox_syncstart.Text = od.subobjects[6].defaultvalue; } if (isTXPDO) { textBox_eventtimer.Enabled = true; textBox_inhibit.Enabled = true; textBox_syncstart.Enabled = true; } textBox_type.Enabled = true; textBox_cob.Enabled = true; button_deletePDO.Enabled = true; button_savepdochanges.Enabled = true; //Is invalid bit set checkBox_invalidpdo.Checked = ((COB & 0x80000000) != 0); }
byte getflags(ODentry od) { byte flags = 0; //aways return 0 for REC objects as CO_OD_getDataPointer() uses this to pickup the details if (od.objecttype == ObjectType.REC) { return(0); } flags = (byte)od.location; //fixme rwr and rrw are not supported if (od.accesstype == EDSsharp.AccessType.ro || od.accesstype == EDSsharp.AccessType.rw || od.accesstype == EDSsharp.AccessType.@const) { flags |= 0x04; } if (od.accesstype == EDSsharp.AccessType.wo || od.accesstype == EDSsharp.AccessType.rw) { flags |= 0x08; } if (od.PDOMapping) { flags |= 0x10; } if (od.PDOMapping) { flags |= 0x20; } if (od.PDOMapping) { flags |= 0x30; //fix me no control over rx and tx mapping, its both or none } if (od.TPDODetectCos) { flags |= 0x40; } int datasize = od.sizeofdatatype(); if (datasize > 1) { flags |= 0x80; } return(flags); }
void adddcfvalue(ODentry od) { foreach (ListViewItem lvi in listView1.Items) { sdocallbackhelper help = (sdocallbackhelper)lvi.Tag; if ((help.od.Index == od.Index) && (help.od.Subindex == od.Subindex)) { lvi.SubItems[6].Text = od.actualvalue; } } }
public void writeODentryhtml(ODentry od) { if (od.parent == null) { file.Write("<hr/>"); file.Write(String.Format("<h3>0x{0:x4} - {1}</h3>", od.index, od.parameter_name)); } else { file.Write(String.Format("<h3>0x{0:x4} sub 0x{2:x2} - {1}</h3>", od.index, od.parameter_name, od.subindex)); } file.Write("<table id=\"odentry\">"); write2linetableheader("Paramater", "Value"); ObjectType ot = od.objecttype; if (ot == ObjectType.UNKNOWN && od.parent != null) { ot = od.parent.objecttype; } write2linetablerow("Object Type", ot.ToString()); DataType dt = od.datatype; if (dt == DataType.UNKNOWN && od.parent != null) { dt = od.parent.datatype; } write2linetablerow("Data Type", dt.ToString()); write2linetablerow("Default Value", od.defaultvalue); write2linetablerow("Location", od.location.ToString()); write2linetablerow("Access type", od.accesstype.ToString()); write2linetablerow("PDO mapping", od.PDOMapping); write2linetablerow("No Sub index", od.nosubindexes); file.Write("</table>"); string description = od.Description; file.Write(string.Format("<pre>{0}</pre>", description)); foreach (KeyValuePair <UInt16, ODentry> sub in od.subobjects) { ODentry subod = sub.Value; writeODentryhtml(subod); } }
private void deleteObjectToolStripMenuItem_Click(object sender, EventArgs e) { ListViewItem item = selecteditem; ODentry od = (ODentry)item.Tag; //Check object is not used in a PDO before deleting for (UInt16 idx = 0x1600; idx < 0x1a00 + 0x01ff; idx++) { //Cheat as we want to only map 1600-17FF and 1a00-1bff if (idx == 0x1800) { idx = 0x1a00; } if (eds.ods.ContainsKey(idx)) { ODentry pdood = eds.ods[idx]; for (byte subno = 1; subno < pdood.Nosubindexes; subno++) { try { UInt16 odindex = Convert.ToUInt16(pdood.subobjects[subno].defaultvalue.Substring(0, 4), 16); if (odindex == od.Index) { MessageBox.Show(string.Format("Cannot delete OD entry it is mapped in PDO {0:4x}", pdood.Index)); return; } } catch (Exception) { //Failed to parse the PDO } } } } if (MessageBox.Show(string.Format("Really delete index 0x{0:x4} ?", od.Index), "Are you sure?", MessageBoxButtons.YesNo) == DialogResult.Yes) { eds.Dirty = true; if (currentmodule == 0) { eds.ods.Remove(od.Index); } populateindexlists(); } }
public ValueEditor(ODentry od, string currentval) { DialogResult = DialogResult.Cancel; InitializeComponent(); label_default.Text = od.defaultvalue; label_index.Text = string.Format("0x{0:x4}", od.Index); label_sub.Text = string.Format("0x{0:x2}", od.Subindex); label_name.Text = od.parameter_name; textBox_desc.Text = od.Description; textBox_current.Text = currentval; }
private void list_mouseclick(ListView listview, MouseEventArgs e) { if (listview.SelectedItems.Count == 0) { return; } if (checkdirty()) { return; } ListViewItem lvi = listview.SelectedItems[0]; UInt16 idx = Convert.ToUInt16(lvi.Text, 16); if (e.Button == MouseButtons.Right) { if (listview.FocusedItem.Bounds.Contains(e.Location) == true) { selecteditem = lvi; ODentry od = (ODentry)lvi.Tag; if (od.Disabled == true) { disableObjectToolStripMenuItem.Text = "Enable Object"; } else { disableObjectToolStripMenuItem.Text = "Disable Object"; } contextMenuStrip1.Show(Cursor.Position); } return; } updateselectedindexdisplay(idx); selectedobject = eds.ods[idx]; validateanddisplaydata(); listView_mandatory_objects.HideSelection = true; listView_manufacture_objects.HideSelection = true; listView_optional_objects.HideSelection = true; listview.HideSelection = false; }
private void saveDifferenceToolStripMenuItem_Click(object sender, EventArgs e) { SaveFileDialog odf = new SaveFileDialog(); odf.Filter = "(*.dcf)|*.dcf"; if (odf.ShowDialog() == DialogResult.OK) { // System.IO.StreamWriter file = new System.IO.StreamWriter(odf.FileName); //file.WriteLine("Object\tSub Index\tName\tDefault\tCurrent\t"); foreach (ListViewItem lvi in listView1.Items) { string index = lvi.SubItems[0].Text; string sub = lvi.SubItems[1].Text; string name = lvi.SubItems[2].Text; sdocallbackhelper help = (sdocallbackhelper)lvi.Tag; string defaultstring = help.od.defaultvalue; string currentstring = help.od.actualvalue; UInt16 key = Convert.ToUInt16(index, 16); UInt16 subi = Convert.ToUInt16(sub, 16); if (subi == 0) { eds.ods[key].actualvalue = currentstring; } else { ODentry subod = eds.ods[key].Getsubobject(subi); if (subod != null) { subod.actualvalue = currentstring; } } // file.WriteLine(string.Format("{0}\t{1}\t{2}\t{3}\t{4}",index,sub,name,defaultstring,currentstring)); } eds.Savefile(odf.FileName, InfoSection.Filetype.File_DCF); //file.Close(); } }
private void listViewDetails_SelectedIndexChanged(object sender, EventArgs e) { if (listViewDetails.SelectedItems.Count == 0) { return; } if (checkdirty()) { return; } ListViewItem lvi = listViewDetails.SelectedItems[0]; selecteditemsub = lvi; selectedobject = (ODentry)lvi.Tag; validateanddisplaydata(); }
private void listView_mandatory_objects_MouseClick(object sender, MouseEventArgs e) { ListViewItem lvi = listView_mandatory_objects.SelectedItems[0]; if (checkdirty()) { return; } UInt16 idx = Convert.ToUInt16(lvi.Text, 16); updateselectedindexdisplay(idx); selectedobject = eds.ods[idx]; validateanddisplaydata(); listView_mandatory_objects.HideSelection = false; listView_manufacture_objects.HideSelection = true; listView_optional_objects.HideSelection = true; }
private void addTXPDOoption(ODentry od) { TXchoices.Add(String.Format("0x{0:x4}/{1:x2}/", od.index, od.subindex) + od.parameter_name); ListViewItem lvi = new ListViewItem(String.Format("0x{0:x4}", od.index)); lvi.SubItems.Add(String.Format("0x{0:x2}", od.subindex)); lvi.SubItems.Add(od.parameter_name); DataType dt = od.datatype; if (dt == DataType.UNKNOWN || od.parent != null) { dt = od.parent.datatype; } lvi.SubItems.Add(dt.ToString()); lvi.Tag = (object)od; listView_TXPDO.Items.Add(lvi); }
private void removeSubItemleaveGapToolStripMenuItem_Click(object sender, EventArgs e) { if (selecteditemsub.Tag != null) { ODentry od = (ODentry)selecteditemsub.Tag; if (od.parent.objecttype == ObjectType.ARRAY || od.parent.objecttype == ObjectType.REC) { UInt16 count = EDSsharp.ConvertToUInt16(od.parent.subobjects[0].defaultvalue); if (count > 0) { count--; } od.parent.subobjects[0].defaultvalue = count.ToString(); } bool success = od.parent.subobjects.Remove(od.Subindex); /* * UInt16 countx = 0; * * SortedDictionary<UInt16, ODentry> newlist = new SortedDictionary<ushort, ODentry>(); * * foreach (KeyValuePair<UInt16, ODentry> kvp in od.parent.subobjects) * { * ODentry sub = kvp.Value; * newlist.Add(countx, sub); * countx++; * } * * od.parent.subobjects = newlist; */ eds.Dirty = true; updateselectedindexdisplay(selectedobject.Index, currentmodule); validateanddisplaydata(); } }
private void changeMaxSubIndexToolStripMenuItem_Click(object sender, EventArgs e) { //Change the max subindex, it is allowed to have a different max subindex to the physical array size //as depending on implementation it might not be a simple array behind the scenes. Even 0x1010,0x1011 //do this on their implementation in CanopenNode if (selecteditemsub.Tag != null) { ODentry od = (ODentry)selecteditemsub.Tag; if (od.parent.objecttype == ObjectType.ARRAY && od.subindex == 0) { MaxSubIndexFrm frm = new MaxSubIndexFrm(od.nosubindexes); if (frm.ShowDialog() == DialogResult.OK) { od.defaultvalue = string.Format("0x{0:x2}", frm.maxsubindex); updateselectedindexdisplay(selectedobject.index); validateanddisplaydata(); } } } }
private void removeSubItemToolStripMenuItem_Click(object sender, EventArgs e) { if (selecteditemsub.Tag != null) { ODentry od = (ODentry)selecteditemsub.Tag; if (od.parent.objecttype == ObjectType.ARRAY) { UInt16 count = EDSsharp.ConvertToUInt16(od.parent.subobjects[0].defaultvalue); if (count > 0) { count--; } od.parent.subobjects[0].defaultvalue = count.ToString(); } bool success = od.parent.subobjects.Remove(od.subindex); UInt16 countx = 0; SortedDictionary <UInt16, ODentry> newlist = new SortedDictionary <ushort, ODentry>(); foreach (KeyValuePair <UInt16, ODentry> kvp in od.parent.subobjects) { ODentry sub = kvp.Value; sub.subindex = countx; newlist.Add(countx, sub); countx++; } od.parent.subobjects = newlist; eds.dirty = true; updateselectedindexdisplay(selectedobject.index); validateanddisplaydata(); } }
public void Test_array_object_loader() { List <string> AlwaysSet = new List <string>(); List <string> MandatorySet = new List <string>(); List <string> OptionalSet = new List <string>(); MandatorySet.Add("ParameterName=My Test Object"); MandatorySet.Add("ObjectType=0x0008"); MandatorySet.Add("SubNumber=5"); test_object_coverage(AlwaysSet, MandatorySet, OptionalSet); if (!ods.ContainsKey(0x2000)) { throw (new Exception("parseEDSentry() failed no object")); } ODentry od = ods[0x2000]; if (od.ObjFlags != 0) { throw (new Exception("Default objectflags not 0")); } }
public void gennetpdodoc(string filepath, List <EDSsharp> network) { file = new StreamWriter(filepath, false); file.Write("<!DOCTYPE html><html><head><link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" /> <title>Network PDO report</title></head><body>"); file.Write(string.Format("<h1>PDO Network Documentation </h1>")); file.Write("<table id=\"nodelist\">"); write2linetableheader("Node ID", "Name"); foreach (EDSsharp eds in network) { write2linetablerow(eds.dc.NodeId.ToString(), eds.di.ProductName); } file.Write("</table>"); file.Write(string.Format("<h1>PDO Map</h1>")); //now for each node find each TX PDO foreach (EDSsharp eds in network) { foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { //find the com params for each TX pdo if (kvp.Key >= 0x1800 && kvp.Key < 0x1a00) { //check the mapping also exists if (eds.ods.ContainsKey((UInt16)(kvp.Key + 0x200))) { ODentry map = eds.ods[(UInt16)(kvp.Key + 0x200)]; ODentry compar = eds.ods[(UInt16)(kvp.Key)]; //Fix me we need some generic PDO access functions UInt32 TXCOB = 0; byte syncstart = 0; UInt16 timer = 0; UInt16 inhibit = 0; byte type = 0; bool nodeidpresent; if (kvp.Value.Containssubindex(1)) { TXCOB = eds.GetNodeID(kvp.Value.Getsubobject(1).defaultvalue, out nodeidpresent); } if (kvp.Value.Containssubindex(2)) { type = EDSsharp.ConvertToByte(kvp.Value.Getsubobject(2).defaultvalue); } if (kvp.Value.Containssubindex(3)) { inhibit = EDSsharp.ConvertToUInt16(kvp.Value.Getsubobject(3).defaultvalue); } if (kvp.Value.Containssubindex(5)) { timer = EDSsharp.ConvertToUInt16(kvp.Value.Getsubobject(5).defaultvalue); } if (kvp.Value.Containssubindex(6)) { syncstart = EDSsharp.ConvertToByte(kvp.Value.Getsubobject(6).defaultvalue); } byte totalsize = 0; for (UInt16 sub = 1; sub <= map.Getmaxsubindex(); sub++) { if (!map.Containssubindex(sub)) { continue; } UInt32 mapping = EDSsharp.ConvertToUInt32(map.Getsubobject(sub).defaultvalue); if (mapping == 0) { continue; } Byte size = (byte)mapping; totalsize += size; } if (totalsize != 0) { file.Write(string.Format("<h2> PDO 0x{0:x3} <h2>", TXCOB)); file.Write("<table><tr> <th>Parameter</th> <th>value</th> </tr>"); file.Write(string.Format("<tr><td>{0}</td><td>0x{1:x3}</td></tr>", "COB", TXCOB)); file.Write(string.Format("<tr><td>{0}</td><td>0x{1:x}</td></tr>", "Type", type)); file.Write(string.Format("<tr><td>{0}</td><td>0x{1:x} ({2})</td></tr>", "Inhibit", inhibit, inhibit)); file.Write(string.Format("<tr><td>{0}</td><td>0x{1:x} ({2})</td></tr>", "Event timer", timer, timer)); file.Write(string.Format("<tr><td>{0}</td><td>0x{1:x} ({2})</td></tr>", "Sync start", syncstart, syncstart)); file.Write(string.Format("<tr><td>{0}</td><td>0x{1:x}</td></tr>", "PDO Size (Bytes)", totalsize / 8)); file.Write("<table class=\"pdomap\">"); file.Write(string.Format("<tr><th>{0}</th><th>{1}</th><th>{2}</th><th>{3}</th><th>{4}</th><th>{5}</th></tr>", "Node", "Dev name", "OD Index", "Name", "Size", "Receivers")); } byte offsetend = 0; byte offsetstart = 0; for (UInt16 sub = 1; sub <= map.Getmaxsubindex(); sub++) { if (!map.Containssubindex(sub)) { continue; } if (map.Getsubobjectdefaultvalue(sub) == "") { continue; } UInt32 mapping = EDSsharp.ConvertToUInt32(map.Getsubobjectdefaultvalue(sub)); if (mapping == 0) { continue; } //its real extract the OD and sub index UInt16 index = (UInt16)(mapping >> 16); UInt16 subindex = (UInt16)(0x00FF & (mapping >> 8)); Byte size = (byte)mapping; String name; if (!eds.ods.ContainsKey(index)) { break; } if (subindex == 0) { name = eds.ods[index].parameter_name; } else { name = eds.ods[index].Getsubobject(subindex).parameter_name; } file.Write(string.Format("<tr> <td>0x{0:x2}</td> <td>{1}</td> <td>0x{2:x4}/0x{3:x2}</td><td>{4}</td> <td>{5}</td><td>", eds.dc.NodeId, eds.di.ProductName, index, subindex, name, size)); //find all receivers here file.Write("<table class=\"receivers\">"); file.Write(string.Format("<tr> <th>Node</th> <th>Dev Name</th> <th>OD Index</th> <th>Name</th> <th>Size</td></tr>")); offsetend += (byte)(size / 8); foreach (EDSsharp eds2 in network) { if (eds == eds2) { continue; } else { foreach (KeyValuePair <UInt16, ODentry> kvp2 in eds2.ods) { if (kvp2.Key >= 0x1400 && kvp2.Key < 0x1600) { if (eds2.ods.ContainsKey((UInt16)(kvp2.Key + 0x200))) { bool nodeidpresent2; UInt32 RXCOB = eds2.GetNodeID(kvp2.Value.Getsubobjectdefaultvalue(1), out nodeidpresent2); if (RXCOB == TXCOB) { ODentry map2 = eds2.ods[(UInt16)(kvp2.Key + 0x200)]; //Get the actual subindex to use byte offsetstart2 = 0; byte offsetend2 = 0; Byte size2 = 0; UInt32 mapping2 = 0; UInt16 index2 = 0; UInt16 subindex2 = 0; byte totalsize2 = 0; //Sanity check the total size for (byte sub2 = 1; sub2 <= map2.Getmaxsubindex(); sub2++) { mapping2 = EDSsharp.ConvertToUInt32(map2.Getsubobjectdefaultvalue(sub2)); size2 = (byte)(mapping2); totalsize2 += size2; } if (totalsize2 != totalsize) { file.WriteLine("<B> Critical error with network RX PDO size != TX PDO SIZE"); } for (byte sub2 = 1; sub2 <= map2.Getmaxsubindex(); sub2++) { mapping2 = EDSsharp.ConvertToUInt32(map2.Getsubobjectdefaultvalue(sub2)); index2 = (UInt16)(mapping2 >> 16); subindex2 = (UInt16)(0x00FF & (mapping2 >> 8)); size2 = (byte)mapping2; if (mapping2 == 0) { continue; } offsetend2 += (byte)(size2 / 8); // if(offsetstart == offsetstart2 && offsetend == offsetend2) //we are all good equal data 1:1 mapping if (offsetstart2 < offsetstart) { //more data needed to reach start offsetstart2 += (byte)(size2 / 8); continue; } if (offsetend2 > offsetend && offsetstart2 > offsetstart) { break; //we are done } offsetstart2 += (byte)(size2 / 8); if (offsetend2 > offsetend) { //merge cell required on parent table //meh difficult to do from here } String name2; if (subindex2 == 0) { //fixme getobject could return null name2 = eds2.Getobject(index2).parameter_name; } else { //fixme getobject could return null name2 = eds2.Getobject(index2).Getsubobject(subindex2).parameter_name; } string sizemsg = ""; if (size != size2) { sizemsg = " <b>WARNING</b>"; } file.Write(string.Format("<tr> <td>0x{0:x2}</td> <td>{1}</td> <td>0x{2:x4}/0x{3:x2}</td> <td>{4}</td><td>{5}{6}</td></tr>", eds2.dc.NodeId, eds2.di.ProductName, index2, subindex2, name2, size2, sizemsg)); } } } } } } } offsetstart += (byte)(size / 8); file.Write("</table>"); file.Write("</td>"); file.Write(string.Format("</tr>")); } } file.Write("</table>"); } } } file.Close(); }
public NewIndex(EDSsharp eds, DataType dt = DataType.UNKNOWN, ObjectType ot = ObjectType.UNKNOWN, ODentry parent = null) { this.eds = eds; InitializeComponent(); foreach (DataType foo in Enum.GetValues(typeof(DataType))) { comboBox_datatype.Items.Add(foo.ToString()); } if (ot == ObjectType.REC) { radioButton_array.Enabled = false; radioButton_rec.Enabled = false; radioButton_var.Enabled = false; numericUpDown_index.Enabled = false; numericUpDown_subindexes.Enabled = false; //order of next two matters radioButton_rec.Checked = true; comboBox_datatype.Enabled = true; childaddition = true; numericUpDown_index.Value = parent.Index; Text = "Create new sub index"; } DialogResult = DialogResult.Cancel; }
private void print_h_bylocation(StreamWriter file, StorageLocation location) { string lastname = ""; //pre walk the list to find groups for arrays Dictionary <string, int> au = new Dictionary <string, int>(); foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.Disabled == true) { continue; } string name = make_cname(od.parameter_name); if (au.ContainsKey(name)) { au[name]++; } else { au[name] = 1; } } foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.Disabled == true) { continue; } if ((od.location != location)) { if (!(od.location == 0 && location == StorageLocation.RAM)) { continue; } } if (od.nosubindexes == 0) { string specialarraylength = ""; if (od.datatype == DataType.VISIBLE_STRING || od.datatype == DataType.OCTET_STRING) { specialarraylength = string.Format("[{0}]", od.sizeofdatatype()); } file.WriteLine(string.Format("/*{0:x4} */ {1,-15} {2}{3};", od.index, od.datatype.ToString(), make_cname(od.parameter_name), specialarraylength)); } else { DataType t = eds.getdatatype(od); //If it not a defined type, and it probably is not for a REC, we must generate a name, this is //related to the previous code that generated the actual structures. string objecttypewords = ""; switch (od.objecttype) { case ObjectType.REC: objecttypewords = String.Format("OD_{0}_t", make_cname(od.parameter_name)); break; case ObjectType.ARRAY: objecttypewords = t.ToString(); //this case is handled by the logic in eds.getdatatype(); break; default: objecttypewords = t.ToString(); break; } string name = make_cname(od.parameter_name); if (au[name] > 1) { if (lastname == name) { continue; } lastname = name; file.WriteLine(string.Format("/*{0:x4} */ {1,-15} {2}[{3}];", od.index, objecttypewords, make_cname(od.parameter_name), au[name])); } else { //Don't put sub indexes on record type in h file unless there are multiples of the same //in which case its not handleded here, we need a special case for the predefined special //values that arrayspecial() checks for, to generate 1 element arrays if needed if (od.objecttype == ObjectType.REC) { if (arrayspecial(od.index, true)) { file.WriteLine(string.Format("/*{0:x4} */ {1,-15} {2}[1];", od.index, objecttypewords, make_cname(od.parameter_name))); } else { file.WriteLine(string.Format("/*{0:x4} */ {1,-15} {2};", od.index, objecttypewords, make_cname(od.parameter_name))); } } else { file.WriteLine(string.Format("/*{0:x4} */ {1,-15} {2}[{3}];", od.index, objecttypewords, make_cname(od.parameter_name), od.nosubindexes - 1)); } } } } }
private void export_c() { StreamWriter file = new StreamWriter(folderpath + Path.DirectorySeparatorChar + "CO_OD.c"); addGPLheader(file); file.WriteLine(@"#include ""CO_driver.h"" #include ""CO_OD.h"" #include ""CO_SDO.h"" /******************************************************************************* DEFINITION AND INITIALIZATION OF OBJECT DICTIONARY VARIABLES *******************************************************************************/ /***** Definition for RAM variables *******************************************/ struct sCO_OD_RAM CO_OD_RAM = { CO_OD_FIRST_LAST_WORD, "); export_OD_def_array(file, StorageLocation.RAM); file.WriteLine(@" CO_OD_FIRST_LAST_WORD, }; /***** Definition for EEPROM variables ****************************************/ struct sCO_OD_EEPROM CO_OD_EEPROM = { CO_OD_FIRST_LAST_WORD, "); export_OD_def_array(file, StorageLocation.EEPROM); file.WriteLine(@" CO_OD_FIRST_LAST_WORD, }; /***** Definition for ROM variables *******************************************/ struct sCO_OD_ROM CO_OD_ROM = { //constant variables, stored in flash CO_OD_FIRST_LAST_WORD, "); export_OD_def_array(file, StorageLocation.ROM); file.WriteLine(@" CO_OD_FIRST_LAST_WORD }; /******************************************************************************* STRUCTURES FOR RECORD TYPE OBJECTS *******************************************************************************/ "); export_record_types(file); file.Write(@"/******************************************************************************* OBJECT DICTIONARY *******************************************************************************/ const CO_OD_entry_t CO_OD["); file.Write(string.Format("{0}", enabledcount)); file.WriteLine(@"] = { "); bool arrayspecialcase = false; int count = 0; foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.Disabled == true) { continue; } string loc = getlocation(od.location); byte flags = getflags(od); DataType t = eds.getdatatype(od); int datasize = od.sizeofdatatype(); string odf; if (od.AccessFunctionName != null) { odf = od.AccessFunctionName; } else { odf = "CO_ODF"; } string array = ""; //only needed for array objects if (od.objecttype == ObjectType.ARRAY && od.nosubindexes > 0) { array = string.Format("[0]"); } if (arrayspecial(od.index, true)) { arrayspecialcase = true; count = 0; } if (arrayspecialcase) { array = string.Format("[{0}]", count); count++; } //Arrays and Recs have 1 less subindex than actually present in the od.subobjects int nosubindexs = od.nosubindexes; if (od.objecttype == ObjectType.ARRAY || od.objecttype == ObjectType.REC) { if (nosubindexs > 0) { nosubindexs--; } } //Arrays really should obey the max subindex paramater not the physical number of elements if (od.objecttype == ObjectType.ARRAY) { if ((od.getmaxsubindex() != nosubindexs) && od.index != 0x1003) //ignore this warning on 0x1003 it is a special case { Warnings.warning_list.Add(String.Format("Subindex discrepancy on object 0x{0:x4} arraysize: {1} vs max-subindex: {2}", od.index, nosubindexs, od.getmaxsubindex())); } nosubindexs = od.getmaxsubindex(); } string pdata; //CO_OD_entry_t pData generator if (od.objecttype == ObjectType.REC) { pdata = string.Format("&OD_record{0:x4}", od.index); } else { pdata = string.Format("&{0}.{1}{2}", loc, make_cname(od.parameter_name), array); } if ((od.objecttype == ObjectType.VAR || od.objecttype == ObjectType.ARRAY) && od.datatype == DataType.DOMAIN) { //NB domain MUST have a data pointer of 0, can open node requires this and makes checks //against null to determine this is a DOMAIN type. pdata = "0"; } file.WriteLine(string.Format("{{0x{0:x4}, 0x{1:x2}, 0x{2:x2}, {3}, (void*){4}}},", od.index, nosubindexs, flags, datasize, pdata)); if (arrayspecial(od.index, false)) { arrayspecialcase = false; } } file.WriteLine("};"); file.Close(); }
private void export_h() { StreamWriter file = new StreamWriter(folderpath + Path.DirectorySeparatorChar + "CO_OD.h"); addGPLheader(file); file.WriteLine("#pragma once"); file.WriteLine(""); file.WriteLine(@"/******************************************************************************* CANopen DATA DYPES *******************************************************************************/ typedef uint8_t UNSIGNED8; typedef uint16_t UNSIGNED16; typedef uint32_t UNSIGNED32; typedef uint64_t UNSIGNED64; typedef int8_t INTEGER8; typedef int16_t INTEGER16; typedef int32_t INTEGER32; typedef int64_t INTEGER64; typedef float32_t REAL32; typedef float64_t REAL64; typedef char_t VISIBLE_STRING; typedef oChar_t OCTET_STRING; typedef domain_t DOMAIN; "); file.WriteLine("/*******************************************************************************"); file.WriteLine(" FILE INFO:"); file.WriteLine(string.Format(" FileName: {0}", eds.fi.FileName)); 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(@"/******************************************************************************* FEATURES *******************************************************************************/"); file.WriteLine(string.Format(" #define CO_NO_SYNC {0} //Associated objects: 1005-1007", noSYNC)); file.WriteLine(string.Format(" #define CO_NO_EMERGENCY {0} //Associated objects: 1014, 1015", noEMCY)); file.WriteLine(string.Format(" #define CO_NO_SDO_SERVER {0} //Associated objects: 1200-127F", noSDOservers)); file.WriteLine(string.Format(" #define CO_NO_SDO_CLIENT {0} //Associated objects: 1280-12FF", noSDOclients)); file.WriteLine(string.Format(" #define CO_NO_RPDO {0} //Associated objects: 14xx, 16xx", noRXpdos)); file.WriteLine(string.Format(" #define CO_NO_TPDO {0} //Associated objects: 18xx, 1Axx", noTXpdos)); bool ismaster = false; if (eds.ods.ContainsKey(0x1f80)) { ODentry master = eds.ods[0x1f80]; // we could do with a cut down function that returns a value rather than a string string meh = formatvaluewithdatatype(master.defaultvalue, master.datatype); meh = meh.Replace("L", ""); UInt32 NMTStartup = Convert.ToUInt32(meh, 16); if ((NMTStartup & 0x01) == 0x01) { ismaster = true; } } file.WriteLine(string.Format(" #define CO_NO_NMT_MASTER {0}", ismaster == true?1:0)); file.WriteLine(""); file.WriteLine(""); file.WriteLine(@"/******************************************************************************* OBJECT DICTIONARY *******************************************************************************/"); file.WriteLine(string.Format(" #define CO_OD_NoOfElements {0}", enabledcount)); file.WriteLine(""); file.WriteLine(""); file.WriteLine(@"/******************************************************************************* TYPE DEFINITIONS FOR RECORDS *******************************************************************************/"); //We need to identify all the record types used and generate a struct for each one //FIXME the original CanOpenNode exporter said how many items used this struct in the comments List <string> structnamelist = new List <string>(); foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.objecttype != ObjectType.REC) { continue; } string structname = String.Format("OD_{0}_t", make_cname(od.parameter_name)); if (structnamelist.Contains(structname)) { continue; } structnamelist.Add(structname); file.WriteLine(string.Format("/*{0:x4} */ typedef struct {{", kvp.Key)); foreach (KeyValuePair <UInt16, ODentry> kvp2 in kvp.Value.subobjects) { string paramaterarrlen = ""; ODentry subod = kvp2.Value; if (subod.datatype == DataType.VISIBLE_STRING || subod.datatype == DataType.OCTET_STRING) { paramaterarrlen = String.Format("[{0}]", subod.sizeofdatatype()); } file.WriteLine(string.Format(" {0,-15}{1}{2};", subod.datatype.ToString(), make_cname(subod.parameter_name), paramaterarrlen)); } file.WriteLine(string.Format(" }} {0};", structname)); } file.WriteLine(@"/******************************************************************************* STRUCTURES FOR VARIABLES IN DIFFERENT MEMORY LOCATIONS *******************************************************************************/ #define CO_OD_FIRST_LAST_WORD 0x55 //Any value from 0x01 to 0xFE. If changed, EEPROM will be reinitialized. /***** Structure for RAM variables ********************************************/ struct sCO_OD_RAM{ UNSIGNED32 FirstWord; "); print_h_bylocation(file, StorageLocation.RAM); file.WriteLine(@" UNSIGNED32 LastWord; };"); file.WriteLine(@"/***** Structure for EEPROM variables *****************************************/ struct sCO_OD_EEPROM{ UNSIGNED32 FirstWord; "); print_h_bylocation(file, StorageLocation.EEPROM); file.WriteLine(@" UNSIGNED32 LastWord; };"); file.WriteLine(@"/***** Structure for ROM variables ********************************************/ struct sCO_OD_ROM{ UNSIGNED32 FirstWord; "); print_h_bylocation(file, StorageLocation.ROM); file.WriteLine(@" UNSIGNED32 LastWord; };"); file.WriteLine(@"/***** Declaration of Object Dictionary variables *****************************/ extern struct sCO_OD_RAM CO_OD_RAM; extern struct sCO_OD_EEPROM CO_OD_EEPROM; extern struct sCO_OD_ROM CO_OD_ROM; /******************************************************************************* ALIASES FOR OBJECT DICTIONARY VARIABLES *******************************************************************************/"); List <string> constructed_rec_types = new List <string>(); foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.Disabled == true) { continue; } string loc = getlocation(od.location); DataType t = eds.getdatatype(od); switch (od.objecttype) { default: { file.WriteLine(string.Format("/*{0:x4}, Data Type: {1} */", od.index, t.ToString())); file.WriteLine(string.Format(" #define {0,-51} {1}.{2}", string.Format("OD_{0}", make_cname(od.parameter_name)), loc, make_cname(od.parameter_name))); DataType dt = od.datatype; if (dt == DataType.OCTET_STRING || dt == DataType.VISIBLE_STRING) { file.WriteLine(string.Format(" #define {0,-51} {1}", string.Format("ODL_{0}_stringLength", make_cname(od.parameter_name)), od.sizeofdatatype())); } file.WriteLine(""); } break; case ObjectType.ARRAY: { DataType dt = od.datatype; file.WriteLine(string.Format("/*{0:x4}, Data Type: {1}, Array[{2}] */", od.index, t.ToString(), od.nosubindexes - 1)); file.WriteLine(string.Format(" #define OD_{0,-48} {1}.{2}", make_cname(od.parameter_name), loc, make_cname(od.parameter_name))); file.WriteLine(string.Format(" #define {0,-51} {1}", string.Format("ODL_{0}_arrayLength", make_cname(od.parameter_name)), od.nosubindexes - 1)); List <string> ODAs = new List <string>(); string ODAout = ""; foreach (KeyValuePair <UInt16, ODentry> kvp2 in od.subobjects) { ODentry sub = kvp2.Value; if (sub.subindex == 0) { continue; } string ODA = string.Format("{0}", string.Format("ODA_{0}_{1}", make_cname(od.parameter_name), make_cname(sub.parameter_name))); if (ODAs.Contains(ODA)) { continue; } ODAs.Add(ODA); //Arrays do not have a size in the raw CO objects, Records do //so offset by one if (od.objecttype == ObjectType.ARRAY) { ODAout += (string.Format(" #define {0,-51} {1}\r\n", string.Format("ODA_{0}_{1}", make_cname(od.parameter_name), make_cname(sub.parameter_name)), sub.subindex - 1)); } else { ODAout += (string.Format(" #define {0,-51} {1}\r\n", string.Format("ODA_{0}_{1}", make_cname(od.parameter_name), make_cname(sub.parameter_name)), sub.subindex)); } } file.Write(ODAout); file.WriteLine(""); } break; case ObjectType.REC: { string rectype = make_cname(od.parameter_name); if (!constructed_rec_types.Contains(rectype)) { file.WriteLine(string.Format("/*{0:x4}, Data Type: {1}_t */", od.index, rectype)); file.WriteLine(string.Format(" #define {0,-51} {1}.{2}", string.Format("OD_{0}", rectype), loc, rectype)); constructed_rec_types.Add(rectype); file.WriteLine(""); } } break; } } file.Close(); }
void export_OD_def_array(StreamWriter file, StorageLocation location) { foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.Disabled == true) { continue; } if ((od.location != location)) { if (!(od.location == 0 && location == StorageLocation.RAM)) { continue; } } if (od.nosubindexes == 0) { file.WriteLine(string.Format("/*{0:x4}*/ {1},", od.index, formatvaluewithdatatype(od.defaultvalue, od.datatype))); } else { if (arrayspecial(od.index, true)) { file.Write(string.Format("/*{0:x4}*/ {{{{", od.index)); } else { file.Write(string.Format("/*{0:x4}*/ {{", od.index)); } foreach (KeyValuePair <UInt16, ODentry> kvp2 in od.subobjects) { ODentry sub = kvp2.Value; DataType dt = sub.datatype; if ((od.objecttype == ObjectType.ARRAY) && sub.subindex == 0) { continue; } file.Write(formatvaluewithdatatype(sub.defaultvalue, dt)); if (od.subobjects.Keys.Last() != kvp2.Key) { file.Write(", "); } } if (arrayspecial(od.index, false)) { file.WriteLine("}},"); } else { file.WriteLine("},"); } } } }
void export_record_types(StreamWriter file) { bool arrayopen = false; int arrayindex = 0; foreach (KeyValuePair <UInt16, ODentry> kvp in eds.ods) { ODentry od = kvp.Value; if (od.objecttype != ObjectType.REC) { continue; } if (od.Disabled == true) { continue; } int count = od.subobjects.Count; //don't include index if (od.index >= 0x1400 && od.index < 0x1600) { count = 3; //CanOpenNode Fudging. Its only 3 paramaters for RX PDOS in the c code despite being a PDO_COMMUNICATION_PARAMETER } string cname = make_cname(od.parameter_name); file.WriteLine(String.Format("/*0x{0:x4}*/ const CO_OD_entryRecord_t OD_record{0:x4}[{1}] = {{", od.index, count)); string arrayaccess = ""; if (arrayspecial(od.index, true) || arrayopen) { arrayaccess = string.Format("[{0}]", arrayindex); arrayindex++; arrayopen = true; } foreach (KeyValuePair <UInt16, ODentry> kvpsub in od.subobjects) { ODentry sub = kvpsub.Value; string subcname = make_cname(sub.parameter_name); if (sub.datatype != DataType.DOMAIN) { file.WriteLine(string.Format(" {{(void*)&{5}.{0}{4}.{1}, 0x{2:x2}, 0x{3} }},", cname, subcname, getflags(sub), sub.sizeofdatatype(), arrayaccess, getlocation(od.location))); } else { //Domain type MUST have its data pointer set to 0 for CanOpenNode file.WriteLine(string.Format(" {{(void*)0, 0x{2:x2}, 0x{3} }},", cname, subcname, getflags(sub), sub.sizeofdatatype(), arrayaccess, getlocation(od.location))); } } if (arrayspecial(od.index, false)) { arrayindex = 0; arrayopen = false; } file.Write("};\r\n\r\n"); } }