diff --git a/Software/LogicAnalyzer/AppConfig.json b/Software/LogicAnalyzer/AppConfig.json
index 8703ba3..a8f7ee0 100644
--- a/Software/LogicAnalyzer/AppConfig.json
+++ b/Software/LogicAnalyzer/AppConfig.json
@@ -1,19 +1,9 @@
{
- "AppName": "Avalonia.Designer.HostApp, Version=0.10.16.0, Culture=neutral, PublicKeyToken=c8d484a7012f9a8b",
+ "AppName": "LogicAnalyzer, Version=3.5.0.1, Culture=neutral, PublicKeyToken=null",
"WindowSettings": {
- "LogicAnalyzer.Dialogs.CreateSamplesDialog": {
- "Width": 800.0,
- "Height": 600.0,
- "Position": {
- "$type": "Avalonia.PixelPoint, Avalonia.Visuals",
- "X": 0,
- "Y": 0
- },
- "WindowState": 0
- },
"LogicAnalyzer.MainWindow": {
- "Width": 1024.0,
- "Height": 800.0,
+ "Width": 1837.0,
+ "Height": 1083.0,
"Position": {
"$type": "Avalonia.PixelPoint, Avalonia.Visuals",
"X": 0,
@@ -22,13 +12,23 @@
"WindowState": 0
},
"LogicAnalyzer.Dialogs.SignalComposerDialog": {
- "EditorFontSize": 14.0,
- "Width": 640.0,
- "Height": 480.0,
+ "EditorFontSize": 19.0,
+ "Width": 973.0,
+ "Height": 415.0,
"Position": {
"$type": "Avalonia.PixelPoint, Avalonia.Visuals",
- "X": 0,
- "Y": 0
+ "X": 1280,
+ "Y": 1016
+ },
+ "WindowState": 0
+ },
+ "LogicAnalyzer.Dialogs.CreateSamplesDialog": {
+ "Width": 800.0,
+ "Height": 600.0,
+ "Position": {
+ "$type": "Avalonia.PixelPoint, Avalonia.Visuals",
+ "X": 1665,
+ "Y": 1233
},
"WindowState": 0
},
@@ -37,8 +37,8 @@
"Height": 450.0,
"Position": {
"$type": "Avalonia.PixelPoint, Avalonia.Visuals",
- "X": 0,
- "Y": 0
+ "X": 1629,
+ "Y": 793
},
"WindowState": 0
}
diff --git a/Software/LogicAnalyzer/Artwork/Logo40.jpg b/Software/LogicAnalyzer/Artwork/Logo40.jpg
new file mode 100644
index 0000000..8e55d49
Binary files /dev/null and b/Software/LogicAnalyzer/Artwork/Logo40.jpg differ
diff --git a/Software/LogicAnalyzer/CLCapture/CLCapture.csproj b/Software/LogicAnalyzer/CLCapture/CLCapture.csproj
index b56f98c..4f6bbef 100644
--- a/Software/LogicAnalyzer/CLCapture/CLCapture.csproj
+++ b/Software/LogicAnalyzer/CLCapture/CLCapture.csproj
@@ -6,7 +6,7 @@
enable
enable
window.ico
- 4.0.0.0
+ 4.5.1.0
diff --git a/Software/LogicAnalyzer/CLCapture/CLCaptureOptions.cs b/Software/LogicAnalyzer/CLCapture/CLCaptureOptions.cs
index bc304bf..074edd2 100644
--- a/Software/LogicAnalyzer/CLCapture/CLCaptureOptions.cs
+++ b/Software/LogicAnalyzer/CLCapture/CLCaptureOptions.cs
@@ -16,7 +16,7 @@ namespace CLCapture
public string? AddressPort { get; set; }
[Value(1, Required = true, HelpText = "Desired sampling frequency.")]
public int SamplingFrequency { get; set; }
- [Value(2, Required = true, HelpText = "List of channels to capture (channels sepparated by comma).")]
+ [Value(2, Required = true, HelpText = "List of channels to capture (channels sepparated by comma, can contain a name adding a semicolon after the channel number, no spaces allowed).")]
public string? Channels { get; set; }
[Value(3, Required = true, HelpText = "Number of samples to capture before the trigger.")]
public int PreSamples { get; set; }
diff --git a/Software/LogicAnalyzer/CLCapture/CLChannel.cs b/Software/LogicAnalyzer/CLCapture/CLChannel.cs
new file mode 100644
index 0000000..607153c
--- /dev/null
+++ b/Software/LogicAnalyzer/CLCapture/CLChannel.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CLCapture
+{
+ public class CLChannel
+ {
+ public CLChannel(string Definition)
+ {
+ if(string.IsNullOrWhiteSpace(Definition))
+ throw new ArgumentNullException("Missing channel definition.");
+
+ var inputParts = Definition.Trim().Split(":");
+
+ if (inputParts.Length < 1)
+ throw new ArgumentException("Invalid channel definition");
+
+ if (inputParts.Length == 1)
+ {
+ int value;
+
+ if (!int.TryParse(inputParts[0], out value))
+ throw new ArgumentException("Invalid channel definition, channel must be defined in decimal form.");
+
+ ChannelNumber = value;
+ ChannelName = $"Channel {value}";
+ }
+ else if (inputParts.Length == 2)
+ {
+ int value;
+
+ if (!int.TryParse(inputParts[0], out value))
+ throw new ArgumentException("Invalid channel definition, channel must be defined in decimal form.");
+
+ ChannelNumber = value;
+ ChannelName = inputParts[1];
+ }
+ else
+ {
+ throw new ArgumentException("Invalid channel definition, too many parts.");
+ }
+ }
+ public int ChannelNumber { get; set; }
+ public string ChannelName { get; set; }
+ }
+}
diff --git a/Software/LogicAnalyzer/CLCapture/Program.cs b/Software/LogicAnalyzer/CLCapture/Program.cs
index 4407c27..3ed7d9c 100644
--- a/Software/LogicAnalyzer/CLCapture/Program.cs
+++ b/Software/LogicAnalyzer/CLCapture/Program.cs
@@ -39,15 +39,27 @@ async Task Capture(CLCaptureOptions opts)
return -1;
}
- int[]? channels = opts.Channels?.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(c => int.Parse(c)).ToArray();
+ CLChannel[]? channels;
- if (channels == null || channels.Any(c => c < 1 || c > 24))
+ try
+ {
+
+ //int[]? channels = opts.Channels?.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(c => int.Parse(c)).ToArray();
+ channels = opts.Channels?.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(c => new CLChannel(c)).ToArray();
+ }
+ catch (Exception ex)
+ {
+ Console.WriteLine(ex.Message);
+ return -1;
+ }
+
+ if (channels == null || channels.Any(c => c.ChannelNumber < 1 || c.ChannelNumber > 24))
{
Console.WriteLine("Specified capture channels out of range.");
return -1;
}
- int maxChannel = channels.Max();
+ int maxChannel = channels.Max(c => c.ChannelNumber);
int channelMode = maxChannel <= 8 ? 0 : (maxChannel <= 16 ? 1 : 2);
int channelCount = maxChannel <= 8 ? 8 : (maxChannel <= 16 ? 16 : 24);
@@ -163,13 +175,13 @@ async Task Capture(CLCaptureOptions opts)
captureCompletedTask = new TaskCompletionSource();
- channels = opts.Channels.Split(",", StringSplitOptions.RemoveEmptyEntries).Select(c => int.Parse(c) - 1).ToArray();
+ int[] nChannels = channels.Select(c => c.ChannelNumber - 1).ToArray();
if (opts.Trigger.TriggerType == CLTriggerType.Edge)
{
Console.WriteLine("Starting edge triggered capture...");
var resStart = driver.StartCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
- channels, opts.Trigger.Channel - 1, opts.Trigger.Value == "0", CaptureFinished);
+ nChannels, opts.Trigger.Channel - 1, opts.Trigger.Value == "0", CaptureFinished);
if (resStart != CaptureError.None)
{
@@ -209,7 +221,7 @@ async Task Capture(CLCaptureOptions opts)
}
var resStart = driver.StartPatternCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
- channels, opts.Trigger.Channel - 1, bitCount, triggerPattern, opts.Trigger.TriggerType == CLTriggerType.Fast, CaptureFinished);
+ nChannels, opts.Trigger.Channel - 1, bitCount, triggerPattern, opts.Trigger.TriggerType == CLTriggerType.Fast, CaptureFinished);
if (resStart != CaptureError.None)
{
@@ -246,7 +258,7 @@ async Task Capture(CLCaptureOptions opts)
var file = File.Create(opts.OutputFile);
StreamWriter sw = new StreamWriter(file);
- sw.WriteLine(String.Join(',', channels.Select(c => $"Channel {c + 1}").ToArray()));
+ sw.WriteLine(String.Join(',', channels.Select(c => c.ChannelName).ToArray()));
StringBuilder sb = new StringBuilder();
@@ -254,14 +266,14 @@ async Task Capture(CLCaptureOptions opts)
{
sb.Clear();
- for (int buc = 0; buc < opts.Channels.Length; buc++)
+ for (int buc = 0; buc < nChannels.Length; buc++)
{
- if ((result.Samples[sample] & ((UInt128)1 << buc)) == 0)
+ if ((result.Samples[sample] & ((UInt128)1 << nChannels[buc])) == 0)
sb.Append("0,");
else
sb.Append("1,");
}
-
+ sb.Remove(sb.Length - 1, 1);
sw.WriteLine(sb.ToString());
}
diff --git a/Software/LogicAnalyzer/CLCapture/Properties/launchSettings.json b/Software/LogicAnalyzer/CLCapture/Properties/launchSettings.json
index f066825..0a33340 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 COM3 1000000 1,2,3,4,5,6,7,8 20 20000 TriggerType:Edge,Channel:1,Value:1 ../test.csv"
+ "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"
}
}
}
\ No newline at end of file
diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Classes/AnalysisSettings.cs b/Software/LogicAnalyzer/LogicAnalyzer/Classes/AnalysisSettings.cs
new file mode 100644
index 0000000..a2dd9f6
--- /dev/null
+++ b/Software/LogicAnalyzer/LogicAnalyzer/Classes/AnalysisSettings.cs
@@ -0,0 +1,16 @@
+using LogicAnalyzer.Protocols;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LogicAnalyzer.Classes
+{
+ public class AnalysisSettings
+ {
+ public ProtocolAnalyzerBase? Analyzer { get; set; }
+ public ProtocolAnalyzerSelectedChannel[]? Channels { get; set; }
+ public ProtocolAnalyzerSettingValue[]? Settings { get; set; }
+ }
+}
diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs
index de978be..d1e0e06 100644
--- a/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs
+++ b/Software/LogicAnalyzer/LogicAnalyzer/Dialogs/CaptureDialog.axaml.cs
@@ -142,7 +142,7 @@ namespace LogicAnalyzer.Dialogs
private void LoadSettings(AnalyzerDriverType DriverType)
{
- settingsFile = $"cpSettings{DriverType}.json";
+ settingsFile = WindowExtensions.GetFilePath($"cpSettings{DriverType}.json");
if (File.Exists(settingsFile))
{
@@ -316,7 +316,13 @@ namespace LogicAnalyzer.Dialogs
{
trigger = (int)nudTriggerBase.Value - 1;
- char[] patternChars = txtPattern.Text.ToArray();
+ if (string.IsNullOrWhiteSpace(txtPattern.Text))
+ {
+ await this.ShowError("Error", "Trigger pattern must be at least one bit long.");
+ return;
+ }
+
+ char[] patternChars = txtPattern.Text.Trim().ToArray();
if (patternChars.Length == 0)
{
diff --git a/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs b/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs
index d89447e..9b3e600 100644
--- a/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs
+++ b/Software/LogicAnalyzer/LogicAnalyzer/Extensions/WindowExtensions.cs
@@ -11,18 +11,32 @@ using System.Threading.Tasks;
using System.IO;
using Newtonsoft.Json;
using System.Text.Json;
+using static System.Environment;
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()
{
- if (File.Exists("AppConfig.json"))
- config = JsonConvert.DeserializeObject(File.ReadAllText("AppConfig.json"), jSettings);
+
+ string path = GetFilePath("AppConfig.json");
+
+ if (File.Exists(path))
+ config = JsonConvert.DeserializeObject(File.ReadAllText(path), jSettings);
if(config == null)
config = new AppConfig();
@@ -132,8 +146,9 @@ namespace LogicAnalyzer.Extensions
}
private static void PersistSettings()
{
+ string path = GetFilePath("AppConfig.json");
- File.WriteAllText("AppConfig.json", JsonConvert.SerializeObject(config, Formatting.Indented, jSettings));
+ File.WriteAllText(path, JsonConvert.SerializeObject(config, Formatting.Indented, jSettings));
}
private static object GetPropertyValue(object Source, string PropertyName)
{
diff --git a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj
index 6d5f5a5..63a1db0 100644
--- a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj
+++ b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj
@@ -8,7 +8,7 @@
true
Assets\Ico40.ico
True
- 4.0.0.0
+ 4.5.1.0
diff --git a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user
index 58adfad..87f9830 100644
--- a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user
+++ b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user
@@ -1,6 +1,10 @@
- <_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Windows-Arm64.pubxml
+ <_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Linux.pubxml
+ LogicAnalyzer
+
+
+ ProjectDebugger
\ No newline at end of file
diff --git a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml
index fd19e6e..03b1e5f 100644
--- a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml
+++ b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml
@@ -3,11 +3,11 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="clr-namespace:LogicAnalyzer.Controls"
- mc:Ignorable="d" d:DesignWidth="1024" d:DesignHeight="800"
+ mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="600"
x:Class="LogicAnalyzer.MainWindow"
Title="LogicAnalyzer - Multiplatform version"
Icon="/Assets/Ico40.ico"
- Background="#383838" MinWidth="1024" MinHeight="800" Width="1024" Height="800" WindowStartupLocation="CenterScreen">
+ Background="#383838" MinWidth="800" MinHeight="600" Width="800" Height="600" WindowStartupLocation="CenterScreen">