diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs index 45f8f8b6a..2a2e9e2c5 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/Accessors.cs @@ -2,12 +2,8 @@ namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; public static class Accessors { - public static MbByte ByteAt(this Byte[] data, Byte i) => new MbByte(new ArraySegment(data), i); - public static MbWord WordAt(this Byte[] data, Byte i) => new MbWord(new ArraySegment(data), i); - public static MbByte ByteAt (this ArraySegment data, Byte i) => new MbByte(data, i); public static MbWord WordAt (this ArraySegment data, Byte i) => new MbWord(data, i); - public static MbAddress AddressAt(this ArraySegment data, Byte i) => new MbAddress(data, i); public static MbWords WordsAt (this ArraySegment data, Byte i) => new MbWords(data, i); public static MbBits BitsAt (this ArraySegment data, Byte i) => new MbBits(data, i); public static MbByte ByteAt(this ArraySegment data,Byte i) where T : struct, IConvertible => new MbByte(data, i); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbAddress.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbAddress.cs deleted file mode 100644 index 56495ee07..000000000 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbAddress.cs +++ /dev/null @@ -1,22 +0,0 @@ -using InnovEnergy.Lib.Utils; - -namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; - -public readonly struct MbAddress -{ - private readonly MbWord _MbWord; - - internal MbAddress(ArraySegment data, Byte index) - { - _MbWord = new MbWord(data, index); - } - - internal UInt16 Get() => (UInt16)(_MbWord.Get() + 1); - - internal UInt16 Set(UInt16 address) => _MbWord.Set(address - 1); - internal UInt16 Set(IConvertible value) => value.ConvertTo().Apply(Set); - - public static implicit operator UInt16(MbAddress w) => w.Get(); - - public override String ToString() => Get().ToString(); -} \ No newline at end of file diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbRegisters.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbRegisters.cs new file mode 100644 index 000000000..6db8492b9 --- /dev/null +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbRegisters.cs @@ -0,0 +1,105 @@ +using System.Collections; +using InnovEnergy.Lib.Utils; +using static InnovEnergy.Lib.Protocols.Modbus.Protocol.MultiRegisterEndianness; + +namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; + +using Float32 = Single; + +public struct MbRegisters : IReadOnlyList +{ + private MbWords Words { get; } + private UInt16 StartRegister { get; } + private MultiRegisterEndianness Endianness { get; } + + public MbRegisters(MbWords words, + UInt16 startRegister, + MultiRegisterEndianness endianness, + RegisterIndexing registerIndexing) + { + Words = words; + Endianness = endianness; + + var start = startRegister - (Int16) registerIndexing; // TODO: check + + if (start < 0) + throw new ArgumentOutOfRangeException(nameof(startRegister)); + + StartRegister = (UInt16)start; + } + + public IEnumerator GetEnumerator() => Words.GetEnumerator(); + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + + public Int32 Count => Words.Count; + + public UInt16 this[Int32 index] => Words[index]; + + private Byte MapIndex(UInt16 index) + { + var i = index - StartRegister; + if (i is < Byte.MinValue or > Byte.MaxValue) + throw new IndexOutOfRangeException(); + + return (Byte)i; + } + + public UInt16 GetUInt16(UInt16 index) + { + return index + .Apply(MapIndex) + .Apply(Words.GetUInt16); + } + + public void SetUInt16(UInt16 index, UInt16 value) + { + Words.SetUInt16(MapIndex(index), value); + } + + public Int16 GetInt16(UInt16 index) + { + return (Int16) GetUInt16(index); + } + + public void SetUInt16(UInt16 index, Int16 value) + { + SetUInt16(index, (UInt16)value); + } + + public UInt32 GetUInt32(UInt16 index) + { + var i = MapIndex(index); + + var hi = (UInt32) GetUInt16(i); + var lo = (UInt32) GetUInt16(++i); + + if (Endianness == LittleEndian) + (lo, hi) = (hi, lo); + + return hi << 16 | lo; + } + + // TODO + // public void SetUInt32(UInt32 index, UInt32 value) + + public Int32 GetInt32(UInt16 index) => (Int32)GetUInt32(index); + + // TODO + // public void SetInt32(Int32 index, Int32 value) + + + public Float32 GetFloat32(UInt16 index) + { + return index + .Apply(GetInt32) + .Apply(BitConverter.Int32BitsToSingle); + } + + // TODO + // public void SetFloat32(Float32 index, Float32 value) + + + + +} \ No newline at end of file diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs index fdc7be0c2..5511c5c63 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Accessors/MbWords.cs @@ -5,20 +5,17 @@ namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors; public readonly struct MbWords : IReadOnlyList { - private readonly ArraySegment _Data; + internal readonly ArraySegment Data; - internal MbWords(ArraySegment data, Byte startIndex) : this(data, startIndex, CountWords(data, startIndex)) + internal MbWords(ArraySegment data, Byte startIndex = 0) : + this(data, startIndex, CountWords(data, startIndex)) { } - internal MbWords(ArraySegment data, Byte startIndex, UInt16 wordCount) : this(data.Array!, startIndex, wordCount) + internal MbWords(ArraySegment data, Byte startIndex, UInt16 wordCount) { + Data = new ArraySegment(data.Array!, startIndex + data.Offset, wordCount * 2); } - internal MbWords(Byte[] data, Byte startIndex, UInt16 wordCount) - { - _Data = new ArraySegment(data, startIndex, wordCount * 2); - } - private static UInt16 CountWords(ArraySegment data, Byte startIndex) { var wordCount = (data.Count - startIndex) / 2; @@ -27,14 +24,14 @@ public readonly struct MbWords : IReadOnlyList internal IReadOnlyCollection Set(IReadOnlyCollection values) { - if (values.Count != _Data.Count / 2) + if (values.Count != Data.Count / 2) throw new ArgumentException($"Expecting an list of size {values.Count}!", nameof(values)); var i = 0; foreach (var value in values) { - _Data[i++] = (Byte) (value >> 8); - _Data[i++] = (Byte) (value & 0xFF); + Data[i++] = (Byte) (value >> 8); + Data[i++] = (Byte) (value & 0xFF); } return values; @@ -43,12 +40,12 @@ public readonly struct MbWords : IReadOnlyList public IEnumerator GetEnumerator() { - var end = _Data.Count; + var end = Data.Count; for (var i = 0; i < end; ) { - var hi = _Data[i++] << 8; - var lo = _Data[i++]; + var hi = Data[i++] << 8; + var lo = Data[i++]; yield return (UInt16) (hi | lo); } @@ -56,7 +53,7 @@ public readonly struct MbWords : IReadOnlyList IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - public Int32 Count => _Data.Count / 2; + public Int32 Count => Data.Count / 2; public UInt16 this[Int32 index] { @@ -66,17 +63,20 @@ public readonly struct MbWords : IReadOnlyList { var i = index * 2; - var hi = _Data[i] << 8; - var lo = _Data[i+1]; + var hi = Data[i] << 8; + var lo = Data[i+1]; return (UInt16) (hi | lo); } - set - { - var i = index * 2; - _Data[i + 0] = (Byte)(value >> 8); - _Data[i + 1] = (Byte)(value & 0xFF); - } + } + + public UInt16 GetUInt16(Byte index) => this[index]; + + public void SetUInt16(Byte index, UInt16 value) + { + var i = index * 2; + Data[i + 0] = (Byte)(value >> 8); + Data[i + 1] = (Byte)(value & 0xFF); } } \ No newline at end of file diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadDiscreteInputsCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadDiscreteInputsCommandFrame.cs index 88461e76e..325d88e5c 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadDiscreteInputsCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadDiscreteInputsCommandFrame.cs @@ -13,8 +13,8 @@ internal class ReadDiscreteInputsCommandFrame : ModbusFrame { private const Int32 Size = 6; - private MbAddress ReadAddress => Data.AddressAt(2); - private MbWord QuantityOfInputs => Data.WordAt(4); + private MbWord ReadAddress => Data.WordAt(2); + private MbWord QuantityOfInputs => Data.WordAt(4); public ReadDiscreteInputsCommandFrame(Byte slave, UInt16 readAddress, UInt16 nBits) : base(Size) diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadHoldingRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadHoldingRegistersCommandFrame.cs index b03914c0a..9134b0be9 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadHoldingRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadHoldingRegistersCommandFrame.cs @@ -14,8 +14,8 @@ internal class ReadHoldingRegistersCommandFrame : ModbusFrame internal const Int32 Size = 6; - public MbAddress ReadAddress => Data.AddressAt(2); - public MbWord NbToRead => Data.WordAt(4); + public MbWord ReadAddress => Data.WordAt(2); + public MbWord NbToRead => Data.WordAt(4); public Int32 ExpectedResponseSize => ReadHoldingRegistersResponseFrame.ExpectedSize(NbToRead); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadInputRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadInputRegistersCommandFrame.cs index f06845565..a17fe34f8 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadInputRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadInputRegistersCommandFrame.cs @@ -11,8 +11,8 @@ internal class ReadInputRegistersCommandFrame : ModbusFrame { internal const Int32 Size = 6; - public MbAddress ReadAddress => Data.AddressAt(2); - public MbWord NbToRead => Data.WordAt(4); + public MbWord ReadAddress => Data.WordAt(2); + public MbWord NbToRead => Data.WordAt(4); public Int32 ExpectedResponseSize => ReadInputRegistersResponseFrame.ExpectedSize(NbToRead); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs index 57f86d379..e280c071d 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/ReadWriteRegistersCommandFrame.cs @@ -11,12 +11,12 @@ internal class ReadWriteRegistersCommandFrame : ModbusFrame { internal new const Int32 MinSize = 11; - public MbAddress ReadAddress => Data.AddressAt(2); + public MbWord ReadAddress => Data.WordAt(2); public MbWord NbToRead => Data.WordAt(4); - public MbAddress WriteAddress => Data.AddressAt(6); + public MbWord WriteAddress => Data.WordAt(6); public MbWord NbToWrite => Data.WordAt(8); public MbByte ByteCount => Data.ByteAt(10); - public MbRegisters RegistersToWrite => Data.RegistersAt(11); + public MbWords RegistersToWrite => Data.WordsAt(11); public Int32 ExpectedResponseSize => ReadWriteRegistersResponseFrame.ExpectedSize(NbToRead); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteCoilsCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteCoilsCommandFrame.cs index 5865ddd21..e366616cb 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteCoilsCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteCoilsCommandFrame.cs @@ -14,10 +14,10 @@ public class WriteCoilsCommandFrame : ModbusFrame { private new const Int32 MinSize = 7; - private MbAddress WriteAddress => Data.AddressAt(2); - private MbWord NbOfCoils => Data.WordAt(4); - private MbByte ByteCount => Data.ByteAt(6); - public MbBits CoilsToWrite => Data.BitsAt(7); + private MbWord WriteAddress => Data.WordAt(2); + private MbWord NbOfCoils => Data.WordAt(4); + private MbByte ByteCount => Data.ByteAt(6); + public MbBits CoilsToWrite => Data.BitsAt(7); public WriteCoilsCommandFrame(Byte slave, UInt16 writeAddress, Booleans coils) : base(MinSize + NbBytes(coils)) { diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs index 8eb4ca915..b317767c1 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Commands/WriteRegistersCommandFrame.cs @@ -11,10 +11,10 @@ internal class WriteRegistersCommandFrame : ModbusFrame { internal new const Int32 MinSize = 7; - public MbAddress WriteAddress => Data.AddressAt(2); - public MbWord NbOfRegisters => Data.WordAt(4); - public MbByte ByteCount => Data.ByteAt(6); - public MbRegisters RegistersToWrite => Data.RegistersAt(7); + public MbWord WriteAddress => Data.WordAt(2); + public MbWord NbOfRegisters => Data.WordAt(4); + public MbByte ByteCount => Data.ByteAt(6); + public MbWords RegistersToWrite => Data.WordsAt(7); public Int32 ExpectedResponseSize => WriteRegistersResponseFrame.ExpectedSize(); diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/ModbusFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/ModbusFrame.cs index 539551b92..fa1c3b008 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/ModbusFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/ModbusFrame.cs @@ -17,7 +17,7 @@ public class ModbusFrame internal ModbusFrame(Int32 size) { - Data = new ArraySegment(new Byte[size]); + Data = new Byte[size]; } diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs index ba8b3e707..7fcd77983 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadHoldingRegistersResponseFrame.cs @@ -11,7 +11,7 @@ internal class ReadHoldingRegistersResponseFrame : ModbusFrame internal new const Int32 MinSize = 3; public MbByte ByteCount => Data.ByteAt(2); - public MbRegisters RegistersRead => Data.RegistersAt(3); + public MbWords RegistersRead => Data.WordsAt(3); public ReadHoldingRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count)) diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs index bb301e638..29cebda39 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadInputRegistersResponseFrame.cs @@ -12,7 +12,7 @@ internal class ReadInputRegistersResponseFrame : ModbusFrame internal new const Int32 MinSize = 3; public MbByte ByteCount => Data.ByteAt(2); - public MbRegisters RegistersRead => Data.RegistersAt(3); + public MbWords RegistersRead => Data.WordsAt(3); public ReadInputRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count)) { diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs index ce7ecf2da..43eed5e21 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/ReadWriteRegistersCommandFrame.cs @@ -12,7 +12,7 @@ internal class ReadWriteRegistersResponseFrame : ModbusFrame internal new const Int32 MinSize = 3; public MbByte ByteCount => Data.ByteAt(2); - public MbRegisters RegistersRead => Data.RegistersAt(3); + public MbWords RegistersRead => Data.WordsAt(3); public ReadWriteRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count)) { diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteCoilsResponseFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteCoilsResponseFrame.cs index 6ec170980..76518a0e5 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteCoilsResponseFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteCoilsResponseFrame.cs @@ -7,8 +7,8 @@ public class WriteCoilsResponseFrame : ModbusFrame { private const Int32 Size = 6; - public MbAddress WriteAddress => Data.AddressAt(2); - public MbWord NbWritten => Data.WordAt(4); + public MbWord WriteAddress => Data.WordAt(2); + public MbWord NbWritten => Data.WordAt(4); internal static Int32 ExpectedSize() => Size; diff --git a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteRegistersResponseFrame.cs b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteRegistersResponseFrame.cs index 2817c3460..76a0a6b7d 100644 --- a/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteRegistersResponseFrame.cs +++ b/csharp/Lib/Protocols/Modbus/Protocol/Frames/Replies/WriteRegistersResponseFrame.cs @@ -7,8 +7,8 @@ internal class WriteRegistersResponseFrame : ModbusFrame { private const Int32 Size = 6; - public MbAddress WriteAddress => Data.AddressAt(2); - public MbWord NbWritten => Data.WordAt(4); + public MbWord WriteAddress => Data.WordAt(2); + public MbWord NbWritten => Data.WordAt(4); internal static Int32 ExpectedSize() => Size;