using System; using ln.json.mapping; using ln.logging; using ln.type; namespace ln.ethercat { public class SDO { public static SDO Create(ECMaster ecMaster, SDOAddr address) { SDO sdo = new SDO(ecMaster, address); if (address.SubIndex == 0) { if (ECMBind.ecmbind_read_objectdescription(address.Slave, address.Index, (int slave, int index, ECDataTypes dataType, ECObjectCodes objectCode, int maxsub, String name)=>{ sdo.DataType = dataType; sdo.ObjectCode = objectCode; sdo.MaxSubIndex = maxsub; sdo.Name = name; }) <= 0) { Logging.Log(LogLevel.WARNING, "cannot create SDO instance for {0}. not found.", address); return null; } } else { if (ECMBind.ecmbind_read_objectdescription_entry((ushort)address.Slave, (ushort)address.Index, (ushort)address.SubIndex, (int slave, int index, ECDataTypes dataType, ECObjectCodes objectCode, int maxsub, String name)=>{ sdo.DataType = dataType; sdo.MaxSubIndex = -1; sdo.Name = name; }) <= 0) { Logging.Log(LogLevel.WARNING, "cannot create SDO instance for {0}. not found.", address); return null; } } return sdo; } public SDOAddr Address { get; } public string Name { get; private set; } public ECDataTypes DataType { get; set; } public ECObjectCodes ObjectCode { get; set; } public int MaxSubIndex { get; set; } public bool IsPartOfPDO => ECMaster.TryGetPDO(Address, out PDO pdo); byte[] rawData; public byte[] RawData { get { if (ECMaster.TryGetPDO(Address, out PDO pdo)) { if ((rawData == null) || (rawData.Length != pdo.ByteLength)) rawData = new byte[pdo.ByteLength]; ECMBind.ecmbind_iomap_get(pdo.AddressOffset, rawData, pdo.ByteLength); } else { ECMaster.ReadSDO(Address, out rawData); } return rawData; } set => rawData = value; } public object Value { get => ECDataTypeConverter.ConvertFromEthercat(DataType ,RawData); set => throw new NotImplementedException(); } ECMaster ECMaster { get; } SDO(ECMaster ecMaster, SDOAddr address) { ECMaster = ecMaster; Address = address; } public override string ToString() { return string.Format("[SDO Slave={0} Index={1:X4}.{7} MaxSubindex={2} ObjectCode={5} DataType={3} Name={4} RawData={6}]", Address.Slave, Address.Index, MaxSubIndex, DataType, Name, ObjectCode, RawData?.ToHexString(), Address.SubIndex); } public override bool Equals(object obj) => (obj is SDO other) && Address.Equals(other.Address); public override int GetHashCode() => Address.GetHashCode(); public T GetValue() => Cast.To(Value); } }