Beispiel #1
0
        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"));
            }
        }
Beispiel #2
0
        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();
            }
        }
Beispiel #3
0
        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"));
            }
        }
Beispiel #4
0
        private void updateselectedindexdisplay(UInt16 index, UInt16 mod)
        {
            selectedindexod = getOD(index, mod);
            currentmodule   = mod;

            updateselectedindexdisplay();
        }
Beispiel #5
0
        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"));
            }
        }
Beispiel #6
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();
        }
Beispiel #7
0
        private void disableObjectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ListViewItem item = selecteditem;

            ODentry od = (ODentry)item.Tag;

            eds.dirty   = true;
            od.Disabled = !od.Disabled;
            populateindexlists();
        }
Beispiel #8
0
        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);
        }
Beispiel #11
0
        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;
                }
            }
        }
Beispiel #12
0
        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);
            }
        }
Beispiel #13
0
        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();
            }
        }
Beispiel #14
0
        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;
        }
Beispiel #15
0
        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;
        }
Beispiel #16
0
        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();
            }
        }
Beispiel #17
0
        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();
        }
Beispiel #18
0
        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);
        }
Beispiel #20
0
        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();
            }
        }
Beispiel #21
0
        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();
                    }
                }
            }
        }
Beispiel #22
0
        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();
            }
        }
Beispiel #23
0
        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"));
            }
        }
Beispiel #24
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();
        }
Beispiel #25
0
        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");
            }
        }