diff --git a/libEDSsharp/CanOpenDevice.cs b/libEDSsharp/CanOpenDevice.cs new file mode 100644 index 0000000..d713758 --- /dev/null +++ b/libEDSsharp/CanOpenDevice.cs @@ -0,0 +1,697 @@ +/* + This file is part of libEDSsharp. + + libEDSsharp is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + libEDSsharp is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with libEDSsharp. If not, see . + + Copyright(c) 2019 Robin Cornelius + Copyright(c) 2024 Janez Paternoster +*/ + +using System; +using System.Collections.Generic; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace libEDSsharp +{ + /// + /// Object dictionary basic data types from CiA 301 + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum DataType + { + UNKNOWN = 0x00, + BOOLEAN = 0x01, + INTEGER8 = 0x02, + INTEGER16 = 0x03, + INTEGER32 = 0x04, + UNSIGNED8 = 0x05, + UNSIGNED16 = 0x06, + UNSIGNED32 = 0x07, + REAL32 = 0x08, + VISIBLE_STRING = 0x09, + OCTET_STRING = 0x0A, + UNICODE_STRING = 0x0B, + TIME_OF_DAY = 0x0C, + TIME_DIFFERENCE = 0x0D, + DOMAIN = 0x0F, + INTEGER24 = 0x10, + REAL64 = 0x11, + INTEGER40 = 0x12, + INTEGER48 = 0x13, + INTEGER56 = 0x14, + INTEGER64 = 0x15, + UNSIGNED24 = 0x16, + UNSIGNED40 = 0x18, + UNSIGNED48 = 0x19, + UNSIGNED56 = 0x1A, + UNSIGNED64 = 0x1B + } + + /// + /// Object Dictionary object codes from CiA 301 + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum ObjectType + { + UNKNOWN = -1, + /// + /// An object with no data fields + /// + NULL = 0, + /// + /// Large variable amount of data e.g. executable program code + /// + DOMAIN = 2, + /// + /// Denotes a type definition such as a BOOLEAN, UNSIGNED16, FLOAT and so on + /// + DEFTYPE = 5, + /// + /// Defines a new record type e.g. the PDO mapping structure at 21h + /// + DEFSTRUCT = 6, + /// + /// A single value such as an UNSIGNED8, BOOLEAN, FLOAT, INTEGER16, VISIBLE STRING etc. + /// + VAR = 7, + /// + /// A multiple data field object where each data field is a + /// simple variable of the SAME basic data type e.g. array of UNSIGNED16 etc. + /// Sub-index 0 is of UNSIGNED8 and therefore not part of the ARRAY data + /// + ARRAY = 8, + /// + /// A multiple data field object where the data fields may be any combination of + /// simple variables. Sub-index 0 is of UNSIGNED8 and sub-index 255 is of UNSIGNED32 and + /// therefore not part of the RECORD data + /// + RECORD = 9, + } + + /// + /// Defines how the object can be changed from SDO + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum AccessSDO + { + /// + /// no access + /// + no, + + /// + /// read only access + /// + ro, + + /// + /// write only access + /// + wo, + + /// + /// read and write access + /// + rw + } + + /// + /// Defines how the object can be changed from PDO + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum AccessPDO + { + /// + /// no access + /// + no, + + /// + /// TPDO access + /// + t, + + /// + /// RPDO access + /// + r, + + /// + /// TPDO and RPDO access + /// + tr + } + + /// + /// Defines how the object can be changed from SRDO + /// + [JsonConverter(typeof(JsonStringEnumConverter))] + public enum AccessSRDO + { + /// + /// no access + /// + no = 0, + + /// + /// SRDO TX access + /// + tx = 1, + + /// + /// SRDO RX access + /// + rx = 2, + + /// + /// SRDO TX or RX access + /// + trx = 3 + } + + /// + /// CANopen [FileInfo] section, based on CiA306 + /// + public class CanOpen_FileInfo + { + /// + /// Actual file version (as string) + /// + public string FileVersion { get; set; } + + /// + /// File description + /// + public string Description { get; set; } + + /// + /// File creation time + /// + public DateTime CreationTime { get; set; } + + /// + /// Name or a description of the file creator + /// + public string CreatedBy { get; set; } + + /// + /// Time of last modification + /// + public DateTime ModificationTime { get; set; } + + /// + /// Name or a description of the creator + /// + public string ModifiedBy { get; set; } + + /// + /// New default object + /// + public CanOpen_FileInfo() + { + // make empty strings instead of null + FileVersion = ""; + Description = ""; + CreatedBy = ""; + ModifiedBy = ""; + } + } + + /// + /// CANopen [DeviceInfo] section, based on CiA306 + /// + public class CanOpen_DeviceInfo + { + /// + /// Vendor name + /// + public string VendorName { get; set; } + + /// + /// Unique vendor-ID (index 1018, sub-index 01) + /// + public UInt32 VendorNumber { get; set; } + + /// + /// Product name + /// + public string ProductName { get; set; } + + /// + /// Product code (index 1018, sub-index 02) + /// + public UInt32 ProductNumber { get; set; } + + /// + /// Support of the baud rate 10 kbit/s + /// + public bool BaudRate_10 { get; set; } + + /// + /// Support of the baud rate 20 kbit/s + /// + public bool BaudRate_20 { get; set; } + + /// + /// Support of the baud rate 50 kbit/s + /// + public bool BaudRate_50 { get; set; } + + /// + /// Support of the baud rate 125 kbit/s + /// + public bool BaudRate_125 { get; set; } + + /// + /// Support of the baud rate 250 kbit/s + /// + public bool BaudRate_250 { get; set; } + + /// + /// Support of the baud rate 500 kbit/s + /// + public bool BaudRate_500 { get; set; } + + /// + /// Support of the baud rate 800 kbit/s + /// + public bool BaudRate_800 { get; set; } + + /// + /// Support of the baud rate 1000 kbit/s + /// + public bool BaudRate_1000 { get; set; } + + /// + /// Minimum size of a mappable object in bits, allowed for the PDO mapping on this CANopen device, usually 8 + /// + public uint Granularity { get; set; } + + /// + /// Number of the supported receive PDOs + /// + public UInt16 NrOfRxPDO { get; set; } + + /// + /// Number of the supported transmit PDOs + /// + public UInt16 NrOfTxPDO { get; set; } + + /// + /// Support of the LSS slave functionality, see CiA305 + /// + public bool LssSlave { get; set; } + + /// + /// Support of the LSS master functionality, see CiA305 + /// + public bool LssMaster { get; set; } + + /// + /// Support of the NodeGuarding slave + /// + public bool NodeGuardingSlave { get; set; } + + /// + /// Support of the NodeGuarding master + /// + public bool NodeGuardingMaster { get; set; } + + /// + /// Support of the NodeGuarding master + /// + public UInt16 NrOfNodeGuardingMonitoredNodes { get; set; } + + /// + /// New default object + /// + public CanOpen_DeviceInfo() + { + // make empty strings instead of null + VendorName = ""; + ProductName = ""; + BaudRate_10 = true; + BaudRate_20 = true; + BaudRate_50 = true; + BaudRate_125 = true; + BaudRate_250 = true; + BaudRate_500 = true; + BaudRate_1000 = true; + Granularity = 8; + NrOfRxPDO = 4; + NrOfTxPDO = 4; + LssSlave = true; + } + } + + /// + /// CANopen [DeviceComissioning] section, based on CiA306, used for the device configuration file (DCF) + /// + public class CanOpen_DeviceComissioning + { + /// + /// CANopen device’s address + /// + public uint NodeID { get; set; } + + /// + /// Node name + /// + public string NodeName { get; set; } + + /// + /// CANopen device’s baudrate + /// + public UInt16 Baudrate { get; set; } + + /// + /// Number of the network + /// + public UInt32 NetNumber { get; set; } + + /// + /// Name of the network + /// + public string NetworkName { get; set; } + + /// + /// CANopen device is the CANopen manager + /// + public bool CANopenManager { get; set; } + + /// + /// Serial number (index 1018, sub-index 03) + /// + public UInt32 LSS_SerialNumber { get; set; } + + /// + /// New default object + /// + public CanOpen_DeviceComissioning() + { + // make empty strings instead of null + NodeName = ""; + NetworkName = ""; + } + } + + /// + /// Object Dictionary SubEntry on specific Subindex. Sorted dictionary of them + /// is part of OdEntry. If OdEntry ObjectType is "record", then each SubEntry in the + /// dictionary may be unique. If OdEntry ObjectType is "array", then some properties + /// of all SubEntries must be equal. If OdEntry ObjectType is "var", then + /// one SubEntry exists. + /// + public class OdSubEntry + { + /// + /// Name of the sub entry. If OdEntry is "VAR", this property is not relevant. + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string SubParameterName { get; set; } + + /// + /// Additonal parameter name, for the device configuration file (DCF). + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string Denotation { get; set; } + + /// + /// CANopen data type + /// + public DataType DataType { get; set; } + + /// + /// CANopen SDO access permissions + /// + public AccessSDO AccessSDO { get; set; } + + /// + /// CANopen PDO access permissions + /// + public AccessPDO AccessPDO { get; set; } + + /// + /// CANopen SRDO access permissions. + /// If 0 or "no", parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public AccessSRDO AccessSRDO { get; set; } + + /// + /// Default value of the sub object. + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string DefaultValue { get; set; } + + /// + /// Actual value, for the device configuration file (DCF). + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string ParameterValue { get; set; } + + /// + /// Low limit for the value. + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string LowLimit { get; set; } + + /// + /// High limit for the value. + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string HighLimit { get; set; } + + /// + /// CanOpenNode OD exporter V4: Minimum length of a string that can be stored. + /// If 0, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public UInt32 StringLengthMin { get; set; } + + /// + /// New default object + /// + public OdSubEntry() + { + } + + /// + /// Deep clone + /// + /// a deep clone + public OdSubEntry Clone() + { + OdSubEntry newSubEntry = new OdSubEntry + { + SubParameterName = SubParameterName, + Denotation = Denotation, + DataType = DataType, + AccessSDO = AccessSDO, + AccessPDO = AccessPDO, + AccessSRDO = AccessSRDO, + DefaultValue = DefaultValue, + ParameterValue = ParameterValue, + LowLimit = LowLimit, + HighLimit = HighLimit, + StringLengthMin = StringLengthMin + }; + return newSubEntry; + } + } + + /// + /// Object Dictionary Entry on specific Index. Sorted dictionary of them + /// is part of CanOpenDevice - CANopen Object Dictionary. + /// + public class OdEntry + { + /// + /// If true, object is completelly skipped by CANopenNode exporters, etc. + /// If false, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public bool Disabled { get; set; } + + /// + /// Name of the entry + /// + public string ParameterName { get; set; } + + /// + /// Additonal parameter name, for the device configuration file (DCF). + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string Denotation { get; set; } + + /// + /// Description of the Entry. + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string Description { get; set; } + + /// + /// CANopen Object Type + /// + public ObjectType ObjectType { get; set; } + + /// + /// CANopen Complex Data Type, if ObjectType==RECORD. This property + /// is informative and required for some exportrs. Complex data types + /// are defined by OdSubEntries for each ODEntry individually. + /// If 0, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public UInt16 ComplexDataType { get; set; } + + /// + /// CanOpenNode OD exporter V4: it will generate a macro for each different CO_countLabel. + /// For example, if four OD objects have "CO_countLabel" set to "TPDO", then + /// macro "#define ODxyz_CNT_TPDO 4" will be generated by the OD exporter. + /// If null, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string CountLabel { get; set; } + + /// + /// CanOpenNode OD exporter V4: storage group into which the C variable will belong. + /// If null, it will default to "RAM" and is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public string StorageGroup { get; set; } + + /// + /// CanOpenNode OD exporter V1.3: Flags for the PDO. + /// If false, parameter is ignored by the JSON exporter. + /// + [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingDefault)] + public bool FlagsPDO { get; set; } + + /// + /// Sorted dictionary of sub entries + /// + public SortedDictionary SubObjects { get; set; } + + /// + /// New empty object + /// + public OdEntry() + { + // make empty strings instead of null + ParameterName = ""; + SubObjects = new SortedDictionary(); + } + + /// + /// Deep clone + /// + /// a deep clone + public OdEntry Clone() + { + OdEntry newEntry = new OdEntry + { + Disabled = Disabled, + ParameterName = ParameterName, + Denotation = Denotation, + Description = Description, + ObjectType = ObjectType, + ComplexDataType = ComplexDataType, + CountLabel = CountLabel, + StorageGroup = StorageGroup, + FlagsPDO = FlagsPDO, + SubObjects = new SortedDictionary() + }; + + foreach (KeyValuePair kvp in SubObjects) + newEntry.SubObjects.Add(kvp.Key, kvp.Value.Clone()); + + return newEntry; + } + } + + /// + /// CANopen Device description object + /// + public class CanOpenDevice + { + /// + /// CANopen [FileInfo] section, based on CiA306 + /// + public CanOpen_FileInfo FileInfo { get; set; } + + /// + /// CANopen [DeviceInfo] section, based on CiA306 + /// + public CanOpen_DeviceInfo DeviceInfo { get; set; } + + /// + /// CANopen [DeviceComissioning] section, based on CiA306, used for the device configuration file (DCF) + /// + public CanOpen_DeviceComissioning DeviceComissioning { get; set; } + + /// + /// CANopen Object Dictionary + /// + public SortedDictionary Objects { get; set; } + + /// + /// New empty object + /// + public CanOpenDevice() + { + FileInfo = new CanOpen_FileInfo(); + DeviceInfo = new CanOpen_DeviceInfo(); + DeviceComissioning = new CanOpen_DeviceComissioning(); + Objects = new SortedDictionary(); + } + + /// + /// Create CanOpenDevice object from JSON string + /// + /// JSON string + /// + public CanOpenDevice(string json) + { + CanOpenDevice dev = JsonSerializer.Deserialize(json); + + FileInfo = dev.FileInfo; + DeviceInfo = dev.DeviceInfo; + DeviceComissioning = dev.DeviceComissioning; + Objects = dev.Objects; + } + + /// + /// Export this class to the JSON string + /// + /// JSON string + public string ToJson() + { + var options = new JsonSerializerOptions + { + WriteIndented = true + }; + + return JsonSerializer.Serialize(this, options); + } + } +} diff --git a/libEDSsharp/PDOHelper.cs b/libEDSsharp/PDOHelper.cs index a476e8b..432bb3a 100644 --- a/libEDSsharp/PDOHelper.cs +++ b/libEDSsharp/PDOHelper.cs @@ -385,7 +385,7 @@ public void buildmappingsfromlists(bool isCANopenNode_V4) ODentry config = new ODentry(); config.Index = slot.ConfigurationIndex; - config.datatype = DataType.PDO_COMMUNICATION_PARAMETER; + config.datatype = DataType.UNKNOWN; // PDO_COMMUNICATION_PARAMETER; config.objecttype = ObjectType.RECORD; config.accesstype = slot.configAccessType; config.prop.CO_storageGroup = slot.configloc; @@ -485,7 +485,7 @@ public void buildmappingsfromlists(bool isCANopenNode_V4) ODentry mapping = new ODentry(); mapping.Index = slot.MappingIndex; - mapping.datatype = DataType.PDO_MAPPING; + mapping.datatype = DataType.UNKNOWN; // PDO_MAPPING; mapping.objecttype = ObjectType.RECORD; if(slot.isTXPDO()) diff --git a/libEDSsharp/eds.cs b/libEDSsharp/eds.cs index 5df2199..360a05a 100644 --- a/libEDSsharp/eds.cs +++ b/libEDSsharp/eds.cs @@ -31,145 +31,13 @@ You should have received a copy of the GNU General Public License namespace libEDSsharp { - /// - /// Object dictionary data types from CiA 301 - /// - public enum DataType - { - UNKNOWN = 0, - BOOLEAN = 1, - INTEGER8 = 2, - INTEGER16 = 3, - INTEGER32 = 4, - UNSIGNED8 = 5, - UNSIGNED16 = 6, - UNSIGNED32 = 7, - REAL32 = 8, - VISIBLE_STRING = 9, - OCTET_STRING = 0x0A, - UNICODE_STRING = 0x0B, - TIME_OF_DAY = 0x0C, - TIME_DIFFERENCE = 0x0D, - DOMAIN = 0x0F, - INTEGER24 = 0x10, - REAL64 = 0x11, - INTEGER40 = 0x12, - INTEGER48 = 0x13, - INTEGER56 = 0x14, - INTEGER64 = 0x15, - UNSIGNED24 = 0x16, - UNSIGNED40 = 0x18, - UNSIGNED48 = 0x19, - UNSIGNED56 = 0x1A, - UNSIGNED64 = 0x1B, - - PDO_COMMUNICATION_PARAMETER = 0x20, //PDO_CommPar - PDO_MAPPING = 0x21, //PDO_Mapping - SDO_PARAMETER = 0x22, - IDENTITY = 0x23, - - } - /// - /// Object Dictionary object definitions from CiA 301 - /// - public enum ObjectType - { - UNKNOWN = -1, - /// - /// An object with no data fields - /// - NULL = 0, - /// - /// Large variable amount of data e.g. executable program code - /// - DOMAIN =2, - /// - /// Denotes a type definition such as a BOOLEAN, UNSIGNED16, FLOAT and so on - /// - DEFTYPE=5, - /// - /// Defines a new record type e.g. the PDO mapping structure at 21h - /// - DEFSTRUCT=6, - /// - /// A single value such as an UNSIGNED8, BOOLEAN, FLOAT, INTEGER16, VISIBLE STRING etc. - /// - VAR = 7, - /// - /// A multiple data field object where each data field is a - /// simple variable of the SAME basic data type e.g. array of UNSIGNED16 etc. - /// Sub-index 0 is of UNSIGNED8 and therefore not part of the ARRAY data - /// - ARRAY = 8, - /// - /// A multiple data field object where the data fields may be any combination of - /// simple variables. Sub-index 0 is of UNSIGNED8 and sub-index 255 is of UNSIGNED32 and - /// therefore not part of the RECORD data - /// - RECORD = 9, - } - public enum PDOMappingType - { - no=0, - optional=1, - RPDO=2, - TPDO=3, - @default=4, - } - - /// - /// Defines how the object can be changed from SDO - /// - public enum AccessSDO - { - /// - /// no access - /// - no, - /// - /// read only access - /// - ro, - /// - /// write only access - /// - wo, - /// - /// read and write access - /// - rw - } - - /// - /// Defines how the object can be changed from PDO - /// - public enum AccessPDO - { - /// - /// no access - /// - no, - /// - /// TPDO access - /// - t, - /// - /// RPDO access - /// - r, - /// - /// TPDO and RPDO access - /// - tr - } - - public enum AccessSRDO { no = 0, - tx = 1, - rx = 2, - trx = 3 + optional = 1, + RPDO = 2, + TPDO = 3, + @default = 4, } /// diff --git a/libEDSsharp/libEDSsharp.csproj b/libEDSsharp/libEDSsharp.csproj index 3bd702c..2c37cb8 100644 --- a/libEDSsharp/libEDSsharp.csproj +++ b/libEDSsharp/libEDSsharp.csproj @@ -23,6 +23,7 @@ - + + \ No newline at end of file