mirror of
https://github.com/JasonYANG170/logicanalyzer.git
synced 2024-11-23 12:06:27 +00:00
Added WiFi battery indicator
Added persistance of last IP used Added link to the Wiki Corrected SPI analyzer Added channel names on analysis settings
This commit is contained in:
parent
accc3214c9
commit
6ab103e120
|
@ -2,7 +2,7 @@
|
|||
"profiles": {
|
||||
"CLCapture": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "capture COM9 1000000 1:SDA,2:SDB,3:SDC_A,4:nana,5,6,7,8 20 20000 TriggerType:Edge,Channel:1,Value:0 test.csv"
|
||||
"commandLineArgs": "capture COM9 1000000 1:SDA,2:SDB,3:SDC_A,4:nana,5,6,7,8 512 1000 5 TriggerType:Edge,Channel:1,Value:1 test.csv"
|
||||
}
|
||||
}
|
||||
}
|
BIN
Software/LogicAnalyzer/LogicAnalyzer/Assets/battery.png
Normal file
BIN
Software/LogicAnalyzer/LogicAnalyzer/Assets/battery.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 678 B |
BIN
Software/LogicAnalyzer/LogicAnalyzer/Assets/plug.png
Normal file
BIN
Software/LogicAnalyzer/LogicAnalyzer/Assets/plug.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 724 B |
|
@ -0,0 +1,50 @@
|
|||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Environment;
|
||||
|
||||
namespace LogicAnalyzer.Classes
|
||||
{
|
||||
public static class AppSettingsManager
|
||||
{
|
||||
static JsonSerializerSettings jSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All, Formatting = Formatting.Indented };
|
||||
|
||||
public static T? GetSettings<T>(string FileName) where T : class
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = GetFilePath(FileName);
|
||||
|
||||
if(!File.Exists(path))
|
||||
return null;
|
||||
|
||||
string content = File.ReadAllText(path);
|
||||
var settings = JsonConvert.DeserializeObject<T>(content, jSettings);
|
||||
return settings;
|
||||
}
|
||||
catch { return null; }
|
||||
}
|
||||
public static bool PersistSettings(string FileName, object Settings)
|
||||
{
|
||||
try
|
||||
{
|
||||
string path = GetFilePath(FileName);
|
||||
var data = JsonConvert.SerializeObject(Settings, jSettings);
|
||||
File.WriteAllText(path, data);
|
||||
return true;
|
||||
}
|
||||
catch { return false; }
|
||||
}
|
||||
|
||||
private static string GetFilePath(string FileName)
|
||||
{
|
||||
string appData = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData, SpecialFolderOption.DoNotVerify), "LogicAnalyzer");
|
||||
Directory.CreateDirectory(appData);
|
||||
return Path.Combine(appData, FileName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
<Window xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="450"
|
||||
MaxWidth="640" MaxHeight="450"
|
||||
MinWidth="640" MinHeight="450"
|
||||
Icon="/Assets/Ico40.ico"
|
||||
x:Class="LogicAnalyzer.Dialogs.AboutDialog"
|
||||
Title="About LogicAnalyzer" ShowInTaskbar="False" CanResize="False"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
Topmost="True">
|
||||
<Grid ColumnDefinitions="Auto,180">
|
||||
<Image Source="/Assets/Logo40.png" Margin="20" Height="420" Width="420"></Image>
|
||||
<StackPanel Spacing="10" Grid.Column="1" VerticalAlignment="Bottom" HorizontalAlignment="Center" Margin="20">
|
||||
<TextBlock TextWrapping="Wrap">©2023 Agustín Giménez Bernad</TextBlock>
|
||||
<TextBlock TextWrapping="Wrap" Name="txtVersion">Version 5.0.0.0</TextBlock>
|
||||
<Button Name="btnLicense" Margin="10,0,10,0">License</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,66 @@
|
|||
using Avalonia.Controls;
|
||||
using LogicAnalyzer.Extensions;
|
||||
using Microsoft.Extensions.PlatformAbstractions;
|
||||
using System.Diagnostics;
|
||||
using System.IO.Packaging;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LogicAnalyzer.Dialogs
|
||||
{
|
||||
public partial class AboutDialog : Window
|
||||
{
|
||||
public AboutDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
txtVersion.Text = $"Version {GetAppVersion()}";
|
||||
btnLicense.Click += BtnLicense_Click;
|
||||
}
|
||||
|
||||
private async void BtnLicense_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenUrl("https://github.com/gusmanb/logicanalyzer/blob/master/LICENSE");
|
||||
}
|
||||
catch
|
||||
{
|
||||
await this.ShowError("Cannot open page.", "Cannot start the default browser. You can access the online documentation in https://github.com/gusmanb/logicanalyzer/blob/master/LICENSE");
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(url);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// hack because of this: https://github.com/dotnet/corefx/issues/10361
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
url = url.Replace("&", "^&");
|
||||
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
Process.Start("xdg-open", url);
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
Process.Start("open", url);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static string GetAppVersion()
|
||||
{
|
||||
ApplicationEnvironment app = PlatformServices.Default.Application;
|
||||
return app.ApplicationVersion;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -142,58 +142,11 @@ namespace LogicAnalyzer.Dialogs
|
|||
|
||||
private void LoadSettings(AnalyzerDriverType DriverType)
|
||||
{
|
||||
settingsFile = WindowExtensions.GetFilePath($"cpSettings{DriverType}.json");
|
||||
settingsFile = $"cpSettings{DriverType}.json";
|
||||
CaptureSettings? settings = AppSettingsManager.GetSettings<CaptureSettings>(settingsFile);
|
||||
|
||||
if (File.Exists(settingsFile))
|
||||
if (settings != null)
|
||||
{
|
||||
string data = File.ReadAllText(settingsFile);
|
||||
|
||||
CaptureSettings? settings = null;
|
||||
|
||||
try
|
||||
{
|
||||
settings = JsonConvert.DeserializeObject<CaptureSettings>(data);
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (settings == null)
|
||||
{
|
||||
try
|
||||
{
|
||||
var oldset = JsonConvert.DeserializeObject<OldCaptureSettings>(data);
|
||||
|
||||
if (oldset != null)
|
||||
{
|
||||
CaptureChannel[] channels = new CaptureChannel[oldset.CaptureChannels.Length];
|
||||
for (int buc = 0; buc < channels.Length; buc++)
|
||||
channels[buc] = new CaptureChannel
|
||||
{
|
||||
ChannelName = (oldset.ChannelTexts?.Length ?? 0) > buc ? oldset.ChannelTexts[buc] : "",
|
||||
ChannelNumber = (int)oldset.CaptureChannels[buc]
|
||||
};
|
||||
|
||||
settings = new CaptureSettings
|
||||
{
|
||||
CaptureChannels = channels,
|
||||
Frequency = oldset.Frequency,
|
||||
PostTriggerSamples = oldset.PostTriggerSamples,
|
||||
PreTriggerSamples = oldset.PreTriggerSamples,
|
||||
LoopCount = 0,
|
||||
TriggerBitCount = oldset.TriggerBitCount,
|
||||
TriggerChannel = oldset.TriggerChannel,
|
||||
TriggerInverted = oldset.TriggerInverted,
|
||||
TriggerPattern = oldset.TriggerPattern,
|
||||
TriggerType = oldset.TriggerType
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (settings == null)
|
||||
return;
|
||||
}
|
||||
|
||||
nudFrequency.Value = settings.Frequency;
|
||||
nudPreSamples.Value = settings.PreTriggerSamples;
|
||||
nudPostSamples.Value = settings.PostTriggerSamples;
|
||||
|
@ -218,7 +171,7 @@ namespace LogicAnalyzer.Dialogs
|
|||
triggerChannels[settings.TriggerChannel].IsChecked = true;
|
||||
ckNegativeTrigger.IsChecked = settings.TriggerInverted;
|
||||
ckBurst.IsChecked = settings.LoopCount > 0;
|
||||
nudBurstCount.Value = settings.LoopCount > 0 ? settings.LoopCount : 1;
|
||||
nudBurstCount.Value = settings.LoopCount > 0 ? settings.LoopCount + 1 : 2;
|
||||
|
||||
rbTriggerTypePattern.IsChecked = false;
|
||||
rbTriggerTypeEdge.IsChecked = true;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Avalonia.Controls;
|
||||
using LogicAnalyzer.Classes;
|
||||
using LogicAnalyzer.Extensions;
|
||||
using MessageBox.Avalonia;
|
||||
using System;
|
||||
|
@ -18,6 +19,14 @@ namespace LogicAnalyzer.Dialogs
|
|||
InitializeComponent();
|
||||
btnAccept.Click += BtnAccept_Click;
|
||||
btnCancel.Click += BtnCancel_Click;
|
||||
|
||||
var settings = AppSettingsManager.GetSettings<NetworkConnectionSettings>("NetConnection.json");
|
||||
|
||||
if (settings != null)
|
||||
{
|
||||
txtAddress.Text = settings.Address;
|
||||
nudPort.Value = settings.Port;
|
||||
}
|
||||
}
|
||||
protected override void OnOpened(EventArgs e)
|
||||
{
|
||||
|
@ -36,10 +45,24 @@ namespace LogicAnalyzer.Dialogs
|
|||
await this.ShowError("Invalid address", "The specified address is not in the correct format.");
|
||||
return;
|
||||
}
|
||||
NetworkConnectionSettings settings = new NetworkConnectionSettings
|
||||
{
|
||||
Address = txtAddress.Text,
|
||||
Port = (ushort)nudPort.Value
|
||||
};
|
||||
|
||||
AppSettingsManager.PersistSettings("NetConnection.json", settings);
|
||||
|
||||
this.Address = txtAddress.Text;
|
||||
this.Port = (ushort)nudPort.Value;
|
||||
this.Close(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class NetworkConnectionSettings
|
||||
{
|
||||
public string? Address { get; set; }
|
||||
public ushort Port { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,8 +19,8 @@ namespace LogicAnalyzer.Dialogs
|
|||
ProtocolAnalyzerBase analyzer;
|
||||
public ProtocolAnalyzerBase Analyzer { get { return analyzer; } set { analyzer = value; LoadControls(); } }
|
||||
|
||||
int[] channels;
|
||||
public int[] Channels { get { return channels; } set { channels = value; LoadControls(); } }
|
||||
Channel[] channels;
|
||||
public Channel[] Channels { get { return channels; } set { channels = value; LoadControls(); } }
|
||||
|
||||
|
||||
public ProtocolAnalyzerSettingsDialog()
|
||||
|
@ -54,7 +54,7 @@ namespace LogicAnalyzer.Dialogs
|
|||
|
||||
channelsSource.Add("< None >");
|
||||
|
||||
channelsSource.AddRange(channels.Select(c => $"Channel {c + 1}"));
|
||||
channelsSource.AddRange(channels.Select(c => c.ChannelName));
|
||||
|
||||
for (int buc = 0; buc < signals.Length; buc++)
|
||||
{
|
||||
|
@ -219,7 +219,6 @@ namespace LogicAnalyzer.Dialogs
|
|||
}
|
||||
|
||||
return settingsValues.ToArray();
|
||||
|
||||
}
|
||||
|
||||
ProtocolAnalyzerSelectedChannel[]? ComposeChannels()
|
||||
|
@ -238,6 +237,9 @@ namespace LogicAnalyzer.Dialogs
|
|||
if (list == null)
|
||||
return null;
|
||||
|
||||
if (list.SelectedIndex == -1)
|
||||
continue;
|
||||
|
||||
selectedChannels.Add(new ProtocolAnalyzerSelectedChannel
|
||||
{
|
||||
ChannelIndex = list.SelectedIndex - 1,
|
||||
|
@ -259,5 +261,11 @@ namespace LogicAnalyzer.Dialogs
|
|||
SelectedChannels = ComposeChannels();
|
||||
this.Close(true);
|
||||
}
|
||||
|
||||
public class Channel
|
||||
{
|
||||
public required int ChannelIndex { get; set; }
|
||||
public required string ChannelName { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,34 +12,17 @@ using System.IO;
|
|||
using Newtonsoft.Json;
|
||||
using System.Text.Json;
|
||||
using static System.Environment;
|
||||
using LogicAnalyzer.Classes;
|
||||
|
||||
namespace LogicAnalyzer.Extensions
|
||||
{
|
||||
public static class WindowExtensions
|
||||
{
|
||||
|
||||
static string BasePath { get { return Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? ""; } }
|
||||
|
||||
static JsonSerializerSettings jSettings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto, Formatting = Formatting.Indented };
|
||||
|
||||
public static string GetFilePath(string FileName)
|
||||
{
|
||||
string appData = Path.Combine(Environment.GetFolderPath(SpecialFolder.ApplicationData, SpecialFolderOption.DoNotVerify), "LogicAnalyzer");
|
||||
Directory.CreateDirectory(appData);
|
||||
return Path.Combine(appData, FileName);
|
||||
}
|
||||
|
||||
static AppConfig config;
|
||||
static WindowExtensions()
|
||||
{
|
||||
|
||||
string path = GetFilePath("AppConfig.json");
|
||||
|
||||
if (File.Exists(path))
|
||||
config = JsonConvert.DeserializeObject<AppConfig>(File.ReadAllText(path), jSettings);
|
||||
|
||||
if(config == null)
|
||||
config = new AppConfig();
|
||||
var cfg = AppSettingsManager.GetSettings<AppConfig>("AppConfig.json");
|
||||
config = cfg ?? new AppConfig();
|
||||
}
|
||||
public static void FixStartupPosition(this Window windowToFix)
|
||||
{
|
||||
|
@ -122,7 +105,7 @@ namespace LogicAnalyzer.Extensions
|
|||
|
||||
config.WindowSettings[Window.GetType().FullName] = settings;
|
||||
|
||||
PersistSettings();
|
||||
AppSettingsManager.PersistSettings("AppConfig.json", config);
|
||||
}
|
||||
public static bool RestoreSettings(this Window Window, IEnumerable<string> Properties)
|
||||
{
|
||||
|
@ -144,12 +127,6 @@ namespace LogicAnalyzer.Extensions
|
|||
|
||||
return true;
|
||||
}
|
||||
private static void PersistSettings()
|
||||
{
|
||||
string path = GetFilePath("AppConfig.json");
|
||||
|
||||
File.WriteAllText(path, JsonConvert.SerializeObject(config, Formatting.Indented, jSettings));
|
||||
}
|
||||
private static object GetPropertyValue(object Source, string PropertyName)
|
||||
{
|
||||
object obj = Source;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
<PackageReference Include="AvaloniaColorPicker" Version="1.3.3" />
|
||||
<PackageReference Include="AvaloniaEdit.TextMate" Version="0.10.12.2" />
|
||||
<PackageReference Include="MessageBox.Avalonia" Version="2.0.2" />
|
||||
<PackageReference Include="Microsoft.Extensions.PlatformAbstractions" Version="1.1.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3-beta1" />
|
||||
<PackageReference Include="XamlNameReferenceGenerator" Version="1.3.4" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Linux.pubxml</_LastSelectedProfileId>
|
||||
<_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Windows.pubxml</_LastSelectedProfileId>
|
||||
<ActiveDebugProfile>LogicAnalyzer</ActiveDebugProfile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
|
||||
</PropertyGroup>
|
||||
</Project>
|
|
@ -24,6 +24,11 @@
|
|||
<MenuItem Header="Network settings" IsEnabled="False" Name="mnuSettings">
|
||||
<MenuItem Header="Update network settings" Name="mnuNetSettings"></MenuItem>
|
||||
</MenuItem>
|
||||
<MenuItem Header="Help">
|
||||
<MenuItem Header="Online documentation" Name="mnuDocs" />
|
||||
<Separator/>
|
||||
<MenuItem Header="About LogicAnalyzer" Name="mnuAbout" />
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
<Grid DockPanel.Dock="Top" Height="48" ColumnDefinitions="*,*" Background="#80303030">
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Stretch" Grid.Column="0" Margin="10,0,0,0">
|
||||
|
@ -57,7 +62,7 @@
|
|||
<controls:SampleViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="sampleViewer" Grid.Column="1"></controls:SampleViewer>
|
||||
</Grid>
|
||||
</ScrollViewer>
|
||||
<Panel Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="#ff303030">
|
||||
<Panel Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="#ff202020">
|
||||
<Grid DockPanel.Dock="Top" RowDefinitions="*,*,2*,*,2*,*" ColumnDefinitions="*,4*,*" HorizontalAlignment="Stretch" VerticalAlignment="Top" Margin="5" Background="#80383838">
|
||||
<TextBlock Grid.ColumnSpan="2" Margin="10">
|
||||
Adjustments
|
||||
|
@ -79,9 +84,7 @@
|
|||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<Panel VerticalAlignment="Stretch" Margin="0,180,0,180" Background="Black">
|
||||
<Image Source="/Assets/Logo40.png" VerticalAlignment="Center"></Image>
|
||||
</Panel>
|
||||
<StackPanel DockPanel.Dock="Bottom" VerticalAlignment="Bottom" Margin="5" Background="#80383838">
|
||||
<TextBlock Margin="5,2,5,2">
|
||||
Information
|
||||
|
@ -128,6 +131,15 @@
|
|||
</TextBlock>
|
||||
<TextBlock Margin="5,2,5,2" HorizontalAlignment="Right" Name="lblValue"></TextBlock>
|
||||
</Panel>
|
||||
<Panel Name="pnlPower" IsVisible="False">
|
||||
<TextBlock Margin="5,2,5,2" HorizontalAlignment="Left">
|
||||
- Power status:
|
||||
</TextBlock>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
|
||||
<Image Margin="5,2,5,2" Name="imgPowerSource" Width="16" Height="16" HorizontalAlignment="Right" Source="/Assets/plug.png"></Image>
|
||||
<TextBlock Margin="5,2,5,2" HorizontalAlignment="Right" Name="lblVoltage">3.38v</TextBlock>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
|
|
|
@ -1,7 +1,11 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media.Imaging;
|
||||
using Avalonia.Platform;
|
||||
using Avalonia.Shared.PlatformSupport;
|
||||
using Avalonia.Threading;
|
||||
using AvaloniaEdit.Utils;
|
||||
using LogicAnalyzer.Classes;
|
||||
|
@ -16,11 +20,14 @@ using SharedDriver;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Net.Mime.MediaTypeNames;
|
||||
|
||||
|
@ -28,7 +35,7 @@ namespace LogicAnalyzer
|
|||
{
|
||||
public partial class MainWindow : PersistableWindowBase
|
||||
{
|
||||
IAnalizerDriver driver;
|
||||
IAnalizerDriver? driver;
|
||||
CaptureSettings settings;
|
||||
|
||||
ProtocolAnalyzerLoader pLoader;
|
||||
|
@ -41,7 +48,7 @@ namespace LogicAnalyzer
|
|||
AnalysisSettings? analysisSettings;
|
||||
|
||||
bool preserveSamples = false;
|
||||
|
||||
Timer tmrPower;
|
||||
public MainWindow()
|
||||
{
|
||||
Instance = this;
|
||||
|
@ -73,11 +80,67 @@ namespace LogicAnalyzer
|
|||
mnuExit.Click += MnuExit_Click;
|
||||
mnuExport.Click += MnuExport_Click;
|
||||
mnuNetSettings.Click += MnuNetSettings_Click;
|
||||
|
||||
mnuDocs.Click += MnuDocs_Click;
|
||||
mnuAbout.Click += MnuAbout_Click;
|
||||
AddHandler(InputElement.KeyDownEvent, MainWindow_KeyDown, handledEventsToo: true);
|
||||
|
||||
LoadAnalyzers();
|
||||
RefreshPorts();
|
||||
|
||||
tmrPower = new Timer((o) =>
|
||||
{
|
||||
Dispatcher.UIThread.InvokeAsync(() =>
|
||||
{
|
||||
GetPowerStatus();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async void MnuAbout_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
var aboutDialog = new AboutDialog();
|
||||
await aboutDialog.ShowDialog(this);
|
||||
}
|
||||
|
||||
private async void MnuDocs_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
OpenUrl("https://github.com/gusmanb/logicanalyzer/wiki");
|
||||
}
|
||||
catch
|
||||
{
|
||||
await this.ShowError("Cannot open page.", "Cannot start the default browser. You can access the online documentation in https://github.com/gusmanb/logicanalyzer/wiki");
|
||||
}
|
||||
}
|
||||
|
||||
private void OpenUrl(string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
Process.Start(url);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// hack because of this: https://github.com/dotnet/corefx/issues/10361
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
url = url.Replace("&", "^&");
|
||||
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
Process.Start("xdg-open", url);
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
|
||||
{
|
||||
Process.Start("open", url);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void MainWindow_KeyDown(object? sender, Avalonia.Input.KeyEventArgs e)
|
||||
|
@ -713,7 +776,7 @@ namespace LogicAnalyzer
|
|||
mnuExport.IsEnabled = true;
|
||||
mnuSettings.IsEnabled = driver.DriverType == AnalyzerDriverType.Serial && (driver.DeviceVersion?.Contains("WIFI") ?? false);
|
||||
LoadInfo();
|
||||
|
||||
GetPowerStatus();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -725,7 +788,19 @@ namespace LogicAnalyzer
|
|||
|
||||
void LoadAnalyzers()
|
||||
{
|
||||
pLoader = new ProtocolAnalyzerLoader(Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "analyzers"));
|
||||
|
||||
string path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "analyzers");
|
||||
|
||||
if(!Directory.Exists(path))
|
||||
path = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location), "Analyzers");
|
||||
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
mnuProtocols.Items = new MenuItem[] { new MenuItem { Header = "<- None ->" } };
|
||||
return;
|
||||
}
|
||||
|
||||
pLoader = new ProtocolAnalyzerLoader(path);
|
||||
|
||||
var protocols = pLoader.ProtocolNames;
|
||||
mnuProtocols.Items = null;
|
||||
|
@ -799,7 +874,19 @@ namespace LogicAnalyzer
|
|||
var dlg = new ProtocolAnalyzerSettingsDialog();
|
||||
{
|
||||
dlg.Analyzer = analyzer;
|
||||
dlg.Channels = channelViewer.Channels.Select(c => c.ChannelNumber).ToArray();
|
||||
dlg.Channels = channelViewer.Channels.Select(c =>
|
||||
{
|
||||
var ch = new ProtocolAnalyzerSettingsDialog.Channel
|
||||
{
|
||||
ChannelIndex = c.ChannelNumber,
|
||||
ChannelName = string.IsNullOrWhiteSpace(c.ChannelName) ?
|
||||
$"Channel {c.ChannelNumber + 1}" :
|
||||
c.ChannelName
|
||||
};
|
||||
|
||||
return ch;
|
||||
|
||||
}).ToArray();
|
||||
|
||||
if (await dlg.ShowDialog<bool>(this) != true)
|
||||
return;
|
||||
|
@ -892,6 +979,7 @@ namespace LogicAnalyzer
|
|||
btnCapture.IsEnabled = true;
|
||||
btnRepeat.IsEnabled = true;
|
||||
mnuSettings.IsEnabled = driver.DriverType == AnalyzerDriverType.Serial && (driver.DeviceVersion?.Contains("WIFI") ?? false);
|
||||
tmrPower.Change(30000, Timeout.Infinite);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -905,9 +993,48 @@ namespace LogicAnalyzer
|
|||
btnCapture.IsEnabled = false;
|
||||
btnRepeat.IsEnabled = false;
|
||||
mnuSettings.IsEnabled = false;
|
||||
}
|
||||
tmrPower.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
}
|
||||
|
||||
GetPowerStatus();
|
||||
}
|
||||
|
||||
void GetPowerStatus()
|
||||
{
|
||||
if (driver == null || !driver.IsNetwork)
|
||||
{
|
||||
pnlPower.IsVisible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(driver.IsCapturing)
|
||||
return;
|
||||
|
||||
var powerStatus = driver.GetVoltageStatus();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(powerStatus) || powerStatus == "UNSUPPORTED")
|
||||
{
|
||||
pnlPower.IsVisible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
string[] parts = powerStatus.Split("_");
|
||||
|
||||
if(parts.Length == 2 )
|
||||
{
|
||||
lblVoltage.Text = parts[0];
|
||||
|
||||
var assets = AvaloniaLocator.Current.GetService<IAssetLoader>();
|
||||
using var str = assets.Open(new Uri(parts[1] == "1" ? "avares://LogicAnalyzer/Assets/plug.png" : "avares://LogicAnalyzer/Assets/battery.png"));
|
||||
Bitmap bmp = new Bitmap(str);
|
||||
var oldSrc = imgPowerSource.Source;
|
||||
imgPowerSource.Source = bmp;
|
||||
pnlPower.IsVisible = true;
|
||||
if (oldSrc is IDisposable)
|
||||
((IDisposable)oldSrc).Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
private void btnRefresh_Click(object? sender, RoutedEventArgs e)
|
||||
{
|
||||
RefreshPorts();
|
||||
|
@ -934,14 +1061,27 @@ namespace LogicAnalyzer
|
|||
{
|
||||
var dialog = new CaptureDialog();
|
||||
dialog.Initialize(driver);
|
||||
|
||||
if (!await dialog.ShowDialog<bool>(this))
|
||||
return;
|
||||
|
||||
settings = dialog.SelectedSettings;
|
||||
preserveSamples = false;
|
||||
|
||||
tmrPower.Change(Timeout.Infinite, Timeout.Infinite);
|
||||
|
||||
try
|
||||
{
|
||||
BeginCapture();
|
||||
|
||||
var settingsFile = $"cpSettings{driver.DriverType}.json";
|
||||
AppSettingsManager.PersistSettings(settingsFile, settings);
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
tmrPower.Change(30000, Timeout.Infinite);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void btnAbort_Click(object? sender, RoutedEventArgs e)
|
||||
|
|
|
@ -326,9 +326,9 @@ namespace SPIProtocolAnalyzer
|
|||
if (csChannel.Samples[buc] == 0)
|
||||
{
|
||||
if (underConstruction == null)
|
||||
underConstruction = new ActiveRange { FirstSample = buc };
|
||||
underConstruction = new ActiveRange { FirstSample = buc, LastSample = buc };
|
||||
else
|
||||
continue;
|
||||
underConstruction.LastSample = buc;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -342,6 +342,12 @@ namespace SPIProtocolAnalyzer
|
|||
|
||||
}
|
||||
|
||||
if (underConstruction != null)
|
||||
{
|
||||
ranges.Add(underConstruction);
|
||||
underConstruction = null;
|
||||
}
|
||||
|
||||
return ranges;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,9 @@ namespace SharedDriver
|
|||
{
|
||||
int deviceCount;
|
||||
|
||||
public bool IsConnected => false;
|
||||
public bool IsCapturing => false;
|
||||
public bool IsNetwork => false;
|
||||
public EmulatedAnalizerDriver(int DeviceCount)
|
||||
{
|
||||
deviceCount = DeviceCount;
|
||||
|
@ -72,6 +75,11 @@ namespace SharedDriver
|
|||
throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public string? GetVoltageStatus()
|
||||
{
|
||||
return "UNSUPPORTED";
|
||||
}
|
||||
|
||||
public bool StopCapture()
|
||||
{
|
||||
return true;
|
||||
|
|
|
@ -9,6 +9,8 @@ namespace SharedDriver
|
|||
public interface IAnalizerDriver : IDisposable
|
||||
{
|
||||
public string? DeviceVersion { get; }
|
||||
public bool IsCapturing { get; }
|
||||
public bool IsNetwork { get; }
|
||||
public AnalyzerDriverType DriverType { get; }
|
||||
public int Channels { get; }
|
||||
public event EventHandler<CaptureEventArgs> CaptureCompleted;
|
||||
|
@ -17,6 +19,8 @@ namespace SharedDriver
|
|||
public CaptureError StartPatternCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, int TriggerBitCount, UInt16 TriggerPattern, bool Fast, Action<CaptureEventArgs>? CaptureCompletedHandler = null);
|
||||
public bool StopCapture();
|
||||
public CaptureLimits GetLimits(int[] Channels);
|
||||
|
||||
public string? GetVoltageStatus();
|
||||
}
|
||||
|
||||
public class CaptureEventArgs : EventArgs
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO.Ports;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
@ -20,6 +21,9 @@ namespace SharedDriver
|
|||
string devAddr;
|
||||
ushort devPort;
|
||||
|
||||
public bool IsCapturing { get { return capturing; } }
|
||||
public bool IsNetwork { get { return isNetwork; } }
|
||||
|
||||
public object Tag { get; set; }
|
||||
public string? DeviceVersion { get; private set; }
|
||||
public int Channels { get { return 24; } }
|
||||
|
@ -450,6 +454,24 @@ namespace SharedDriver
|
|||
return CaptureModes.Modes[mode];
|
||||
}
|
||||
|
||||
public string? GetVoltageStatus()
|
||||
{
|
||||
if(!isNetwork)
|
||||
return "UNSUPPORTED";
|
||||
|
||||
OutputPacket pack = new OutputPacket();
|
||||
pack.AddByte(3);
|
||||
|
||||
baseStream.Write(pack.Serialize());
|
||||
baseStream.Flush();
|
||||
|
||||
baseStream.ReadTimeout = Timeout.Infinite;
|
||||
var result = readResponse.ReadLine();
|
||||
baseStream.ReadTimeout = Timeout.Infinite;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
try
|
||||
|
|
|
@ -29,6 +29,10 @@ namespace SharedDriver
|
|||
private int preSamples;
|
||||
|
||||
private Action<CaptureEventArgs>? currentCaptureHandler;
|
||||
|
||||
public bool IsCapturing { get { return capturing; } }
|
||||
public bool IsNetwork { get { return false; } }
|
||||
|
||||
public string DeviceVersion { get; private set; }
|
||||
public AnalyzerDriverType DriverType
|
||||
{
|
||||
|
@ -237,6 +241,12 @@ namespace SharedDriver
|
|||
var mode = GetCaptureMode(Channels);
|
||||
return CaptureModes.Modes[mode];
|
||||
}
|
||||
|
||||
public string? GetVoltageStatus()
|
||||
{
|
||||
return "UNSUPPORTED";
|
||||
}
|
||||
|
||||
private void Dev_CaptureCompleted(object? sender, CaptureEventArgs e)
|
||||
{
|
||||
lock(locker)
|
||||
|
|
Loading…
Reference in New Issue
Block a user