diff --git a/Software/LogicAnalyzer/CLCapture/Properties/launchSettings.json b/Software/LogicAnalyzer/CLCapture/Properties/launchSettings.json index 0a33340..8b29ea9 100644 --- a/Software/LogicAnalyzer/CLCapture/Properties/launchSettings.json +++ b/Software/LogicAnalyzer/CLCapture/Properties/launchSettings.json @@ -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" } } } \ No newline at end of file diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Assets/battery.png b/Software/LogicAnalyzer/LogicAnalyzer/Assets/battery.png new file mode 100644 index 0000000..1e0e55e Binary files /dev/null and b/Software/LogicAnalyzer/LogicAnalyzer/Assets/battery.png differ diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Assets/plug.png b/Software/LogicAnalyzer/LogicAnalyzer/Assets/plug.png new file mode 100644 index 0000000..8b76995 Binary files /dev/null and b/Software/LogicAnalyzer/LogicAnalyzer/Assets/plug.png differ diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Classes/AppSettingsManager.cs b/Software/LogicAnalyzer/LogicAnalyzer/Classes/AppSettingsManager.cs new file mode 100644 index 0000000..c2553c3 --- /dev/null +++ b/Software/LogicAnalyzer/LogicAnalyzer/Classes/AppSettingsManager.cs @@ -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(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(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); + } + } +} diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/AboutDialog.axaml b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/AboutDialog.axaml new file mode 100644 index 0000000..c1da4d0 --- /dev/null +++ b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/AboutDialog.axaml @@ -0,0 +1,21 @@ + + + + + ©2023 Agustín Giménez Bernad + Version 5.0.0.0 + + + + diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/AboutDialog.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/AboutDialog.axaml.cs new file mode 100644 index 0000000..874341e --- /dev/null +++ b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/AboutDialog.axaml.cs @@ -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; + } + } +} diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs index 6df7fce..41bb4ee 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs +++ b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs @@ -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(settingsFile); - if (File.Exists(settingsFile)) + if (settings != null) { - string data = File.ReadAllText(settingsFile); - - CaptureSettings? settings = null; - - try - { - settings = JsonConvert.DeserializeObject(data); - } - catch { } - - if (settings == null) - { - try - { - var oldset = JsonConvert.DeserializeObject(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; diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/NetworkDialog.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/NetworkDialog.axaml.cs index 81ad135..d6661c8 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/NetworkDialog.axaml.cs +++ b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/NetworkDialog.axaml.cs @@ -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("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; } + } } diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/ProtocolAnalyzerSettingsDialog.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/ProtocolAnalyzerSettingsDialog.axaml.cs index 5d10d45..90b67e0 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/ProtocolAnalyzerSettingsDialog.axaml.cs +++ b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/ProtocolAnalyzerSettingsDialog.axaml.cs @@ -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; } + } } } diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs b/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs index 9b3e600..8272b02 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs +++ b/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs @@ -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(File.ReadAllText(path), jSettings); - - if(config == null) - config = new AppConfig(); + var cfg = AppSettingsManager.GetSettings("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 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; diff --git a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj index efd9494..69bdf37 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj +++ b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj @@ -31,6 +31,7 @@ + diff --git a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user index 87f9830..4ea6b80 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user +++ b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user @@ -1,10 +1,13 @@  - <_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Linux.pubxml + <_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Windows.pubxml LogicAnalyzer ProjectDebugger + + ProjectDebugger + \ No newline at end of file diff --git a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml index 247caa9..5fbd264 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml +++ b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml @@ -24,7 +24,12 @@ - + + + + + + @@ -57,7 +62,7 @@ - + Adjustments @@ -79,9 +84,7 @@ - - - + Information @@ -128,6 +131,15 @@ + + + - Power status: + + + + 3.38v + + diff --git a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs index fabdd77..87614e8 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs +++ b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs @@ -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(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(); + 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,13 +1061,26 @@ namespace LogicAnalyzer { var dialog = new CaptureDialog(); dialog.Initialize(driver); - if (!await dialog.ShowDialog(this)) return; settings = dialog.SelectedSettings; preserveSamples = false; - BeginCapture(); + + tmrPower.Change(Timeout.Infinite, Timeout.Infinite); + + try + { + BeginCapture(); + + var settingsFile = $"cpSettings{driver.DriverType}.json"; + AppSettingsManager.PersistSettings(settingsFile, settings); + + } + finally + { + tmrPower.Change(30000, Timeout.Infinite); + } } diff --git a/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIAnalyzer.cs b/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIAnalyzer.cs index e4b5b7e..a2ff14e 100644 --- a/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIAnalyzer.cs +++ b/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIAnalyzer.cs @@ -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; } diff --git a/Software/LogicAnalyzer/SharedDriver/EmulatedAnalizerDriver.cs b/Software/LogicAnalyzer/SharedDriver/EmulatedAnalizerDriver.cs index b774344..6f33ac7 100644 --- a/Software/LogicAnalyzer/SharedDriver/EmulatedAnalizerDriver.cs +++ b/Software/LogicAnalyzer/SharedDriver/EmulatedAnalizerDriver.cs @@ -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; diff --git a/Software/LogicAnalyzer/SharedDriver/IAnalizerDriver.cs b/Software/LogicAnalyzer/SharedDriver/IAnalizerDriver.cs index cb5dba2..3983edc 100644 --- a/Software/LogicAnalyzer/SharedDriver/IAnalizerDriver.cs +++ b/Software/LogicAnalyzer/SharedDriver/IAnalizerDriver.cs @@ -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 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? CaptureCompletedHandler = null); public bool StopCapture(); public CaptureLimits GetLimits(int[] Channels); + + public string? GetVoltageStatus(); } public class CaptureEventArgs : EventArgs diff --git a/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs b/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs index b41ea40..6a36153 100644 --- a/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs +++ b/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs @@ -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 diff --git a/Software/LogicAnalyzer/SharedDriver/MultiAnalizerDriver.cs b/Software/LogicAnalyzer/SharedDriver/MultiAnalizerDriver.cs index 0a26393..cc8e272 100644 --- a/Software/LogicAnalyzer/SharedDriver/MultiAnalizerDriver.cs +++ b/Software/LogicAnalyzer/SharedDriver/MultiAnalizerDriver.cs @@ -29,6 +29,10 @@ namespace SharedDriver private int preSamples; private Action? 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)