mirror of
https://github.com/OpenLogics/MewtocolNet.git
synced 2025-12-06 03:01:24 +00:00
Adjusted for new mewtocol ver
This commit is contained in:
@@ -8,7 +8,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\MewtocolNet\MewtocolNet.csproj" />
|
<ProjectReference Include="..\MewtocolNet\MewtocolNet.csproj"/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ public class TestRegisterCollection : RegisterCollection {
|
|||||||
[Register("R16B")]
|
[Register("R16B")]
|
||||||
public bool TestR16B { get; set; }
|
public bool TestR16B { get; set; }
|
||||||
|
|
||||||
|
[Register("R902")]
|
||||||
|
public bool Test { get; set; }
|
||||||
|
|
||||||
[BitRegister("DT1000", 0), PollLevel(3)]
|
[BitRegister("DT1000", 0), PollLevel(3)]
|
||||||
public bool? TestDT100_Word_Duplicate_SingleBit { get; set; }
|
public bool? TestDT100_Word_Duplicate_SingleBit { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using Examples.WPF.ViewModels;
|
using Examples.WPF.ViewModels;
|
||||||
using MewtocolNet;
|
using MewtocolNet;
|
||||||
using MewtocolNet.ComCassette;
|
using MewtocolNet.ComCassette;
|
||||||
|
using MewtocolNet.Logging;
|
||||||
using MewtocolNet.Registers;
|
using MewtocolNet.Registers;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -106,25 +107,44 @@ public partial class ConnectView : UserControl {
|
|||||||
b.Struct<float>("DDT1016").PollLevel(2).Build();
|
b.Struct<float>("DDT1016").PollLevel(2).Build();
|
||||||
b.Struct<TimeSpan>("DDT1018").PollLevel(2).Build();
|
b.Struct<TimeSpan>("DDT1018").PollLevel(2).Build();
|
||||||
|
|
||||||
b.String("DT1024", 32).PollLevel(3).Build();
|
b.Struct<DateAndTime>("DDT1020").PollLevel(2).Build();
|
||||||
b.String("DT1042", 5).PollLevel(4).Build();
|
b.Struct<DateAndTime>("DDT1022").PollLevel(2).Build();
|
||||||
|
|
||||||
|
b.String("DT1028", 32).PollLevel(3).Build();
|
||||||
|
b.String("DT1046", 5).PollLevel(4).Build();
|
||||||
|
|
||||||
|
b.Struct<Word>("DT1000").AsArray(5).PollLevel(1).Build();
|
||||||
|
|
||||||
})
|
})
|
||||||
.WithHeartbeatTask(async () => {
|
.WithHeartbeatTask(async (plc) => {
|
||||||
|
|
||||||
await heartbeatSetter.WriteAsync((short)new Random().Next(short.MinValue, short.MaxValue));
|
var randShort = (short)new Random().Next(short.MinValue, short.MaxValue);
|
||||||
|
|
||||||
if (outputContactReference.Value != null)
|
//write direct
|
||||||
await outputContactReference.WriteAsync(!outputContactReference.Value.Value);
|
//await heartbeatSetter.WriteAsync(randShort);
|
||||||
|
//or by anonymous
|
||||||
|
await plc.Register.Struct<short>("DT1000").WriteAsync(randShort);
|
||||||
|
|
||||||
if(testBoolReference.Value != null)
|
//write a register without a reference
|
||||||
|
bool randBool = new Random().Next(0, 2) == 1;
|
||||||
|
await plc.Register.Bool("Y4").WriteAsync(randBool);
|
||||||
|
|
||||||
|
if (testBoolReference.Value != null)
|
||||||
await testBoolReference.WriteAsync(!testBoolReference.Value.Value);
|
await testBoolReference.WriteAsync(!testBoolReference.Value.Value);
|
||||||
|
|
||||||
|
await plc.Register.Struct<DateAndTime>("DDT1022").WriteAsync(DateAndTime.FromDateTime(DateTime.UtcNow));
|
||||||
|
|
||||||
})
|
})
|
||||||
.Build();
|
.Build();
|
||||||
|
|
||||||
//connect to it
|
//connect to it
|
||||||
await App.ViewModel.Plc.ConnectAsync();
|
await App.ViewModel.Plc.ConnectAsync(async () => {
|
||||||
|
|
||||||
|
await App.ViewModel.Plc.RestartProgramAsync();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
await App.ViewModel.Plc.AwaitFirstDataCycleAsync();
|
||||||
|
|
||||||
if (App.ViewModel.Plc.IsConnected) {
|
if (App.ViewModel.Plc.IsConnected) {
|
||||||
|
|
||||||
|
|||||||
@@ -49,6 +49,21 @@
|
|||||||
Fill="Lime"
|
Fill="Lime"
|
||||||
IsEnabled="{Binding Plc.IsConnected}"/>
|
IsEnabled="{Binding Plc.IsConnected}"/>
|
||||||
|
|
||||||
|
<Run>
|
||||||
|
<Run.Style>
|
||||||
|
<Style TargetType="Run">
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding Plc.IsRunMode, Mode=OneWay}" Value="True">
|
||||||
|
<Setter Property="Text" Value="RUN MODE"/>
|
||||||
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Plc.IsRunMode, Mode=OneWay}" Value="False">
|
||||||
|
<Setter Property="Text" Value="NO RUN MODE"/>
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
</Run.Style>
|
||||||
|
</Run>
|
||||||
|
|
||||||
<TextBlock.Style>
|
<TextBlock.Style>
|
||||||
<Style TargetType="TextBlock">
|
<Style TargetType="TextBlock">
|
||||||
<Style.Triggers>
|
<Style.Triggers>
|
||||||
@@ -156,10 +171,13 @@
|
|||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
<RowDefinition Height="auto"/>
|
<RowDefinition Height="auto"/>
|
||||||
<RowDefinition/>
|
<RowDefinition/>
|
||||||
|
<RowDefinition Height="auto"/>
|
||||||
|
<RowDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<GridSplitter Grid.Column="1"
|
<GridSplitter Grid.Column="1"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
|
Grid.RowSpan="3"
|
||||||
VerticalAlignment="Stretch"
|
VerticalAlignment="Stretch"
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
Background="Gray"
|
Background="Gray"
|
||||||
@@ -179,6 +197,7 @@
|
|||||||
Margin="10"/>
|
Margin="10"/>
|
||||||
|
|
||||||
<DataGrid Grid.Row="1"
|
<DataGrid Grid.Row="1"
|
||||||
|
Grid.RowSpan="3"
|
||||||
AutoGenerateColumns="False"
|
AutoGenerateColumns="False"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
ItemsSource="{Binding Plc.Registers, Mode=OneWay}">
|
ItemsSource="{Binding Plc.Registers, Mode=OneWay}">
|
||||||
@@ -219,14 +238,14 @@
|
|||||||
<DataGridTemplateColumn Width="15">
|
<DataGridTemplateColumn Width="15">
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border Background="{Binding MemoryAreaHash, Mode=OneWay, Converter={StaticResource hashColor}}"/>
|
<Border Background="{Binding MemoryArea, Mode=OneWay, Converter={StaticResource hashColor}}"/>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
|
|
||||||
<TextBlock Text="Property Bindings"
|
<TextBlock Text="Memory Areas"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
FontSize="18"
|
FontSize="18"
|
||||||
Margin="10"/>
|
Margin="10"/>
|
||||||
@@ -238,6 +257,43 @@
|
|||||||
BorderBrush="LightBlue"
|
BorderBrush="LightBlue"
|
||||||
BorderThickness="1.5">
|
BorderThickness="1.5">
|
||||||
|
|
||||||
|
<DataGrid IsReadOnly="True"
|
||||||
|
AutoGenerateColumns="False"
|
||||||
|
ItemsSource="{Binding Plc.MemoryAreas, Mode=OneWay}">
|
||||||
|
|
||||||
|
<DataGrid.Columns>
|
||||||
|
|
||||||
|
<DataGridTextColumn Header="Address Range" Binding="{Binding AddressRange, Mode=OneWay}"/>
|
||||||
|
|
||||||
|
<DataGridTemplateColumn Width="15">
|
||||||
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border Background="{Binding Converter={StaticResource hashColor}}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
|
</DataGridTemplateColumn>
|
||||||
|
|
||||||
|
<DataGridTextColumn Header="Words" Binding="{Binding UnderlyingWordsString, Mode=OneWay}"/>
|
||||||
|
|
||||||
|
</DataGrid.Columns>
|
||||||
|
|
||||||
|
</DataGrid>
|
||||||
|
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<TextBlock Text="Property Bindings"
|
||||||
|
Grid.Column="2"
|
||||||
|
Grid.Row="2"
|
||||||
|
FontSize="18"
|
||||||
|
Margin="10"/>
|
||||||
|
|
||||||
|
<Border Grid.Column="2"
|
||||||
|
Grid.Row="3"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
BorderBrush="LightBlue"
|
||||||
|
BorderThickness="1.5">
|
||||||
|
|
||||||
<ScrollViewer>
|
<ScrollViewer>
|
||||||
|
|
||||||
<StackPanel>
|
<StackPanel>
|
||||||
|
|||||||
92
MewtocolNet/CustomTypes/DateAndTime.cs
Normal file
92
MewtocolNet/CustomTypes/DateAndTime.cs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace MewtocolNet {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A DateAndTime struct of 4 bytes represented as seconds from 2001-01-01 in the PLC<br/>
|
||||||
|
/// This also works for the PLC type TIME_OF_DAY and DATE
|
||||||
|
/// </summary>
|
||||||
|
public struct DateAndTime : MewtocolExtTypeInit2Word {
|
||||||
|
|
||||||
|
internal DateTime value;
|
||||||
|
|
||||||
|
public DateAndTime(int year = 2001, int month = 1, int day = 1, int hour = 0, int minute = 0, int second = 0) {
|
||||||
|
|
||||||
|
var minDate = MinDate;
|
||||||
|
var maxDate = MaxDate;
|
||||||
|
|
||||||
|
if (year < 2001 || year > 2099)
|
||||||
|
throw new NotSupportedException("Year must be between 2001 and 2099");
|
||||||
|
|
||||||
|
if (month < 1 || month > 12)
|
||||||
|
throw new NotSupportedException("Month must be between 1 and 12");
|
||||||
|
|
||||||
|
if (day < 1 || day > 32)
|
||||||
|
throw new NotSupportedException("Day must be between 1 and 32");
|
||||||
|
|
||||||
|
if (day < 1 || day > 32)
|
||||||
|
throw new NotSupportedException("Month must be between 1 and 32");
|
||||||
|
|
||||||
|
var dt = new DateTime(year, month, day, hour, minute, second);
|
||||||
|
|
||||||
|
if (dt < minDate)
|
||||||
|
throw new Exception($"The minimal DATE_AND_TIME repesentation is {minDate}");
|
||||||
|
|
||||||
|
if (dt > maxDate)
|
||||||
|
throw new Exception($"The maximal DATE_AND_TIME repesentation is {maxDate}");
|
||||||
|
|
||||||
|
value = dt;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateAndTime FromBytes(byte[] bytes) {
|
||||||
|
|
||||||
|
var secondsFrom = BitConverter.ToUInt32(bytes, 0);
|
||||||
|
|
||||||
|
return FromDateTime(MinDate + TimeSpan.FromSeconds(secondsFrom));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static DateAndTime FromDateTime(DateTime time) => new DateAndTime(time.Year, time.Month, time.Day, time.Hour, time.Minute, time.Second);
|
||||||
|
|
||||||
|
//operations
|
||||||
|
|
||||||
|
public static TimeSpan operator -(DateAndTime a, DateAndTime b) => a.value - b.value;
|
||||||
|
|
||||||
|
public static DateAndTime operator +(DateAndTime a, TimeSpan b) => FromDateTime(a.value + b);
|
||||||
|
|
||||||
|
public static bool operator ==(DateAndTime a, DateAndTime b) => a.value == b.value;
|
||||||
|
|
||||||
|
public static bool operator !=(DateAndTime a, DateAndTime b) => a.value != b.value;
|
||||||
|
|
||||||
|
public override bool Equals(object obj) {
|
||||||
|
|
||||||
|
if ((obj == null) || !this.GetType().Equals(obj.GetType())) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return (DateAndTime)obj == this;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode() => value.GetHashCode();
|
||||||
|
|
||||||
|
public byte[] ToByteArray() => BitConverter.GetBytes(SecondsSinceStart());
|
||||||
|
|
||||||
|
public DateTime ToDateTime() => value;
|
||||||
|
|
||||||
|
private uint SecondsSinceStart() => (uint)(value - MinDate).TotalSeconds;
|
||||||
|
|
||||||
|
private static DateTime MinDate => new DateTime(2001, 01, 01, 0, 0, 0);
|
||||||
|
|
||||||
|
private static DateTime MaxDate => new DateTime(2099, 12, 31, 23, 59, 59);
|
||||||
|
|
||||||
|
//string ops
|
||||||
|
|
||||||
|
public override string ToString() => $"DT#{value:yyyy-MM-dd-HH:mm:ss}";
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -82,8 +82,11 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
typeCode = (int)t;
|
typeCode = (int)t;
|
||||||
discontinued = t.IsDiscontinued();
|
discontinued = t.IsDiscontinued();
|
||||||
|
|
||||||
|
#if Debug
|
||||||
exrt = t.IsEXRTPLC();
|
exrt = t.IsEXRTPLC();
|
||||||
tested = t.WasTestedLive();
|
tested = t.WasTestedLive();
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
using MewtocolNet.Events;
|
using MewtocolNet.Events;
|
||||||
using MewtocolNet.ProgramParsing;
|
using MewtocolNet.ProgramParsing;
|
||||||
using MewtocolNet.RegisterBuilding;
|
using MewtocolNet.RegisterBuilding;
|
||||||
|
using MewtocolNet.RegisterBuilding.BuilderPatterns;
|
||||||
using MewtocolNet.Registers;
|
using MewtocolNet.Registers;
|
||||||
|
using MewtocolNet.UnderlyingRegisters;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
@@ -69,6 +71,11 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
int PollerCycleDurationMs { get; }
|
int PollerCycleDurationMs { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shorthand indicator if the plc is in RUN mode
|
||||||
|
/// </summary>
|
||||||
|
bool IsRunMode { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Currently queued message count
|
/// Currently queued message count
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -96,10 +103,12 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
IEnumerable<IRegister> Registers { get; }
|
IEnumerable<IRegister> Registers { get; }
|
||||||
|
|
||||||
|
RBuildAnon Register { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tries to establish a connection with the device asynchronously
|
/// Tries to establish a connection with the device asynchronously
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="onConnected">A callback for excecuting something right after the plc connected</param>
|
/// <param name="onConnected">A callback for excecuting something inside the plc connetion process</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task ConnectAsync(Func<Task> onConnected = null);
|
Task ConnectAsync(Func<Task> onConnected = null);
|
||||||
|
|
||||||
@@ -187,6 +196,11 @@ namespace MewtocolNet {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
string Explain();
|
string Explain();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A readonly list of the underlying memory areas
|
||||||
|
/// </summary>
|
||||||
|
IReadOnlyList<IMemoryArea> MemoryAreas { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace MewtocolNet.Logging {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Defines the default output logger targets
|
/// Defines the default output logger targets
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static LoggerTargets DefaultTargets { get; set; } = LoggerTargets.Console;
|
public static LoggerTargets DefaultTargets { get; set; } = LoggerTargets.None;
|
||||||
|
|
||||||
internal static Action<DateTime, LogLevel, string> LogInvoked;
|
internal static Action<DateTime, LogLevel, string> LogInvoked;
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ namespace MewtocolNet.Logging {
|
|||||||
|
|
||||||
OnNewLogMessage((d, l, m) => {
|
OnNewLogMessage((d, l, m) => {
|
||||||
|
|
||||||
if(isConsoleApplication && DefaultTargets.HasFlag(LoggerTargets.Console)) {
|
if(isConsoleApplication || DefaultTargets.HasFlag(LoggerTargets.Console)) {
|
||||||
|
|
||||||
switch (l) {
|
switch (l) {
|
||||||
case LogLevel.Error:
|
case LogLevel.Error:
|
||||||
|
|||||||
@@ -379,12 +379,12 @@ namespace MewtocolNet
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// A builder for attaching register collections
|
/// A builder for attaching register collections
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public PostInit<T> WithRegisters(Action<RBuild> builder) {
|
public PostInit<T> WithRegisters(Action<RBuildMulti> builder) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
var plc = (MewtocolInterface)(object)intf;
|
var plc = (MewtocolInterface)(object)intf;
|
||||||
var regBuilder = new RBuild(plc);
|
var regBuilder = new RBuildMulti(plc);
|
||||||
|
|
||||||
builder.Invoke(regBuilder);
|
builder.Invoke(regBuilder);
|
||||||
|
|
||||||
@@ -406,7 +406,7 @@ namespace MewtocolNet
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="heartBeatAsync"></param>
|
/// <param name="heartBeatAsync"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public EndInitSetup<T> WithHeartbeatTask(Func<Task> heartBeatAsync, bool executeInProg = false) {
|
public EndInitSetup<T> WithHeartbeatTask(Func<IPlc,Task> heartBeatAsync, bool executeInProg = false) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
var plc = (MewtocolInterface)(object)this.intf;
|
var plc = (MewtocolInterface)(object)this.intf;
|
||||||
@@ -426,6 +426,14 @@ namespace MewtocolNet
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repeats the passed method each time the hearbeat is triggered,
|
||||||
|
/// use
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="heartBeatAsync"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public EndInitSetup<T> WithHeartbeatTask(Func<Task> heartBeatAsync, bool executeInProg = false) => WithHeartbeatTask(heartBeatAsync, executeInProg);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Builds and returns the final plc interface
|
/// Builds and returns the final plc interface
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
using MewtocolNet.Events;
|
using MewtocolNet.Events;
|
||||||
using MewtocolNet.Helpers;
|
using MewtocolNet.Helpers;
|
||||||
using MewtocolNet.Logging;
|
using MewtocolNet.Logging;
|
||||||
|
using MewtocolNet.RegisterBuilding.BuilderPatterns;
|
||||||
using MewtocolNet.Registers;
|
using MewtocolNet.Registers;
|
||||||
using MewtocolNet.UnderlyingRegisters;
|
using MewtocolNet.UnderlyingRegisters;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -156,6 +158,9 @@ namespace MewtocolNet {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int BytesPerSecondDownstream => bytesPerSecondDownstream;
|
public int BytesPerSecondDownstream => bytesPerSecondDownstream;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool IsRunMode => PlcInfo.IsRunMode;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public MewtocolVersion MewtocolVersion {
|
public MewtocolVersion MewtocolVersion {
|
||||||
get => mewtocolVersion;
|
get => mewtocolVersion;
|
||||||
@@ -168,6 +173,9 @@ namespace MewtocolNet {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string ConnectionInfo => GetConnectionInfo();
|
public string ConnectionInfo => GetConnectionInfo();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public RBuildAnon Register => new RBuildAnon(this);
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Public read/write Properties / Fields
|
#region Public read/write Properties / Fields
|
||||||
@@ -191,6 +199,21 @@ namespace MewtocolNet {
|
|||||||
Disconnected += MewtocolInterface_Disconnected;
|
Disconnected += MewtocolInterface_Disconnected;
|
||||||
RegisterChanged += OnRegisterChanged;
|
RegisterChanged += OnRegisterChanged;
|
||||||
|
|
||||||
|
PropertyChanged += (s, e) => {
|
||||||
|
if (e.PropertyName == nameof(PlcInfo)) {
|
||||||
|
PlcInfo.PropertyChanged += (s1, e1) => {
|
||||||
|
if (e1.PropertyName == nameof(PlcInfo.IsRunMode))
|
||||||
|
OnPropChange(nameof(IsRunMode));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
memoryManager.MemoryLayoutChanged += () => {
|
||||||
|
|
||||||
|
OnPropChange(nameof(MemoryAreas));
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal MewtocolInterface Build () {
|
internal MewtocolInterface Build () {
|
||||||
@@ -269,10 +292,19 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
if (callBack != null) {
|
if (callBack != null) {
|
||||||
|
|
||||||
await Task.Run(callBack);
|
await callBack();
|
||||||
|
|
||||||
Logger.Log($">> OnConnected run complete <<", LogLevel.Verbose, this);
|
Logger.Log($">> OnConnected run complete <<", LogLevel.Verbose, this);
|
||||||
|
|
||||||
|
//run all register collection on online tasks
|
||||||
|
foreach (var col in registerCollections) {
|
||||||
|
|
||||||
|
await col.OnInterfaceLinkedAndOnline(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.Log($">> OnConnected register collections run complete <<", LogLevel.Verbose, this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -281,7 +313,14 @@ namespace MewtocolNet {
|
|||||||
protected virtual Task ReconnectAsync(int conTimeout) => throw new NotImplementedException();
|
protected virtual Task ReconnectAsync(int conTimeout) => throw new NotImplementedException();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task AwaitFirstDataCycleAsync() => await firstPollTask;
|
public async Task AwaitFirstDataCycleAsync() {
|
||||||
|
|
||||||
|
if(firstPollTask != null && !firstPollTask.IsCompleted)
|
||||||
|
await firstPollTask;
|
||||||
|
|
||||||
|
await Task.CompletedTask;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async Task DisconnectAsync() {
|
public async Task DisconnectAsync() {
|
||||||
@@ -842,22 +881,8 @@ namespace MewtocolNet {
|
|||||||
isReconnectingStage = false;
|
isReconnectingStage = false;
|
||||||
isConnectingStage = false;
|
isConnectingStage = false;
|
||||||
|
|
||||||
if (!usePoller) {
|
|
||||||
firstPollTask.RunSynchronously();
|
|
||||||
}
|
|
||||||
|
|
||||||
Connected?.Invoke(this, new PlcConnectionArgs());
|
Connected?.Invoke(this, new PlcConnectionArgs());
|
||||||
|
|
||||||
PolledCycle += OnPollCycleDone;
|
|
||||||
void OnPollCycleDone() {
|
|
||||||
|
|
||||||
if(firstPollTask != null && !firstPollTask.IsCompleted)
|
|
||||||
firstPollTask.RunSynchronously();
|
|
||||||
|
|
||||||
PolledCycle -= OnPollCycleDone;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private protected void OnReconnected () {
|
private protected void OnReconnected () {
|
||||||
@@ -982,8 +1007,12 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public string Explain() => memoryManager.ExplainLayout();
|
public string Explain() => memoryManager.ExplainLayout();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IReadOnlyList<IMemoryArea> MemoryAreas => memoryManager.GetAllMemoryAreas();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,10 +18,11 @@ namespace MewtocolNet {
|
|||||||
public abstract partial class MewtocolInterface {
|
public abstract partial class MewtocolInterface {
|
||||||
|
|
||||||
private bool heartbeatNeedsRun = false;
|
private bool heartbeatNeedsRun = false;
|
||||||
|
private bool heartbeatTimerRunning = false;
|
||||||
|
|
||||||
internal Task heartbeatTask = Task.CompletedTask;
|
internal Task heartbeatTask = Task.CompletedTask;
|
||||||
|
|
||||||
internal Func<Task> heartbeatCallbackTask;
|
internal Func<IPlc, Task> heartbeatCallbackTask;
|
||||||
internal bool execHeartBeatCallbackTaskInProg = false;
|
internal bool execHeartBeatCallbackTaskInProg = false;
|
||||||
|
|
||||||
internal Task pollCycleTask;
|
internal Task pollCycleTask;
|
||||||
@@ -73,6 +74,7 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
heartBeatTimer.Elapsed -= PollTimerTick;
|
heartBeatTimer.Elapsed -= PollTimerTick;
|
||||||
heartBeatTimer.Dispose();
|
heartBeatTimer.Dispose();
|
||||||
|
heartbeatTimerRunning = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,12 +84,15 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
if (!IsConnected) return;
|
if (!IsConnected) return;
|
||||||
|
|
||||||
heartBeatTimer = new System.Timers.Timer();
|
if(!heartbeatTimerRunning) {
|
||||||
heartBeatTimer.Interval = 3000;
|
heartBeatTimer = new System.Timers.Timer();
|
||||||
heartBeatTimer.Elapsed += PollTimerTick;
|
heartBeatTimer.Interval = 3000;
|
||||||
heartBeatTimer.Start();
|
heartBeatTimer.Elapsed += PollTimerTick;
|
||||||
|
heartBeatTimer.Start();
|
||||||
|
heartbeatTimerRunning = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (!usePoller) return;
|
if (!usePoller || PollerActive) return;
|
||||||
|
|
||||||
bool hasCyclic = memoryManager.HasCyclicPollableRegisters();
|
bool hasCyclic = memoryManager.HasCyclicPollableRegisters();
|
||||||
bool hasFirstCycle = memoryManager.HasSingleCyclePollableRegisters();
|
bool hasFirstCycle = memoryManager.HasSingleCyclePollableRegisters();
|
||||||
@@ -154,7 +159,7 @@ namespace MewtocolNet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(heartbeatCallbackTask != null && (plcInfo.IsRunMode || execHeartBeatCallbackTaskInProg))
|
if(heartbeatCallbackTask != null && (plcInfo.IsRunMode || execHeartBeatCallbackTaskInProg))
|
||||||
await heartbeatCallbackTask();
|
await heartbeatCallbackTask(this);
|
||||||
|
|
||||||
Logger.LogVerbose("End heartbeat", this);
|
Logger.LogVerbose("End heartbeat", this);
|
||||||
|
|
||||||
@@ -235,6 +240,12 @@ namespace MewtocolNet {
|
|||||||
|
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|
||||||
|
if (firstPollTask != null && !firstPollTask.IsCompleted) {
|
||||||
|
firstPollTask.RunSynchronously();
|
||||||
|
firstPollTask = null;
|
||||||
|
Logger.Log("poll cycle first done");
|
||||||
|
}
|
||||||
|
|
||||||
pollerFirstCycleCompleted = true;
|
pollerFirstCycleCompleted = true;
|
||||||
PollerCycleDurationMs = (int)sw.ElapsedMilliseconds;
|
PollerCycleDurationMs = (int)sw.ElapsedMilliseconds;
|
||||||
|
|
||||||
@@ -296,11 +307,6 @@ namespace MewtocolNet {
|
|||||||
collection.OnInterfaceLinked(this);
|
collection.OnInterfaceLinked(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Connected += (s,e) => {
|
|
||||||
if (collection != null)
|
|
||||||
collection.OnInterfaceLinkedAndOnline(this);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AddRegisters(regBuild.assembler.assembled.ToArray());
|
AddRegisters(regBuild.assembler.assembled.ToArray());
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
|
|
||||||
<IsPublishable>false</IsPublishable>
|
<IsPublishable>false</IsPublishable>
|
||||||
|
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
<PackageId>Mewtocol.NET</PackageId>
|
<PackageId>Mewtocol.NET</PackageId>
|
||||||
<Version>0.0.0</Version>
|
<Version>0.0.0</Version>
|
||||||
@@ -17,15 +16,19 @@
|
|||||||
<PackageTags>plc;panasonic;mewtocol;automation;</PackageTags>
|
<PackageTags>plc;panasonic;mewtocol;automation;</PackageTags>
|
||||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
<UserSecretsId>2ccdcc9b-94a3-4e76-8827-453ab889ea33</UserSecretsId>
|
<UserSecretsId>2ccdcc9b-94a3-4e76-8827-453ab889ea33</UserSecretsId>
|
||||||
|
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
||||||
<DocumentationFile>..\Builds\MewtocolNet\MewtocolNet.xml</DocumentationFile>
|
<DocumentationFile>..\Builds\MewtocolNet\MewtocolNet.xml</DocumentationFile>
|
||||||
<OutputPath>..\Builds\MewtocolNet</OutputPath>
|
<OutputPath>..\Builds\MewtocolNet</OutputPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
||||||
|
<DocumentationFile>..\Builds\MewtocolNet\Debug\MewtocolNet.xml</DocumentationFile>
|
||||||
|
<OutputPath>..\Builds\MewtocolNet\Debug</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||||
<_Parameter1>MewtocolTests</_Parameter1>
|
<_Parameter1>MewtocolTests</_Parameter1>
|
||||||
</AssemblyAttribute>
|
</AssemblyAttribute>
|
||||||
|
|||||||
@@ -15,35 +15,35 @@ namespace MewtocolNet {
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is in RUN mode, otherwise its PROG Mode
|
/// Is in RUN mode, otherwise its PROG Mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RunMode = 1,
|
RunMode = 1 << 0,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is in test mode, otherwise ok
|
/// Is in test mode, otherwise ok
|
||||||
/// </summary>
|
/// </summary>
|
||||||
TestMode = 2,
|
TestMode = 1 << 1,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is BRK/1 step executed
|
/// Is BRK/1 step executed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BreakPointPerOneStep = 4,
|
BreakPointPerOneStep = 1 << 2,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is BRK command enabled
|
/// Is BRK command enabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
BreakEnabled = 16,
|
BreakEnabled = 1 << 3,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is outputting to external device
|
/// Is outputting to external device
|
||||||
/// </summary>
|
/// </summary>
|
||||||
ExternalOutput = 32,
|
ExternalOutput = 1 << 4,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is 1 step exec enabled
|
/// Is 1 step exec enabled
|
||||||
/// </summary>
|
/// </summary>
|
||||||
OneStepExecEnabled = 64,
|
OneStepExecEnabled = 1 << 5,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is a message displayed?
|
/// Is a message displayed?
|
||||||
/// </summary>
|
/// </summary>
|
||||||
MessageInstructionDisplayed = 128,
|
MessageInstructionDisplayed = 1 << 6,
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Is in remote mode
|
/// Is in remote mode
|
||||||
/// </summary>
|
/// </summary>
|
||||||
RemoteMode = 255,
|
RemoteMode = 1 << 7,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using MewtocolNet.Registers;
|
using MewtocolNet.Registers;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MewtocolNet.RegisterAttributes {
|
namespace MewtocolNet.RegisterAttributes {
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ namespace MewtocolNet.RegisterAttributes {
|
|||||||
/// and the plc connection is established
|
/// and the plc connection is established
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plc">The parent interface</param>
|
/// <param name="plc">The parent interface</param>
|
||||||
public virtual void OnInterfaceLinkedAndOnline(MewtocolInterface plc) { }
|
public virtual Task OnInterfaceLinkedAndOnline(MewtocolInterface plc) => Task.CompletedTask;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace MewtocolNet.RegisterBuilding {
|
|||||||
private static ParseResult TryBuildBoolean(string plcAddrName) {
|
private static ParseResult TryBuildBoolean(string plcAddrName) {
|
||||||
|
|
||||||
//regex to find special register values
|
//regex to find special register values
|
||||||
var patternBool = new Regex(@"(?<prefix>X|Y|R)(?<area>[0-9]{0,3})(?<special>(?:[0-9]|[A-F]){1})?");
|
var patternBool = new Regex(@"(?<prefix>X|Y|R)(?<area>[0-9]{0,3})(?<special>(?:[0-9]|[A-F]){1})");
|
||||||
|
|
||||||
var match = patternBool.Match(plcAddrName);
|
var match = patternBool.Match(plcAddrName);
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,13 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
//bool constructor
|
//bool constructor
|
||||||
|
|
||||||
public StructStp<bool> Bool(string fpAddr, string name = null) {
|
internal StructStp<bool> Bool(string fpAddr, string name = null) {
|
||||||
|
|
||||||
var data = AddressTools.ParseAddress(fpAddr, name);
|
var data = AddressTools.ParseAddress(fpAddr, name);
|
||||||
|
|
||||||
|
if (!data.regType.IsBoolean())
|
||||||
|
throw new NotSupportedException($"The address '{fpAddr}' was no boolean FP address");
|
||||||
|
|
||||||
data.dotnetVarType = typeof(bool);
|
data.dotnetVarType = typeof(bool);
|
||||||
|
|
||||||
return new StructStp<bool>(data) {
|
return new StructStp<bool>(data) {
|
||||||
@@ -48,10 +51,13 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
//struct constructor
|
//struct constructor
|
||||||
|
|
||||||
public StructStp<T> Struct<T>(string fpAddr, string name = null) where T : struct {
|
internal StructStp<T> Struct<T>(string fpAddr, string name = null) where T : struct {
|
||||||
|
|
||||||
var data = AddressTools.ParseAddress(fpAddr, name);
|
var data = AddressTools.ParseAddress(fpAddr, name);
|
||||||
|
|
||||||
|
if (data.regType.IsBoolean())
|
||||||
|
throw new NotSupportedException($"The address '{fpAddr}' was no DT address");
|
||||||
|
|
||||||
data.dotnetVarType = typeof(T);
|
data.dotnetVarType = typeof(T);
|
||||||
|
|
||||||
return new StructStp<T>(data) {
|
return new StructStp<T>(data) {
|
||||||
@@ -62,10 +68,13 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
//string constructor
|
//string constructor
|
||||||
|
|
||||||
public StringStp<string> String(string fpAddr, int sizeHint, string name = null) {
|
internal StringStp<string> String(string fpAddr, int sizeHint, string name = null) {
|
||||||
|
|
||||||
var data = AddressTools.ParseAddress(fpAddr, name);
|
var data = AddressTools.ParseAddress(fpAddr, name);
|
||||||
|
|
||||||
|
if (data.regType.IsBoolean())
|
||||||
|
throw new NotSupportedException($"The address '{fpAddr}' was no string address");
|
||||||
|
|
||||||
data.dotnetVarType = typeof(string);
|
data.dotnetVarType = typeof(string);
|
||||||
data.byteSizeHint = (uint)sizeHint;
|
data.byteSizeHint = (uint)sizeHint;
|
||||||
|
|
||||||
@@ -82,6 +91,8 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
//structs can lead to arrays
|
//structs can lead to arrays
|
||||||
public class StructStp<T> : ArrayStp<T> where T : struct {
|
public class StructStp<T> : ArrayStp<T> where T : struct {
|
||||||
|
|
||||||
|
internal StructStp() {}
|
||||||
|
|
||||||
internal StructStp(StepData data) {
|
internal StructStp(StepData data) {
|
||||||
|
|
||||||
this.Data = data;
|
this.Data = data;
|
||||||
@@ -89,30 +100,13 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Build() => builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IRegister<T> reference) => reference = (IRegister<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
public StructStpOut<T> PollLevel(int level) {
|
|
||||||
|
|
||||||
Data.pollLevel = level;
|
|
||||||
return new StructStpOut<T>().Map(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class StructStpOut<T> : SBaseRB where T : struct {
|
|
||||||
|
|
||||||
public void Build() => builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IRegister<T> reference) => reference = (IRegister<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//strings can lead to arrays
|
//strings can lead to arrays
|
||||||
public class StringStp<T> : ArrayStp<T> where T : class {
|
public class StringStp<T> : ArrayStp<T> where T : class {
|
||||||
|
|
||||||
|
internal StringStp() { }
|
||||||
|
|
||||||
internal StringStp(StepData data) {
|
internal StringStp(StepData data) {
|
||||||
|
|
||||||
this.Data = data;
|
this.Data = data;
|
||||||
@@ -120,25 +114,6 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Build() => builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IStringRegister reference) => reference = (IStringRegister)builder.Assemble(this);
|
|
||||||
|
|
||||||
public StringOutStp PollLevel(int level) {
|
|
||||||
|
|
||||||
Data.pollLevel = level;
|
|
||||||
return new StringOutStp().Map(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class StringOutStp : SBaseRB {
|
|
||||||
|
|
||||||
public void Build() => builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IStringRegister reference) => reference = (IStringRegister)builder.Assemble(this);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//arrays
|
//arrays
|
||||||
@@ -199,66 +174,21 @@ namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
|||||||
|
|
||||||
//1D array
|
//1D array
|
||||||
|
|
||||||
public class TypedArr1D<T> : TypedArr1DOut<T> {
|
public class TypedArr1D<T> : TypedArr1DOut<T> { }
|
||||||
|
|
||||||
public TypedArr1DOut<T> PollLevel(int level) {
|
public class TypedArr1DOut<T> : SBaseRB { }
|
||||||
|
|
||||||
Data.pollLevel = level;
|
|
||||||
return new TypedArr1DOut<T>().Map(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypedArr1DOut<T> : SBaseRB {
|
|
||||||
|
|
||||||
public IArrayRegister<T> Build() => (IArrayRegister<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IArrayRegister<T> reference) => reference = (IArrayRegister<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//2D array
|
//2D array
|
||||||
|
|
||||||
public class TypedArr2D<T> : TypedArr2DOut<T> {
|
public class TypedArr2D<T> : TypedArr2DOut<T> { }
|
||||||
|
|
||||||
public TypedArr2DOut<T> PollLevel(int level) {
|
public class TypedArr2DOut<T> : SBaseRB { }
|
||||||
|
|
||||||
Data.pollLevel = level;
|
|
||||||
return new TypedArr2DOut<T>().Map(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypedArr2DOut<T> : SBaseRB {
|
|
||||||
|
|
||||||
public IArrayRegister2D<T> Build() => (IArrayRegister2D<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IArrayRegister2D<T> reference) => reference = (IArrayRegister2D<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
//3D array
|
//3D array
|
||||||
|
|
||||||
public class TypedArr3D<T> : SBaseRB {
|
public class TypedArr3D<T> : SBaseRB { }
|
||||||
|
|
||||||
public TypedArr3DOut<T> PollLevel(int level) {
|
public class TypedArr3DOut<T> : SBaseRB { }
|
||||||
|
|
||||||
Data.pollLevel = level;
|
|
||||||
return new TypedArr3DOut<T>().Map(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class TypedArr3DOut<T> : SBaseRB {
|
|
||||||
|
|
||||||
public IArrayRegister3D<T> Build() => (IArrayRegister3D<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
public void Build(out IArrayRegister3D<T> reference) => reference = (IArrayRegister3D<T>)builder.Assemble(this);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
130
MewtocolNet/RegisterBuilding/BuilderPatterns/RBuildAnon.cs
Normal file
130
MewtocolNet/RegisterBuilding/BuilderPatterns/RBuildAnon.cs
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
using MewtocolNet.Registers;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An anonymous register build interface
|
||||||
|
/// </summary>
|
||||||
|
public class RBuildAnon : RBuild {
|
||||||
|
|
||||||
|
internal RBuildAnon(MewtocolInterface plc) : base(plc) { }
|
||||||
|
|
||||||
|
public new MultStructStp<bool> Bool(string fpAddr) => new MultStructStp<bool>().Map(base.Bool(fpAddr));
|
||||||
|
|
||||||
|
public new MultStructStp<T> Struct<T>(string fpAddr) where T : struct => new MultStructStp<T>().Map(base.Struct<T>(fpAddr));
|
||||||
|
|
||||||
|
public new MultStringStp<string> String(string fpAddr, int sizeHint) => new MultStringStp<string>().Map(base.String(fpAddr, sizeHint));
|
||||||
|
|
||||||
|
public class MultStructStp<T> : MultArrayStp<T> where T : struct {
|
||||||
|
|
||||||
|
public async Task WriteAsync(T value) {
|
||||||
|
|
||||||
|
var reg = (IRegister<T>)builder.Assemble(this);
|
||||||
|
await reg.WriteAsync(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T> ReadAsync() {
|
||||||
|
|
||||||
|
var reg = (IRegister<T>)builder.Assemble(this);
|
||||||
|
return await reg.ReadAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultStringStp<T> : MultArrayStp<T> where T : class {
|
||||||
|
|
||||||
|
public async Task WriteAsync(string value) {
|
||||||
|
|
||||||
|
var reg = (IStringRegister)builder.Assemble(this);
|
||||||
|
await reg.WriteAsync(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<string> ReadAsync() {
|
||||||
|
|
||||||
|
var reg = (IStringRegister)builder.Assemble(this);
|
||||||
|
return await reg.ReadAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultArrayStp<T> : ArrayStp<T> {
|
||||||
|
|
||||||
|
public new MultTypedArr1D<T> AsArray(int i) => new MultTypedArr1D<T>().Map(base.AsArray(i));
|
||||||
|
|
||||||
|
public new MultTypedArr2D<T> AsArray(int i1, int i2) => new MultTypedArr2D<T>().Map(base.AsArray(i1, i2));
|
||||||
|
|
||||||
|
public new MultTypedArr3D<T> AsArray(int i1, int i2, int i3) => new MultTypedArr3D<T>().Map(base.AsArray(i1, i2, i3));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//1D array
|
||||||
|
|
||||||
|
public class MultTypedArr1D<T> : TypedArr1D<T> {
|
||||||
|
|
||||||
|
public async Task WriteAsync(T[] value) {
|
||||||
|
|
||||||
|
var reg = (IArrayRegister<T>)builder.Assemble(this);
|
||||||
|
await reg.WriteAsync(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T[]> ReadAsync() {
|
||||||
|
|
||||||
|
var reg = (IArrayRegister<T>)builder.Assemble(this);
|
||||||
|
return await reg.ReadAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//2D array
|
||||||
|
|
||||||
|
public class MultTypedArr2D<T> : TypedArr2D<T> {
|
||||||
|
|
||||||
|
public async Task WriteAsync(T[,] value) {
|
||||||
|
|
||||||
|
var reg = (IArrayRegister2D<T>)builder.Assemble(this);
|
||||||
|
await reg.WriteAsync(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T[,]> ReadAsync() {
|
||||||
|
|
||||||
|
var reg = (IArrayRegister2D<T>)builder.Assemble(this);
|
||||||
|
return await reg.ReadAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//3D array
|
||||||
|
|
||||||
|
public class MultTypedArr3D<T> : TypedArr3D<T> {
|
||||||
|
|
||||||
|
public async Task WriteAsync(T[,,] value) {
|
||||||
|
|
||||||
|
var reg = (IArrayRegister3D<T>)builder.Assemble(this);
|
||||||
|
await reg.WriteAsync(value);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<T[,,]> ReadAsync() {
|
||||||
|
|
||||||
|
var reg = (IArrayRegister3D<T>)builder.Assemble(this);
|
||||||
|
return await reg.ReadAsync();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
142
MewtocolNet/RegisterBuilding/BuilderPatterns/RBuildMulti.cs
Normal file
142
MewtocolNet/RegisterBuilding/BuilderPatterns/RBuildMulti.cs
Normal file
@@ -0,0 +1,142 @@
|
|||||||
|
using MewtocolNet.Registers;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace MewtocolNet.RegisterBuilding.BuilderPatterns {
|
||||||
|
|
||||||
|
public class RBuildMulti : RBuild {
|
||||||
|
|
||||||
|
internal RBuildMulti(MewtocolInterface plc) : base(plc) {}
|
||||||
|
|
||||||
|
//bool constructor
|
||||||
|
public new MultStructStp<bool> Bool(string fpAddr, string name = null) => new MultStructStp<bool>().Map(base.Bool(fpAddr, name));
|
||||||
|
|
||||||
|
//struct constructor
|
||||||
|
public new MultStructStp<T> Struct<T>(string fpAddr, string name = null) where T : struct => new MultStructStp<T>().Map(base.Struct<T>(fpAddr, name));
|
||||||
|
|
||||||
|
//string constructor
|
||||||
|
public new MultStringStp<string> String(string fpAddr, int sizeHint, string name = null) => new MultStringStp<string>().Map(base.String(fpAddr, sizeHint, name));
|
||||||
|
|
||||||
|
public class MultStructStp<T> : MultArrayStp<T> where T : struct {
|
||||||
|
|
||||||
|
public void Build() => builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IRegister<T> reference) => reference = (IRegister<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
public StructStpOut<T> PollLevel(int level) {
|
||||||
|
|
||||||
|
Data.pollLevel = level;
|
||||||
|
return new StructStpOut<T>().Map(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StructStpOut<T> : SBaseRB where T : struct {
|
||||||
|
|
||||||
|
public void Build() => builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IRegister<T> reference) => reference = (IRegister<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultStringStp<T> : MultArrayStp<T> where T : class {
|
||||||
|
|
||||||
|
public void Build() => builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IStringRegister reference) => reference = (IStringRegister)builder.Assemble(this);
|
||||||
|
|
||||||
|
public StringOutStp PollLevel(int level) {
|
||||||
|
|
||||||
|
Data.pollLevel = level;
|
||||||
|
return new StringOutStp().Map(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class StringOutStp : SBaseRB {
|
||||||
|
|
||||||
|
public void Build() => builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IStringRegister reference) => reference = (IStringRegister)builder.Assemble(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultArrayStp<T> : ArrayStp<T> {
|
||||||
|
|
||||||
|
public new MultTypedArr1D<T> AsArray(int i) => new MultTypedArr1D<T>().Map(base.AsArray(i));
|
||||||
|
|
||||||
|
public new MultTypedArr2D<T> AsArray(int i1, int i2) => new MultTypedArr2D<T>().Map(base.AsArray(i1, i2));
|
||||||
|
|
||||||
|
public new MultTypedArr3D<T> AsArray(int i1, int i2, int i3) => new MultTypedArr3D<T>().Map(base.AsArray(i1, i2, i3));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//1D array
|
||||||
|
|
||||||
|
public class MultTypedArr1D<T> : TypedArr1D<T> {
|
||||||
|
|
||||||
|
public MultTypedArr1DOut<T> PollLevel(int level) {
|
||||||
|
|
||||||
|
Data.pollLevel = level;
|
||||||
|
return new MultTypedArr1DOut<T>().Map(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultTypedArr1DOut<T> : TypedArr1DOut<T> {
|
||||||
|
|
||||||
|
public IArrayRegister<T> Build() => (IArrayRegister<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IArrayRegister<T> reference) => reference = (IArrayRegister<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//2D array
|
||||||
|
|
||||||
|
public class MultTypedArr2D<T> : TypedArr2D<T> {
|
||||||
|
|
||||||
|
public MultTypedArr2DOut<T> PollLevel(int level) {
|
||||||
|
|
||||||
|
Data.pollLevel = level;
|
||||||
|
return new MultTypedArr2DOut<T>().Map(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultTypedArr2DOut<T> : TypedArr2DOut<T> {
|
||||||
|
|
||||||
|
public IArrayRegister2D<T> Build() => (IArrayRegister2D<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IArrayRegister2D<T> reference) => reference = (IArrayRegister2D<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//3D array
|
||||||
|
|
||||||
|
public class MultTypedArr3D<T> : TypedArr3D<T> {
|
||||||
|
|
||||||
|
public MultTypedArr3DOut<T> PollLevel(int level) {
|
||||||
|
|
||||||
|
Data.pollLevel = level;
|
||||||
|
return new MultTypedArr3DOut<T>().Map(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MultTypedArr3DOut<T> : TypedArr3DOut<T> {
|
||||||
|
|
||||||
|
public IArrayRegister3D<T> Build() => (IArrayRegister3D<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
public void Build(out IArrayRegister3D<T> reference) => reference = (IArrayRegister3D<T>)builder.Assemble(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MewtocolNet.Events;
|
using MewtocolNet.Events;
|
||||||
|
using MewtocolNet.UnderlyingRegisters;
|
||||||
|
|
||||||
namespace MewtocolNet.Registers {
|
namespace MewtocolNet.Registers {
|
||||||
|
|
||||||
@@ -20,6 +21,11 @@ namespace MewtocolNet.Registers {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool IsAutoGenerated { get; }
|
bool IsAutoGenerated { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The readonly memory area of the register
|
||||||
|
/// </summary>
|
||||||
|
IMemoryArea MemoryArea { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Type of the underlying register
|
/// Type of the underlying register
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -66,6 +66,9 @@ namespace MewtocolNet.Registers {
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public RegisterPrefix RegisterType { get; internal set; }
|
public RegisterPrefix RegisterType { get; internal set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IMemoryArea MemoryArea => underlyingMemory;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public string Name => name;
|
public string Name => name;
|
||||||
|
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ namespace MewtocolNet.Registers {
|
|||||||
//if string correct the sizing of the byte hint was wrong
|
//if string correct the sizing of the byte hint was wrong
|
||||||
var reservedSize = BitConverter.ToInt16(bytes, 0);
|
var reservedSize = BitConverter.ToInt16(bytes, 0);
|
||||||
|
|
||||||
if (reservedStringLength != reservedSize && attachedInterface.PlcInfo.IsRunMode)
|
if (reservedStringLength != reservedSize && attachedInterface.PlcInfo.IsRunMode && !attachedInterface.isConnectingStage)
|
||||||
throw new NotSupportedException(
|
throw new NotSupportedException(
|
||||||
$"The STRING register at {GetMewName()} is not correctly sized, " +
|
$"The STRING register at {GetMewName()} is not correctly sized, " +
|
||||||
$"the size should be STRING[{reservedSize}] instead of STRING[{reservedStringLength}]"
|
$"the size should be STRING[{reservedSize}] instead of STRING[{reservedStringLength}]"
|
||||||
|
|||||||
@@ -127,6 +127,15 @@ namespace MewtocolNet.TypeConversion {
|
|||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
//default Datetime DDT conversion
|
||||||
|
new PlcTypeConversion<DateAndTime>(RegisterPrefix.DDT) {
|
||||||
|
HoldingRegisterType = typeof(StructRegister<DateAndTime>),
|
||||||
|
PlcVarType = PlcVarType.DATE_AND_TIME,
|
||||||
|
FromRaw = (reg, bytes) => DateAndTime.FromBytes(bytes),
|
||||||
|
ToRaw = (reg, value) => value.ToByteArray(),
|
||||||
|
},
|
||||||
|
|
||||||
//default string DT Range conversion Example bytes: (04 00 03 00 XX XX XX)
|
//default string DT Range conversion Example bytes: (04 00 03 00 XX XX XX)
|
||||||
//first 4 bytes are reserved size (2 bytes) and used size (2 bytes)
|
//first 4 bytes are reserved size (2 bytes) and used size (2 bytes)
|
||||||
//the remaining bytes are the ascii bytes for the string
|
//the remaining bytes are the ascii bytes for the string
|
||||||
|
|||||||
@@ -2,17 +2,21 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace MewtocolNet.UnderlyingRegisters {
|
namespace MewtocolNet.UnderlyingRegisters {
|
||||||
|
|
||||||
public class AreaBase {
|
internal class AreaBase : IMemoryArea {
|
||||||
|
|
||||||
private MewtocolInterface mewInterface;
|
private MewtocolInterface mewInterface;
|
||||||
|
private int pollLevel;
|
||||||
|
|
||||||
internal RegisterPrefix registerType;
|
internal RegisterPrefix registerType;
|
||||||
|
|
||||||
internal ulong addressStart;
|
internal ulong addressStart;
|
||||||
internal ulong addressEnd;
|
internal ulong addressEnd;
|
||||||
|
|
||||||
@@ -23,12 +27,25 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal List<LinkedRegisterGroup> managedRegisters = new List<LinkedRegisterGroup>();
|
internal List<LinkedRegisterGroup> managedRegisters = new List<LinkedRegisterGroup>();
|
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
|
||||||
public ulong AddressStart => addressStart;
|
public ulong AddressStart => addressStart;
|
||||||
public ulong AddressEnd => addressEnd;
|
public ulong AddressEnd => addressEnd;
|
||||||
|
|
||||||
internal AreaBase(MewtocolInterface mewIf) {
|
//interface
|
||||||
|
|
||||||
|
public string AddressRange => GetAddressRangeString();
|
||||||
|
|
||||||
|
public IReadOnlyList<Word> UnderlyingWords => GetUnderlyingWords();
|
||||||
|
|
||||||
|
public string UnderlyingWordsString => string.Join(" ", GetUnderlyingWords());
|
||||||
|
|
||||||
|
public int PollLevel => pollLevel;
|
||||||
|
|
||||||
|
internal AreaBase(MewtocolInterface mewIf, int pollLvl) {
|
||||||
|
|
||||||
mewInterface = mewIf;
|
mewInterface = mewIf;
|
||||||
|
pollLevel = pollLvl;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,6 +66,9 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
addressStart = addFrom;
|
addressStart = addFrom;
|
||||||
addressEnd = addTo;
|
addressEnd = addTo;
|
||||||
|
|
||||||
|
OnPropChange(nameof(AddressRange));
|
||||||
|
OnPropChange(nameof(UnderlyingWords));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateAreaRegisterValues() {
|
public void UpdateAreaRegisterValues() {
|
||||||
@@ -61,6 +81,9 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
var bytes = this.GetUnderlyingBytes(regStart, addLen);
|
var bytes = this.GetUnderlyingBytes(regStart, addLen);
|
||||||
register.SetValueFromBytes(bytes);
|
register.SetValueFromBytes(bytes);
|
||||||
|
|
||||||
|
OnPropChange(nameof(UnderlyingWords));
|
||||||
|
OnPropChange(nameof(UnderlyingWordsString));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -112,6 +135,8 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
|
|
||||||
var bitArr = new BitArray(underlyingBefore);
|
var bitArr = new BitArray(underlyingBefore);
|
||||||
|
|
||||||
|
bitArr[bitIndex] = value;
|
||||||
|
|
||||||
bitArr.CopyTo(underlyingBefore, 0);
|
bitArr.CopyTo(underlyingBefore, 0);
|
||||||
|
|
||||||
SetUnderlyingBytes(underlyingBefore, reg.MemoryAddress);
|
SetUnderlyingBytes(underlyingBefore, reg.MemoryAddress);
|
||||||
@@ -131,22 +156,45 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
private List<Word> GetUnderlyingWords () {
|
||||||
|
|
||||||
|
var bytes = GetUnderlyingBytes((uint)AddressStart, (int)(addressEnd - AddressStart) + 1);
|
||||||
|
var words = new List<Word>();
|
||||||
|
|
||||||
|
for (int i = 0; i < bytes.Length / 2; i += 2) {
|
||||||
|
|
||||||
|
words.Add(new Word(new byte[] { bytes[i], bytes[i + 1] }));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return words;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetAddressRangeString() {
|
||||||
|
|
||||||
switch (registerType) {
|
switch (registerType) {
|
||||||
case RegisterPrefix.X:
|
case RegisterPrefix.X:
|
||||||
case RegisterPrefix.Y:
|
case RegisterPrefix.Y:
|
||||||
case RegisterPrefix.R:
|
case RegisterPrefix.R:
|
||||||
return $"W{registerType}{AddressStart}-{AddressEnd} ({managedRegisters.Count} Registers)";
|
return $"W{registerType}{AddressStart}-{AddressEnd}";
|
||||||
case RegisterPrefix.DT:
|
case RegisterPrefix.DT:
|
||||||
case RegisterPrefix.DDT:
|
case RegisterPrefix.DDT:
|
||||||
return $"DT{AddressStart}-{AddressEnd} ({managedRegisters.Count} Registers)";
|
return $"DT{AddressStart}-{AddressEnd}";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString() => $"{GetAddressRangeString()} ({managedRegisters.Count} Registers)";
|
||||||
|
|
||||||
|
private protected void OnPropChange([CallerMemberName] string propertyName = null) {
|
||||||
|
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
using MewtocolNet.Registers;
|
using MewtocolNet.Registers;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
namespace MewtocolNet.UnderlyingRegisters {
|
namespace MewtocolNet.UnderlyingRegisters {
|
||||||
|
|
||||||
internal interface IMemoryArea {
|
public interface IMemoryArea : INotifyPropertyChanged {
|
||||||
|
|
||||||
string GetName();
|
string AddressRange { get; }
|
||||||
|
|
||||||
byte[] GetUnderlyingBytes(Register reg);
|
IReadOnlyList<Word> UnderlyingWords { get; }
|
||||||
|
|
||||||
void SetUnderlyingBytes(Register reg, byte[] bytes);
|
string UnderlyingWordsString { get; }
|
||||||
|
|
||||||
void UpdateAreaRegisterValues();
|
int PollLevel { get; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
//create a new area
|
//create a new area
|
||||||
if (targetArea == null) {
|
if (targetArea == null) {
|
||||||
|
|
||||||
targetArea = new AreaBase(mewInterface) {
|
targetArea = new AreaBase(mewInterface, pollLevelFound.level) {
|
||||||
addressStart = regInsAddStart,
|
addressStart = regInsAddStart,
|
||||||
addressEnd = regInsAddEnd,
|
addressEnd = regInsAddEnd,
|
||||||
registerType = insertReg.RegisterType,
|
registerType = insertReg.RegisterType,
|
||||||
@@ -455,6 +455,20 @@ namespace MewtocolNet.UnderlyingRegisters {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal IReadOnlyList<IMemoryArea> GetAllMemoryAreas() {
|
||||||
|
|
||||||
|
List<IMemoryArea> areas = new List<IMemoryArea>();
|
||||||
|
|
||||||
|
foreach (var lvl in pollLevels) {
|
||||||
|
|
||||||
|
areas.AddRange(lvl.GetAllAreas());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return areas;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
internal bool HasSingleCyclePollableRegisters() {
|
internal bool HasSingleCyclePollableRegisters() {
|
||||||
|
|
||||||
bool hasCyclicPollableLevels = pollLevels.Any(x => x.level != MewtocolNet.PollLevel.FirstIteration);
|
bool hasCyclicPollableLevels = pollLevels.Any(x => x.level != MewtocolNet.PollLevel.FirstIteration);
|
||||||
|
|||||||
9
nuget.config
Normal file
9
nuget.config
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<add key="LocalMewtocolNetNuget" value="Builds/MewtocolNet/Debug" />
|
||||||
|
</packageSources>
|
||||||
|
<activePackageSource>
|
||||||
|
<add key="All" value="(Aggregate source)" />
|
||||||
|
</activePackageSource>
|
||||||
|
</configuration>
|
||||||
Reference in New Issue
Block a user