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 Documementation </h1>")); file.Write("<table id=\"nodelist\">"); write2linetableheader("Node ID", "Name"); foreach (EDSsharp eds in network) { write2linetablerow(eds.di.concreteNodeId.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.di.concreteNodeId, eds.di.ProductName, index, subindex, name, size)); //find all recievers 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.di.concreteNodeId, 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(); }
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(); }