From bba03c69ebf1e671b52e794d4e845c1e8799a7c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Gimenez?= Date: Tue, 7 Feb 2023 19:09:50 +0100 Subject: [PATCH] Corrected driver to work properly under Linux --- .../LogicAnalyzer/CLCapture/CLCapture.csproj | 1 + Software/LogicAnalyzer/CLCapture/Program.cs | 6 + .../I2CProtocolAnalyzer.csproj | 1 + .../LogicAnalyzer/LogicAnalyzer.csproj | 1 + .../LogicAnalyzer/LogicAnalyzer.csproj.user | 2 +- .../LogicAnalyzer/MainWindow.axaml.cs | 3 + .../SPIProtocolAnalyzer.csproj | 1 + .../SerialProtocolAnalyzer.csproj | 1 + .../SharedDriver/LogicAnalyzerDriver.cs | 314 +++++++++++------- .../SharedDriver/SharedDriver.csproj | 1 + 10 files changed, 204 insertions(+), 127 deletions(-) diff --git a/Software/LogicAnalyzer/CLCapture/CLCapture.csproj b/Software/LogicAnalyzer/CLCapture/CLCapture.csproj index 089610b..69f8eae 100644 --- a/Software/LogicAnalyzer/CLCapture/CLCapture.csproj +++ b/Software/LogicAnalyzer/CLCapture/CLCapture.csproj @@ -6,6 +6,7 @@ enable enable window.ico + 3.5.0.1 diff --git a/Software/LogicAnalyzer/CLCapture/Program.cs b/Software/LogicAnalyzer/CLCapture/Program.cs index 3ada266..d69d3b7 100644 --- a/Software/LogicAnalyzer/CLCapture/Program.cs +++ b/Software/LogicAnalyzer/CLCapture/Program.cs @@ -186,6 +186,9 @@ async Task Capture(CLCaptureOptions opts) case CaptureError.HardwareError: Console.WriteLine("Device reported error starting capture. Restart the device and try again."); return -1; + case CaptureError.UnexpectedError: + Console.WriteLine("Unexpected error. Restart the device and try again."); + return -1; } } @@ -223,6 +226,9 @@ async Task Capture(CLCaptureOptions opts) case CaptureError.HardwareError: Console.WriteLine("Device reported error starting capture. Restart the device and try again."); return -1; + case CaptureError.UnexpectedError: + Console.WriteLine("Unexpected error. Restart the device and try again."); + return -1; } } diff --git a/Software/LogicAnalyzer/I2CProtocolAnalyzer/I2CProtocolAnalyzer.csproj b/Software/LogicAnalyzer/I2CProtocolAnalyzer/I2CProtocolAnalyzer.csproj index 217c143..eb25d9d 100644 --- a/Software/LogicAnalyzer/I2CProtocolAnalyzer/I2CProtocolAnalyzer.csproj +++ b/Software/LogicAnalyzer/I2CProtocolAnalyzer/I2CProtocolAnalyzer.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + 3.5.0.1 diff --git a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj index edeb58d..4a1a0b5 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj +++ b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj @@ -8,6 +8,7 @@ true Assets\window.ico True + 3.5.0.1 diff --git a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user index 58adfad..df3f138 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user +++ b/Software/LogicAnalyzer/LogicAnalyzer/LogicAnalyzer.csproj.user @@ -1,6 +1,6 @@  - <_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Windows-Arm64.pubxml + <_LastSelectedProfileId>C:\Users\geniw\source\repos\LogicAnalyzer\LogicAnalyzer\Properties\PublishProfiles\Linux-Arm.pubxml \ No newline at end of file diff --git a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs index 98092f8..e1ceeb3 100644 --- a/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs +++ b/Software/LogicAnalyzer/LogicAnalyzer/MainWindow.axaml.cs @@ -561,6 +561,9 @@ private async Task ShowError(CaptureError error) case CaptureError.HardwareError: await ShowError("Error", "Device reported error starting capture. Restart the device and try again."); return; + case CaptureError.UnexpectedError: + await ShowError("Error", "Unexpected error, restart the application and the device and try again."); + return; } } diff --git a/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIProtocolAnalyzer.csproj b/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIProtocolAnalyzer.csproj index 217c143..eb25d9d 100644 --- a/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIProtocolAnalyzer.csproj +++ b/Software/LogicAnalyzer/SPIProtocolAnalyzer/SPIProtocolAnalyzer.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + 3.5.0.1 diff --git a/Software/LogicAnalyzer/SerialProtocolAnalyzer/SerialProtocolAnalyzer.csproj b/Software/LogicAnalyzer/SerialProtocolAnalyzer/SerialProtocolAnalyzer.csproj index 217c143..eb25d9d 100644 --- a/Software/LogicAnalyzer/SerialProtocolAnalyzer/SerialProtocolAnalyzer.csproj +++ b/Software/LogicAnalyzer/SerialProtocolAnalyzer/SerialProtocolAnalyzer.csproj @@ -4,6 +4,7 @@ net6.0 enable enable + 3.5.0.1 diff --git a/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs b/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs index 54fe14c..2c80612 100644 --- a/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs +++ b/Software/LogicAnalyzer/SharedDriver/LogicAnalyzerDriver.cs @@ -1,4 +1,5 @@ using System.IO.Ports; +using System.Net.Http; using System.Net.Sockets; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; @@ -15,6 +16,8 @@ public class LogicAnalyzerDriver : IDisposable Stream baseStream; SerialPort sp; TcpClient tcpClient; + string devAddr; + ushort devPort; public string? DeviceVersion { get; set; } public event EventHandler? CaptureCompleted; @@ -59,17 +62,15 @@ public LogicAnalyzerDriver(string AddressPort) if (match == null || !match.Success) throw new ArgumentException("Specified address/port is invalid"); - string addr = match.Groups[1].Value; + devAddr = match.Groups[1].Value; string port = match.Groups[2].Value; - ushort uport; - - if(!ushort.TryParse(port, out uport)) + if(!ushort.TryParse(port, out devPort)) throw new ArgumentException("Specified address/port is invalid"); tcpClient = new TcpClient(); - tcpClient.Connect(addr, uport); + tcpClient.Connect(devAddr, devPort); baseStream = tcpClient.GetStream(); readResponse = new StreamReader(baseStream); @@ -127,137 +128,144 @@ public CaptureError StartCapture(int Frequency, int PreSamples, int PostSamples, if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PostSamples < 512 || Frequency < 3100 || Frequency > 100000000) return CaptureError.BadParams; - switch (CaptureMode) + try { - case 0: - - if (PreSamples > 98303 || PostSamples > 131069 || PreSamples + PostSamples > 131071) - return CaptureError.BadParams; - break; - - case 1: - - if (PreSamples > 49151 || PostSamples > 65533 || PreSamples + PostSamples > 65535) - return CaptureError.BadParams; - break; - - case 2: + switch (CaptureMode) + { + case 0: - if (PreSamples > 24576 || PostSamples > 32765 || PreSamples + PostSamples > 32767) - return CaptureError.BadParams; - break; - } + if (PreSamples > 98303 || PostSamples > 131069 || PreSamples + PostSamples > 131071) + return CaptureError.BadParams; + break; - channelCount = Channels.Length; - triggerChannel = Array.IndexOf(Channels, TriggerChannel); - preSamples = PreSamples; - currentCaptureHandler = CaptureCompletedHandler; + case 1: - CaptureRequest request = new CaptureRequest - { - triggerType = 0, - trigger = (byte)TriggerChannel, - invertedOrCount = TriggerInverted ? (byte)1 : (byte)0, - channels = new byte[32], - channelCount = (byte)Channels.Length, - frequency = (uint)Frequency, - preSamples = (uint)PreSamples, - postSamples = (uint)PostSamples, - captureMode = CaptureMode - }; - - for (int buc = 0; buc < Channels.Length; buc++) - request.channels[buc] = (byte)Channels[buc]; + if (PreSamples > 49151 || PostSamples > 65533 || PreSamples + PostSamples > 65535) + return CaptureError.BadParams; + break; - OutputPacket pack = new OutputPacket(); - pack.AddByte(1); - pack.AddStruct(request); + case 2: - baseStream.Write(pack.Serialize()); - baseStream.Flush(); + if (PreSamples > 24576 || PostSamples > 32765 || PreSamples + PostSamples > 32767) + return CaptureError.BadParams; + break; + } - baseStream.ReadTimeout = 10000; - var result = readResponse.ReadLine(); - baseStream.ReadTimeout = Timeout.Infinite; + channelCount = Channels.Length; + triggerChannel = Array.IndexOf(Channels, TriggerChannel); + preSamples = PreSamples; + currentCaptureHandler = CaptureCompletedHandler; - if (result == "CAPTURE_STARTED") - { - capturing = true; - Task.Run(() => ReadCapture(PreSamples + PostSamples, CaptureMode)); - return CaptureError.None; + CaptureRequest request = new CaptureRequest + { + triggerType = 0, + trigger = (byte)TriggerChannel, + invertedOrCount = TriggerInverted ? (byte)1 : (byte)0, + channels = new byte[32], + channelCount = (byte)Channels.Length, + frequency = (uint)Frequency, + preSamples = (uint)PreSamples, + postSamples = (uint)PostSamples, + captureMode = CaptureMode + }; + + for (int buc = 0; buc < Channels.Length; buc++) + request.channels[buc] = (byte)Channels[buc]; + + OutputPacket pack = new OutputPacket(); + pack.AddByte(1); + pack.AddStruct(request); + + baseStream.Write(pack.Serialize()); + baseStream.Flush(); + + baseStream.ReadTimeout = 10000; + var result = readResponse.ReadLine(); + baseStream.ReadTimeout = Timeout.Infinite; + + if (result == "CAPTURE_STARTED") + { + capturing = true; + Task.Run(() => ReadCapture(PreSamples + PostSamples, CaptureMode)); + return CaptureError.None; + } + return CaptureError.HardwareError; } - return CaptureError.HardwareError; + catch { return CaptureError.UnexpectedError; } } public CaptureError StartPatternCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, int TriggerBitCount, UInt16 TriggerPattern, bool Fast, byte CaptureMode, Action? CaptureCompletedHandler = null) { - - if (capturing) - return CaptureError.Busy; - - if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PostSamples < 512 || Frequency < 3100 || Frequency > 100000000) - return CaptureError.BadParams; - - switch (CaptureMode) + try { - case 0: - - if (PreSamples > 98303 || PostSamples > 131069 || PreSamples + PostSamples > 131071) - return CaptureError.BadParams; - break; - - case 1: + if (capturing) + return CaptureError.Busy; - if (PreSamples > 49151 || PostSamples > 65533 || PreSamples + PostSamples > 65535) - return CaptureError.BadParams; - break; + if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PostSamples < 512 || Frequency < 3100 || Frequency > 100000000) + return CaptureError.BadParams; - case 2: + switch (CaptureMode) + { + case 0: - if (PreSamples > 24576 || PostSamples > 32765 || PreSamples + PostSamples > 32767) - return CaptureError.BadParams; - break; - } + if (PreSamples > 98303 || PostSamples > 131069 || PreSamples + PostSamples > 131071) + return CaptureError.BadParams; + break; - channelCount = Channels.Length; - triggerChannel = Array.IndexOf(Channels, TriggerChannel); - preSamples = PreSamples; - currentCaptureHandler = CaptureCompletedHandler; + case 1: - CaptureRequest request = new CaptureRequest - { - triggerType = (byte)(Fast ? 2 : 1), - trigger = (byte)TriggerChannel, - invertedOrCount = (byte)TriggerBitCount, - triggerValue = (UInt16)TriggerPattern, - channels = new byte[32], - channelCount = (byte)Channels.Length, - frequency = (uint)Frequency, - preSamples = (uint)PreSamples, - postSamples = (uint)PostSamples, - captureMode = CaptureMode - }; - - for (int buc = 0; buc < Channels.Length; buc++) - request.channels[buc] = (byte)Channels[buc]; + if (PreSamples > 49151 || PostSamples > 65533 || PreSamples + PostSamples > 65535) + return CaptureError.BadParams; + break; - OutputPacket pack = new OutputPacket(); - pack.AddByte(1); - pack.AddStruct(request); + case 2: - baseStream.Write(pack.Serialize()); - baseStream.Flush(); + if (PreSamples > 24576 || PostSamples > 32765 || PreSamples + PostSamples > 32767) + return CaptureError.BadParams; + break; + } - baseStream.ReadTimeout = 10000; - var result = readResponse.ReadLine(); - baseStream.ReadTimeout = Timeout.Infinite; + channelCount = Channels.Length; + triggerChannel = Array.IndexOf(Channels, TriggerChannel); + preSamples = PreSamples; + currentCaptureHandler = CaptureCompletedHandler; - if (result == "CAPTURE_STARTED") - { - capturing = true; - Task.Run(() => ReadCapture(PreSamples + PostSamples, CaptureMode)); - return CaptureError.None; + CaptureRequest request = new CaptureRequest + { + triggerType = (byte)(Fast ? 2 : 1), + trigger = (byte)TriggerChannel, + invertedOrCount = (byte)TriggerBitCount, + triggerValue = (UInt16)TriggerPattern, + channels = new byte[32], + channelCount = (byte)Channels.Length, + frequency = (uint)Frequency, + preSamples = (uint)PreSamples, + postSamples = (uint)PostSamples, + captureMode = CaptureMode + }; + + for (int buc = 0; buc < Channels.Length; buc++) + request.channels[buc] = (byte)Channels[buc]; + + OutputPacket pack = new OutputPacket(); + pack.AddByte(1); + pack.AddStruct(request); + + baseStream.Write(pack.Serialize()); + baseStream.Flush(); + + baseStream.ReadTimeout = 10000; + var result = readResponse.ReadLine(); + baseStream.ReadTimeout = Timeout.Infinite; + + if (result == "CAPTURE_STARTED") + { + capturing = true; + Task.Run(() => ReadCapture(PreSamples + PostSamples, CaptureMode)); + return CaptureError.None; + } + return CaptureError.HardwareError; } - return CaptureError.HardwareError; + catch { return CaptureError.UnexpectedError; } } public bool StopCapture() @@ -267,15 +275,32 @@ public bool StopCapture() capturing = false; - sp.Write(new byte[] { 0xFF }, 0, 1); - sp.BaseStream.Flush(); - Thread.Sleep(1); - sp.Close(); - Thread.Sleep(1); - sp.Open(); - baseStream = sp.BaseStream; - readResponse = new StreamReader(baseStream); - readData = new BinaryReader(baseStream); + if (IsNetwork) + { + baseStream.WriteByte(0xff); + baseStream.Flush(); + Thread.Sleep(1); + tcpClient.Close(); + Thread.Sleep(1); + tcpClient = new TcpClient(); + tcpClient.Connect(devAddr, devPort); + baseStream = tcpClient.GetStream(); + readResponse = new StreamReader(baseStream); + readData = new BinaryReader(baseStream); + } + else + { + + sp.Write(new byte[] { 0xFF }, 0, 1); + sp.BaseStream.Flush(); + Thread.Sleep(1); + sp.Close(); + Thread.Sleep(1); + sp.Open(); + baseStream = sp.BaseStream; + readResponse = new StreamReader(baseStream); + readData = new BinaryReader(baseStream); + } return true; } @@ -333,19 +358,39 @@ void ReadCapture(int Samples, byte Mode) uint length = readData.ReadUInt32(); uint[] samples = new uint[length]; + BinaryReader rdData; + + if (IsNetwork) + rdData = readData; + else + { + byte[] readBuffer = new byte[Samples * (Mode == 0 ? 1 : (Mode == 1 ? 2 : 4))]; + int left = readBuffer.Length; + int pos = 0; + + while (left > 0 && sp.IsOpen) + { + pos += sp.Read(readBuffer, pos, left); + left = readBuffer.Length - pos; + } + + MemoryStream ms = new MemoryStream(readBuffer); + rdData = new BinaryReader(ms); + } + switch(Mode) { case 0: for (int buc = 0; buc < length; buc++) - samples[buc] = readData.ReadByte(); + samples[buc] = rdData.ReadByte(); break; case 1: for (int buc = 0; buc < length; buc++) - samples[buc] = readData.ReadUInt16(); + samples[buc] = rdData.ReadUInt16(); break; case 2: for (int buc = 0; buc < length; buc++) - samples[buc] = readData.ReadUInt32(); + samples[buc] = rdData.ReadUInt32(); break; } @@ -354,6 +399,22 @@ void ReadCapture(int Samples, byte Mode) else if (CaptureCompleted != null) CaptureCompleted(this, new CaptureEventArgs { Samples = samples, ChannelCount = channelCount, TriggerChannel = triggerChannel, PreSamples = preSamples }); + if (!IsNetwork) + { + try + { + rdData.BaseStream.Close(); + rdData.BaseStream.Dispose(); + } + catch { } + + try + { + rdData.Close(); + rdData.Dispose(); + } + catch { } + } capturing = false; } catch(Exception ex) @@ -453,7 +514,8 @@ public enum CaptureError None, Busy, BadParams, - HardwareError + HardwareError, + UnexpectedError } public class CaptureEventArgs : EventArgs diff --git a/Software/LogicAnalyzer/SharedDriver/SharedDriver.csproj b/Software/LogicAnalyzer/SharedDriver/SharedDriver.csproj index c1dffb0..20ffb37 100644 --- a/Software/LogicAnalyzer/SharedDriver/SharedDriver.csproj +++ b/Software/LogicAnalyzer/SharedDriver/SharedDriver.csproj @@ -5,6 +5,7 @@ enable enable True + 3.5.0.1