remove MbAddress type

This commit is contained in:
ig 2023-03-10 13:46:46 +01:00
parent 2d242f25b7
commit df087b9d8e
16 changed files with 153 additions and 74 deletions

View File

@ -2,12 +2,8 @@ namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors;
public static class Accessors public static class Accessors
{ {
public static MbByte ByteAt(this Byte[] data, Byte i) => new MbByte(new ArraySegment<Byte>(data), i);
public static MbWord WordAt(this Byte[] data, Byte i) => new MbWord(new ArraySegment<Byte>(data), i);
public static MbByte ByteAt (this ArraySegment<Byte> data, Byte i) => new MbByte(data, i); public static MbByte ByteAt (this ArraySegment<Byte> data, Byte i) => new MbByte(data, i);
public static MbWord WordAt (this ArraySegment<Byte> data, Byte i) => new MbWord(data, i); public static MbWord WordAt (this ArraySegment<Byte> data, Byte i) => new MbWord(data, i);
public static MbAddress AddressAt(this ArraySegment<Byte> data, Byte i) => new MbAddress(data, i);
public static MbWords WordsAt (this ArraySegment<Byte> data, Byte i) => new MbWords(data, i); public static MbWords WordsAt (this ArraySegment<Byte> data, Byte i) => new MbWords(data, i);
public static MbBits BitsAt (this ArraySegment<Byte> data, Byte i) => new MbBits(data, i); public static MbBits BitsAt (this ArraySegment<Byte> data, Byte i) => new MbBits(data, i);
public static MbByte<T> ByteAt<T>(this ArraySegment<Byte> data,Byte i) where T : struct, IConvertible => new MbByte<T>(data, i); public static MbByte<T> ByteAt<T>(this ArraySegment<Byte> data,Byte i) where T : struct, IConvertible => new MbByte<T>(data, i);

View File

@ -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<Byte> 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<UInt16>().Apply(Set);
public static implicit operator UInt16(MbAddress w) => w.Get();
public override String ToString() => Get().ToString();
}

View File

@ -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<UInt16>
{
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<UInt16> 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)
}

View File

@ -5,20 +5,17 @@ namespace InnovEnergy.Lib.Protocols.Modbus.Protocol.Frames.Accessors;
public readonly struct MbWords : IReadOnlyList<UInt16> public readonly struct MbWords : IReadOnlyList<UInt16>
{ {
private readonly ArraySegment<Byte> _Data; internal readonly ArraySegment<Byte> Data;
internal MbWords(ArraySegment<Byte> data, Byte startIndex) : this(data, startIndex, CountWords(data, startIndex)) internal MbWords(ArraySegment<Byte> data, Byte startIndex = 0) :
this(data, startIndex, CountWords(data, startIndex))
{ } { }
internal MbWords(ArraySegment<Byte> data, Byte startIndex, UInt16 wordCount) : this(data.Array!, startIndex, wordCount) internal MbWords(ArraySegment<Byte> data, Byte startIndex, UInt16 wordCount)
{ {
Data = new ArraySegment<Byte>(data.Array!, startIndex + data.Offset, wordCount * 2);
} }
internal MbWords(Byte[] data, Byte startIndex, UInt16 wordCount)
{
_Data = new ArraySegment<Byte>(data, startIndex, wordCount * 2);
}
private static UInt16 CountWords(ArraySegment<Byte> data, Byte startIndex) private static UInt16 CountWords(ArraySegment<Byte> data, Byte startIndex)
{ {
var wordCount = (data.Count - startIndex) / 2; var wordCount = (data.Count - startIndex) / 2;
@ -27,14 +24,14 @@ public readonly struct MbWords : IReadOnlyList<UInt16>
internal IReadOnlyCollection<UInt16> Set(IReadOnlyCollection<UInt16> values) internal IReadOnlyCollection<UInt16> Set(IReadOnlyCollection<UInt16> 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)); throw new ArgumentException($"Expecting an list of size {values.Count}!", nameof(values));
var i = 0; var i = 0;
foreach (var value in values) foreach (var value in values)
{ {
_Data[i++] = (Byte) (value >> 8); Data[i++] = (Byte) (value >> 8);
_Data[i++] = (Byte) (value & 0xFF); Data[i++] = (Byte) (value & 0xFF);
} }
return values; return values;
@ -43,12 +40,12 @@ public readonly struct MbWords : IReadOnlyList<UInt16>
public IEnumerator<UInt16> GetEnumerator() public IEnumerator<UInt16> GetEnumerator()
{ {
var end = _Data.Count; var end = Data.Count;
for (var i = 0; i < end; ) for (var i = 0; i < end; )
{ {
var hi = _Data[i++] << 8; var hi = Data[i++] << 8;
var lo = _Data[i++]; var lo = Data[i++];
yield return (UInt16) (hi | lo); yield return (UInt16) (hi | lo);
} }
@ -56,7 +53,7 @@ public readonly struct MbWords : IReadOnlyList<UInt16>
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public Int32 Count => _Data.Count / 2; public Int32 Count => Data.Count / 2;
public UInt16 this[Int32 index] public UInt16 this[Int32 index]
{ {
@ -66,17 +63,20 @@ public readonly struct MbWords : IReadOnlyList<UInt16>
{ {
var i = index * 2; var i = index * 2;
var hi = _Data[i] << 8; var hi = Data[i] << 8;
var lo = _Data[i+1]; var lo = Data[i+1];
return (UInt16) (hi | lo); return (UInt16) (hi | lo);
} }
set }
{
var i = index * 2; public UInt16 GetUInt16(Byte index) => this[index];
_Data[i + 0] = (Byte)(value >> 8);
_Data[i + 1] = (Byte)(value & 0xFF); public void SetUInt16(Byte index, UInt16 value)
} {
var i = index * 2;
Data[i + 0] = (Byte)(value >> 8);
Data[i + 1] = (Byte)(value & 0xFF);
} }
} }

View File

@ -13,8 +13,8 @@ internal class ReadDiscreteInputsCommandFrame : ModbusFrame
{ {
private const Int32 Size = 6; private const Int32 Size = 6;
private MbAddress ReadAddress => Data.AddressAt(2); private MbWord ReadAddress => Data.WordAt(2);
private MbWord QuantityOfInputs => Data.WordAt(4); private MbWord QuantityOfInputs => Data.WordAt(4);
public ReadDiscreteInputsCommandFrame(Byte slave, UInt16 readAddress, UInt16 nBits) : base(Size) public ReadDiscreteInputsCommandFrame(Byte slave, UInt16 readAddress, UInt16 nBits) : base(Size)

View File

@ -14,8 +14,8 @@ internal class ReadHoldingRegistersCommandFrame : ModbusFrame
internal const Int32 Size = 6; internal const Int32 Size = 6;
public MbAddress ReadAddress => Data.AddressAt(2); public MbWord ReadAddress => Data.WordAt(2);
public MbWord NbToRead => Data.WordAt(4); public MbWord NbToRead => Data.WordAt(4);
public Int32 ExpectedResponseSize => ReadHoldingRegistersResponseFrame.ExpectedSize(NbToRead); public Int32 ExpectedResponseSize => ReadHoldingRegistersResponseFrame.ExpectedSize(NbToRead);

View File

@ -11,8 +11,8 @@ internal class ReadInputRegistersCommandFrame : ModbusFrame
{ {
internal const Int32 Size = 6; internal const Int32 Size = 6;
public MbAddress ReadAddress => Data.AddressAt(2); public MbWord ReadAddress => Data.WordAt(2);
public MbWord NbToRead => Data.WordAt(4); public MbWord NbToRead => Data.WordAt(4);
public Int32 ExpectedResponseSize => ReadInputRegistersResponseFrame.ExpectedSize(NbToRead); public Int32 ExpectedResponseSize => ReadInputRegistersResponseFrame.ExpectedSize(NbToRead);

View File

@ -11,12 +11,12 @@ internal class ReadWriteRegistersCommandFrame : ModbusFrame
{ {
internal new const Int32 MinSize = 11; 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 MbWord NbToRead => Data.WordAt(4);
public MbAddress WriteAddress => Data.AddressAt(6); public MbWord WriteAddress => Data.WordAt(6);
public MbWord NbToWrite => Data.WordAt(8); public MbWord NbToWrite => Data.WordAt(8);
public MbByte ByteCount => Data.ByteAt(10); public MbByte ByteCount => Data.ByteAt(10);
public MbRegisters RegistersToWrite => Data.RegistersAt(11); public MbWords RegistersToWrite => Data.WordsAt(11);
public Int32 ExpectedResponseSize => ReadWriteRegistersResponseFrame.ExpectedSize(NbToRead); public Int32 ExpectedResponseSize => ReadWriteRegistersResponseFrame.ExpectedSize(NbToRead);

View File

@ -14,10 +14,10 @@ public class WriteCoilsCommandFrame : ModbusFrame
{ {
private new const Int32 MinSize = 7; private new const Int32 MinSize = 7;
private MbAddress WriteAddress => Data.AddressAt(2); private MbWord WriteAddress => Data.WordAt(2);
private MbWord NbOfCoils => Data.WordAt(4); private MbWord NbOfCoils => Data.WordAt(4);
private MbByte ByteCount => Data.ByteAt(6); private MbByte ByteCount => Data.ByteAt(6);
public MbBits CoilsToWrite => Data.BitsAt(7); public MbBits CoilsToWrite => Data.BitsAt(7);
public WriteCoilsCommandFrame(Byte slave, UInt16 writeAddress, Booleans coils) : base(MinSize + NbBytes(coils)) public WriteCoilsCommandFrame(Byte slave, UInt16 writeAddress, Booleans coils) : base(MinSize + NbBytes(coils))
{ {

View File

@ -11,10 +11,10 @@ internal class WriteRegistersCommandFrame : ModbusFrame
{ {
internal new const Int32 MinSize = 7; internal new const Int32 MinSize = 7;
public MbAddress WriteAddress => Data.AddressAt(2); public MbWord WriteAddress => Data.WordAt(2);
public MbWord NbOfRegisters => Data.WordAt(4); public MbWord NbOfRegisters => Data.WordAt(4);
public MbByte ByteCount => Data.ByteAt(6); public MbByte ByteCount => Data.ByteAt(6);
public MbRegisters RegistersToWrite => Data.RegistersAt(7); public MbWords RegistersToWrite => Data.WordsAt(7);
public Int32 ExpectedResponseSize => WriteRegistersResponseFrame.ExpectedSize(); public Int32 ExpectedResponseSize => WriteRegistersResponseFrame.ExpectedSize();

View File

@ -17,7 +17,7 @@ public class ModbusFrame
internal ModbusFrame(Int32 size) internal ModbusFrame(Int32 size)
{ {
Data = new ArraySegment<Byte>(new Byte[size]); Data = new Byte[size];
} }

View File

@ -11,7 +11,7 @@ internal class ReadHoldingRegistersResponseFrame : ModbusFrame
internal new const Int32 MinSize = 3; internal new const Int32 MinSize = 3;
public MbByte ByteCount => Data.ByteAt(2); 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)) public ReadHoldingRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count))

View File

@ -12,7 +12,7 @@ internal class ReadInputRegistersResponseFrame : ModbusFrame
internal new const Int32 MinSize = 3; internal new const Int32 MinSize = 3;
public MbByte ByteCount => Data.ByteAt(2); 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)) public ReadInputRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count))
{ {

View File

@ -12,7 +12,7 @@ internal class ReadWriteRegistersResponseFrame : ModbusFrame
internal new const Int32 MinSize = 3; internal new const Int32 MinSize = 3;
public MbByte ByteCount => Data.ByteAt(2); 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)) public ReadWriteRegistersResponseFrame(Byte slave, UInt16s registersRead) : base(ExpectedSize(registersRead.Count))
{ {

View File

@ -7,8 +7,8 @@ public class WriteCoilsResponseFrame : ModbusFrame
{ {
private const Int32 Size = 6; private const Int32 Size = 6;
public MbAddress WriteAddress => Data.AddressAt(2); public MbWord WriteAddress => Data.WordAt(2);
public MbWord NbWritten => Data.WordAt(4); public MbWord NbWritten => Data.WordAt(4);
internal static Int32 ExpectedSize() => Size; internal static Int32 ExpectedSize() => Size;

View File

@ -7,8 +7,8 @@ internal class WriteRegistersResponseFrame : ModbusFrame
{ {
private const Int32 Size = 6; private const Int32 Size = 6;
public MbAddress WriteAddress => Data.AddressAt(2); public MbWord WriteAddress => Data.WordAt(2);
public MbWord NbWritten => Data.WordAt(4); public MbWord NbWritten => Data.WordAt(4);
internal static Int32 ExpectedSize() => Size; internal static Int32 ExpectedSize() => Size;