mirror of
https://github.com/JasonYANG170/logicanalyzer.git
synced 2024-11-23 12:06:27 +00:00
Updated applications
This commit is contained in:
parent
2816c8be90
commit
bf29561d91
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -130,8 +130,25 @@ return await Parser.Default.ParseArguments<CLCaptureCommandLineOptions>(args)
|
||||||
if (opts.Trigger.TriggerType == CLTriggerType.Edge)
|
if (opts.Trigger.TriggerType == CLTriggerType.Edge)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Starting edge triggered capture...");
|
Console.WriteLine("Starting edge triggered capture...");
|
||||||
driver.StartCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
|
var resStart = driver.StartCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
|
||||||
channels, opts.Trigger.Channel - 1, opts.Trigger.Value == "0", CaptureFinished);
|
channels, opts.Trigger.Channel - 1, opts.Trigger.Value == "0", CaptureFinished);
|
||||||
|
|
||||||
|
if (resStart != CaptureError.None)
|
||||||
|
{
|
||||||
|
switch (resStart)
|
||||||
|
{
|
||||||
|
case CaptureError.Busy:
|
||||||
|
Console.WriteLine("Device is busy, stop the capture before starting a new one.");
|
||||||
|
return -1;
|
||||||
|
case CaptureError.BadParams:
|
||||||
|
Console.WriteLine("Specified parameters are incorrect.\r\n\r\n -Frequency must be between 3.1Khz and 100Mhz\r\n -PreSamples must be between 2 and 31743\r\n -PostSamples must be between 512 and 32767\r\n -Total samples cannot exceed 32767");
|
||||||
|
return -1;
|
||||||
|
case CaptureError.HardwareError:
|
||||||
|
Console.WriteLine("Device reported error starting capture. Restart the device and try again.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine("Capture running...");
|
Console.WriteLine("Capture running...");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -150,8 +167,25 @@ return await Parser.Default.ParseArguments<CLCaptureCommandLineOptions>(args)
|
||||||
triggerPattern |= (UInt16)(1 << buc);
|
triggerPattern |= (UInt16)(1 << buc);
|
||||||
}
|
}
|
||||||
|
|
||||||
driver.StartPatternCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
|
var resStart = driver.StartPatternCapture(opts.SamplingFrequency, opts.PreSamples, opts.PostSamples,
|
||||||
channels, opts.Trigger.Channel - 1, bitCount, triggerPattern, opts.Trigger.TriggerType == CLTriggerType.Fast, CaptureFinished);
|
channels, opts.Trigger.Channel - 1, bitCount, triggerPattern, opts.Trigger.TriggerType == CLTriggerType.Fast, CaptureFinished);
|
||||||
|
|
||||||
|
if (resStart != CaptureError.None)
|
||||||
|
{
|
||||||
|
switch (resStart)
|
||||||
|
{
|
||||||
|
case CaptureError.Busy:
|
||||||
|
Console.WriteLine("Device is busy, stop the capture before starting a new one.");
|
||||||
|
return -1;
|
||||||
|
case CaptureError.BadParams:
|
||||||
|
Console.WriteLine("Specified parameters are incorrect.\r\n\r\n -Frequency must be between 3.1Khz and 100Mhz\r\n -PreSamples must be between 2 and 31743\r\n -PostSamples must be between 512 and 32767\r\n -Total samples cannot exceed 32767");
|
||||||
|
return -1;
|
||||||
|
case CaptureError.HardwareError:
|
||||||
|
Console.WriteLine("Device reported error starting capture. Restart the device and try again.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine("Capture running...");
|
Console.WriteLine("Capture running...");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using LogicAnalyzer.Classes;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using SharedDriver;
|
using SharedDriver;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -7,7 +6,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace LogicAnalyzer
|
namespace LogicAnalyzer.Classes
|
||||||
{
|
{
|
||||||
public class ExportedCapture
|
public class ExportedCapture
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace LogicAnalyzer.Classes
|
||||||
|
|
||||||
public static Pen GetPen(Color PenColor, double PenThickness, IDashStyle Style = null)
|
public static Pen GetPen(Color PenColor, double PenThickness, IDashStyle Style = null)
|
||||||
{
|
{
|
||||||
string key = "COLOR" + PenColor.ToString() + PenThickness.ToString() + (Style?.ToString() ?? "");
|
string key = "COLOR" + PenColor.ToString() + PenThickness.ToString() + GetDashName(Style);
|
||||||
|
|
||||||
if (!_pens.ContainsKey(key))
|
if (!_pens.ContainsKey(key))
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace LogicAnalyzer.Classes
|
||||||
|
|
||||||
public static Pen GetPen(IBrush PenBrush, double PenThickness, IDashStyle Style = null)
|
public static Pen GetPen(IBrush PenBrush, double PenThickness, IDashStyle Style = null)
|
||||||
{
|
{
|
||||||
string key = "BRUSH" + PenBrush.GetHashCode().ToString() + PenThickness.ToString() + (Style?.ToString() ?? "");
|
string key = "BRUSH" + PenBrush.GetHashCode().ToString() + PenThickness.ToString() + GetDashName(Style);
|
||||||
|
|
||||||
if (!_pens.ContainsKey(key))
|
if (!_pens.ContainsKey(key))
|
||||||
{
|
{
|
||||||
|
@ -50,5 +50,10 @@ namespace LogicAnalyzer.Classes
|
||||||
|
|
||||||
return _pens[key];
|
return _pens[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static string GetDashName(IDashStyle Style)
|
||||||
|
{
|
||||||
|
return Style == null ? "" : string.Join("", Style.Dashes) + "-" + Style.Offset.ToString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ namespace LogicAnalyzer.Classes
|
||||||
{
|
{
|
||||||
public int FirstSample { get; set; }
|
public int FirstSample { get; set; }
|
||||||
public int LastSample { get; set; }
|
public int LastSample { get; set; }
|
||||||
public int SampleCount { get { return LastSample - FirstSample; } }
|
public int SampleCount { get { return Math.Abs(LastSample - FirstSample); } }
|
||||||
public string RegionName { get; set; } = "";
|
public string RegionName { get; set; } = "";
|
||||||
public Color RegionColor { get; set; } = Color.FromArgb(128, 255,255,255);
|
public Color RegionColor { get; set; } = Color.FromArgb(128, 255,255,255);
|
||||||
|
|
||||||
|
|
|
@ -123,4 +123,15 @@ namespace LogicAnalyzer.Controls
|
||||||
{
|
{
|
||||||
public SelectedSampleRegion? Region { get; set; }
|
public SelectedSampleRegion? Region { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SamplesEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public int FirstSample { get; set; }
|
||||||
|
public int SampleCount { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class UserMarkerEventArgs : EventArgs
|
||||||
|
{
|
||||||
|
public int Position { get; set; }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,12 @@
|
||||||
<TextBlock Margin="0,0,0,0" Name="lblLeft" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
|
<TextBlock Margin="0,0,0,0" Name="lblLeft" VerticalAlignment="Center" HorizontalAlignment="Left"></TextBlock>
|
||||||
<TextBlock Name="lblCenter" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
|
<TextBlock Name="lblCenter" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
|
||||||
<TextBlock Margin="0,0,0,0" Name="lblRight" VerticalAlignment="Center" HorizontalAlignment="Right"></TextBlock>
|
<TextBlock Margin="0,0,0,0" Name="lblRight" VerticalAlignment="Center" HorizontalAlignment="Right"></TextBlock>
|
||||||
|
|
||||||
|
<Panel.ContextMenu>
|
||||||
|
<ContextMenu Name="rgnDeleteMenu">
|
||||||
|
<MenuItem Header="Delete regions" Name="mnuDeleteRegions" />
|
||||||
|
<MenuItem Header="Delete regions and samples" Name="mnuDeleteRegionsSamples" />
|
||||||
|
</ContextMenu>
|
||||||
|
</Panel.ContextMenu>
|
||||||
</Panel>
|
</Panel>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|
|
@ -50,14 +50,59 @@ namespace LogicAnalyzer.Controls
|
||||||
public event EventHandler<RegionEventArgs> RegionCreated;
|
public event EventHandler<RegionEventArgs> RegionCreated;
|
||||||
public event EventHandler<RegionEventArgs> RegionDeleted;
|
public event EventHandler<RegionEventArgs> RegionDeleted;
|
||||||
|
|
||||||
|
public event EventHandler<SamplesEventArgs> SamplesDeleted;
|
||||||
|
public event EventHandler<UserMarkerEventArgs> UserMarkerSelected;
|
||||||
|
|
||||||
List<SelectedSampleRegion> regions = new List<SelectedSampleRegion>();
|
List<SelectedSampleRegion> regions = new List<SelectedSampleRegion>();
|
||||||
|
|
||||||
SelectedSampleRegion? regionUnderConstruction;
|
SelectedSampleRegion? regionUnderConstruction;
|
||||||
|
SelectedSampleRegion[] regionsToDelete = null;
|
||||||
|
|
||||||
|
int? userMarker = null;
|
||||||
public SelectedSampleRegion[] SelectedRegions { get { return regions.ToArray(); } }
|
public SelectedSampleRegion[] SelectedRegions { get { return regions.ToArray(); } }
|
||||||
|
|
||||||
public SampleMarker()
|
public SampleMarker()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
mnuDeleteRegions.Click += MnuDeleteRegions_Click;
|
||||||
|
mnuDeleteRegionsSamples.Click += MnuDeleteRegionsSamples_Click;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MnuDeleteRegionsSamples_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var minDelete = regionsToDelete.Select(r => Math.Min(r.FirstSample, r.LastSample)).Min();
|
||||||
|
var maxDelete = regionsToDelete.Select(r => Math.Max(r.LastSample, r.FirstSample)).Max();
|
||||||
|
|
||||||
|
int len = maxDelete - minDelete;
|
||||||
|
|
||||||
|
if (RegionDeleted != null)
|
||||||
|
{
|
||||||
|
foreach (var region in regionsToDelete)
|
||||||
|
{
|
||||||
|
RegionDeleted(this, new RegionEventArgs { Region = region });
|
||||||
|
RemoveRegion(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SamplesDeleted != null)
|
||||||
|
SamplesDeleted(this, new SamplesEventArgs { FirstSample = minDelete, SampleCount = len });
|
||||||
|
}
|
||||||
|
|
||||||
|
private void MnuDeleteRegions_Click(object? sender, Avalonia.Interactivity.RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
var minDelete = regionsToDelete.Select(r => Math.Min(r.FirstSample, r.LastSample)).Min();
|
||||||
|
var maxDelete = regionsToDelete.Select(r => Math.Max(r.LastSample, r.FirstSample)).Max();
|
||||||
|
|
||||||
|
int len = maxDelete - minDelete;
|
||||||
|
|
||||||
|
if (RegionDeleted != null)
|
||||||
|
{
|
||||||
|
foreach (var region in regionsToDelete)
|
||||||
|
{
|
||||||
|
RegionDeleted(this, new RegionEventArgs { Region = region });
|
||||||
|
RemoveRegion(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(SelectedSampleRegion Region)
|
public void AddRegion(SelectedSampleRegion Region)
|
||||||
|
@ -111,8 +156,8 @@ namespace LogicAnalyzer.Controls
|
||||||
|
|
||||||
if (regionUnderConstruction != null)
|
if (regionUnderConstruction != null)
|
||||||
{
|
{
|
||||||
|
int first = Math.Min(regionUnderConstruction.FirstSample, regionUnderConstruction.LastSample);
|
||||||
double start = (regionUnderConstruction.FirstSample - FirstSample) * sampleWidth;
|
double start = (first - FirstSample) * sampleWidth;
|
||||||
double end = sampleWidth * regionUnderConstruction.SampleCount;
|
double end = sampleWidth * regionUnderConstruction.SampleCount;
|
||||||
context.FillRectangle(GraphicObjectsCache.GetBrush(regionUnderConstruction.RegionColor), new Rect(start, 0, end, this.Bounds.Height));
|
context.FillRectangle(GraphicObjectsCache.GetBrush(regionUnderConstruction.RegionColor), new Rect(start, 0, end, this.Bounds.Height));
|
||||||
|
|
||||||
|
@ -122,7 +167,8 @@ namespace LogicAnalyzer.Controls
|
||||||
{
|
{
|
||||||
foreach (var region in regions)
|
foreach (var region in regions)
|
||||||
{
|
{
|
||||||
double start = (region.FirstSample - FirstSample) * sampleWidth;
|
int first = Math.Min(region.FirstSample, region.LastSample);
|
||||||
|
double start = (first - FirstSample) * sampleWidth;
|
||||||
double end = sampleWidth * region.SampleCount;
|
double end = sampleWidth * region.SampleCount;
|
||||||
context.FillRectangle(GraphicObjectsCache.GetBrush(region.RegionColor), new Rect(start, 0, end, this.Bounds.Height));
|
context.FillRectangle(GraphicObjectsCache.GetBrush(region.RegionColor), new Rect(start, 0, end, this.Bounds.Height));
|
||||||
FormattedText text = new FormattedText(region.RegionName, Typeface.Default, 12, TextAlignment.Left, TextWrapping.NoWrap, Size.Infinity);
|
FormattedText text = new FormattedText(region.RegionName, Typeface.Default, 12, TextAlignment.Left, TextWrapping.NoWrap, Size.Infinity);
|
||||||
|
@ -138,6 +184,11 @@ namespace LogicAnalyzer.Controls
|
||||||
double y2 = this.Bounds.Height;
|
double y2 = this.Bounds.Height;
|
||||||
|
|
||||||
context.DrawLine(GraphicObjectsCache.GetPen(Foreground, 1), new Point(x, y1), new Point(x, y2));
|
context.DrawLine(GraphicObjectsCache.GetPen(Foreground, 1), new Point(x, y1), new Point(x, y2));
|
||||||
|
|
||||||
|
x = buc * sampleWidth;
|
||||||
|
y1 = halfHeight * 1.75f;
|
||||||
|
|
||||||
|
context.DrawLine(GraphicObjectsCache.GetPen(Foreground, 1), new Point(x, y1), new Point(x, y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
base.Render(context);
|
base.Render(context);
|
||||||
|
@ -191,7 +242,7 @@ namespace LogicAnalyzer.Controls
|
||||||
|
|
||||||
int ovrSample = (int)(pos.Position.X / sampleWidth) + FirstSample;
|
int ovrSample = (int)(pos.Position.X / sampleWidth) + FirstSample;
|
||||||
|
|
||||||
regionUnderConstruction = new SelectedSampleRegion { FirstSample = ovrSample, LastSample = ovrSample + 1 };
|
regionUnderConstruction = new SelectedSampleRegion { FirstSample = ovrSample, LastSample = ovrSample };
|
||||||
this.InvalidateVisual();
|
this.InvalidateVisual();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -229,12 +280,48 @@ namespace LogicAnalyzer.Controls
|
||||||
double sampleWidth = this.Bounds.Width / (float)VisibleSamples;
|
double sampleWidth = this.Bounds.Width / (float)VisibleSamples;
|
||||||
int ovrSample = (int)(pos.Position.X / sampleWidth) + FirstSample;
|
int ovrSample = (int)(pos.Position.X / sampleWidth) + FirstSample;
|
||||||
regionUnderConstruction.LastSample = ovrSample + 1;
|
regionUnderConstruction.LastSample = ovrSample + 1;
|
||||||
|
|
||||||
|
if (regionUnderConstruction.LastSample < regionUnderConstruction.FirstSample)
|
||||||
|
{
|
||||||
|
int val = regionUnderConstruction.FirstSample;
|
||||||
|
regionUnderConstruction.FirstSample = regionUnderConstruction.LastSample;
|
||||||
|
regionUnderConstruction.LastSample = val;
|
||||||
|
}
|
||||||
|
|
||||||
var rgn = regionUnderConstruction;
|
var rgn = regionUnderConstruction;
|
||||||
regionUnderConstruction = null;
|
regionUnderConstruction = null;
|
||||||
|
|
||||||
if (rgn.SampleCount > 0)
|
if (rgn.SampleCount > 0)
|
||||||
{
|
{
|
||||||
ShowDialog(rgn);
|
if (rgn.SampleCount == 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(userMarker != null && userMarker == rgn.FirstSample)
|
||||||
|
userMarker = null;
|
||||||
|
|
||||||
|
if (e.InputModifiers.HasFlag(InputModifiers.Shift) && userMarker != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (this.UserMarkerSelected != null)
|
||||||
|
this.UserMarkerSelected(this, new UserMarkerEventArgs { Position = userMarker.Value });
|
||||||
|
|
||||||
|
rgn.FirstSample = userMarker.Value;
|
||||||
|
|
||||||
|
userMarker = null;
|
||||||
|
|
||||||
|
ShowDialog(rgn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
userMarker = rgn.FirstSample;
|
||||||
|
|
||||||
|
if (this.UserMarkerSelected != null)
|
||||||
|
this.UserMarkerSelected(this, new UserMarkerEventArgs { Position = rgn.FirstSample });
|
||||||
|
|
||||||
|
this.InvalidateVisual();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ShowDialog(rgn);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -245,18 +332,26 @@ namespace LogicAnalyzer.Controls
|
||||||
double sampleWidth = this.Bounds.Width / (float)VisibleSamples;
|
double sampleWidth = this.Bounds.Width / (float)VisibleSamples;
|
||||||
int ovrSample = (int)(pos.Position.X / sampleWidth) + FirstSample;
|
int ovrSample = (int)(pos.Position.X / sampleWidth) + FirstSample;
|
||||||
|
|
||||||
var toDelete = regions.Where(r => ovrSample >= r.FirstSample && ovrSample < r.LastSample).ToArray();
|
var toDelete = regions.Where(r => ovrSample >= Math.Min(r.FirstSample , r.LastSample) && ovrSample < Math.Max(r.FirstSample, r.LastSample)).ToArray();
|
||||||
|
|
||||||
foreach (var region in toDelete)
|
if (toDelete != null && toDelete.Length > 0)
|
||||||
{
|
{
|
||||||
if (ovrSample >= region.FirstSample && ovrSample < region.LastSample)
|
regionsToDelete= toDelete;
|
||||||
{
|
rgnDeleteMenu.PlacementRect = new Rect(pos.Position.X, pos.Position.Y, 1, 1);
|
||||||
if (RegionDeleted != null)
|
rgnDeleteMenu.Open();
|
||||||
RegionDeleted(this, new RegionEventArgs { Region = region });
|
|
||||||
|
|
||||||
RemoveRegion(region);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//foreach (var region in toDelete)
|
||||||
|
//{
|
||||||
|
// if (ovrSample >= region.FirstSample && ovrSample < region.LastSample)
|
||||||
|
// {
|
||||||
|
|
||||||
|
// if (RegionDeleted != null)
|
||||||
|
// RegionDeleted(this, new RegionEventArgs { Region = region });
|
||||||
|
|
||||||
|
// RemoveRegion(region);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ namespace LogicAnalyzer.Controls
|
||||||
public int SamplesInScreen { get; set; }
|
public int SamplesInScreen { get; set; }
|
||||||
public int FirstSample { get; set; }
|
public int FirstSample { get; set; }
|
||||||
|
|
||||||
|
public int? UserMarker { get; set; }
|
||||||
|
|
||||||
bool updating = false;
|
bool updating = false;
|
||||||
|
|
||||||
List<SelectedSampleRegion> regions = new List<SelectedSampleRegion>();
|
List<SelectedSampleRegion> regions = new List<SelectedSampleRegion>();
|
||||||
|
@ -26,8 +28,11 @@ namespace LogicAnalyzer.Controls
|
||||||
public SelectedSampleRegion[] SelectedRegions { get { return regions.ToArray(); } }
|
public SelectedSampleRegion[] SelectedRegions { get { return regions.ToArray(); } }
|
||||||
|
|
||||||
List<ProtocolAnalyzedChannel> analysisData = new List<ProtocolAnalyzedChannel>();
|
List<ProtocolAnalyzedChannel> analysisData = new List<ProtocolAnalyzedChannel>();
|
||||||
Color sampleLineColor = Color.FromArgb(80,120,120,120);
|
Color sampleLineColor = Color.FromArgb(80, 120, 120, 120);
|
||||||
Color triggerLineColor = Colors.White;
|
Color triggerLineColor = Colors.White;
|
||||||
|
Color userLineColor = Colors.Cyan;
|
||||||
|
DashStyle halfDash = new DashStyle(new double[] { 1, 8 }, 0);
|
||||||
|
DashStyle fullDash = new DashStyle(new double[] { 4, 5 }, 0);
|
||||||
public SampleViewer()
|
public SampleViewer()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
@ -107,7 +112,8 @@ namespace LogicAnalyzer.Controls
|
||||||
{
|
{
|
||||||
foreach (var region in regions)
|
foreach (var region in regions)
|
||||||
{
|
{
|
||||||
double start = (region.FirstSample - FirstSample) * sampleWidth;
|
int first = Math.Min(region.FirstSample, region.LastSample);
|
||||||
|
double start = (first - FirstSample) * sampleWidth;
|
||||||
double end = sampleWidth * region.SampleCount;
|
double end = sampleWidth * region.SampleCount;
|
||||||
context.FillRectangle(GraphicObjectsCache.GetBrush(region.RegionColor), new Rect(start, 0, end, this.Bounds.Height));
|
context.FillRectangle(GraphicObjectsCache.GetBrush(region.RegionColor), new Rect(start, 0, end, this.Bounds.Height));
|
||||||
}
|
}
|
||||||
|
@ -120,11 +126,16 @@ namespace LogicAnalyzer.Controls
|
||||||
uint prevSample = buc == 0 ? 0 : Samples[buc - 1];
|
uint prevSample = buc == 0 ? 0 : Samples[buc - 1];
|
||||||
double lineX = (buc - FirstSample) * sampleWidth;
|
double lineX = (buc - FirstSample) * sampleWidth;
|
||||||
|
|
||||||
context.DrawLine(GraphicObjectsCache.GetPen(sampleLineColor, 1, DashStyle.Dash), new Point(lineX + sampleWidth / 2, 0), new Point(lineX + sampleWidth / 2, thisBounds.Height));
|
context.DrawLine(GraphicObjectsCache.GetPen(sampleLineColor, 1, fullDash), new Point(lineX + sampleWidth / 2, 0), new Point(lineX + sampleWidth / 2, thisBounds.Height));
|
||||||
|
|
||||||
|
context.DrawLine(GraphicObjectsCache.GetPen(sampleLineColor, 1, halfDash), new Point(lineX, 0), new Point(lineX, thisBounds.Height));
|
||||||
|
|
||||||
if (buc == PreSamples)
|
if (buc == PreSamples)
|
||||||
context.DrawLine(GraphicObjectsCache.GetPen(triggerLineColor, 2), new Point(lineX, 0), new Point(lineX, thisBounds.Height));
|
context.DrawLine(GraphicObjectsCache.GetPen(triggerLineColor, 2), new Point(lineX, 0), new Point(lineX, thisBounds.Height));
|
||||||
|
|
||||||
|
if(UserMarker != null && UserMarker == buc)
|
||||||
|
context.DrawLine(GraphicObjectsCache.GetPen(userLineColor, 2, DashStyle.DashDot), new Point(lineX, 0), new Point(lineX, thisBounds.Height));
|
||||||
|
|
||||||
for (int chan = 0; chan < ChannelCount; chan++)
|
for (int chan = 0; chan < ChannelCount; chan++)
|
||||||
{
|
{
|
||||||
double lineY;
|
double lineY;
|
||||||
|
|
|
@ -27,11 +27,11 @@
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
|
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
|
||||||
<TextBlock VerticalAlignment="Center" Margin="0,0,5,0">Pre samples:</TextBlock>
|
<TextBlock VerticalAlignment="Center" Margin="0,0,5,0">Pre samples:</TextBlock>
|
||||||
<NumericUpDown Width="130" Height="35" Value="512" Minimum="0" Maximum="32767" Name="nudPreSamples"></NumericUpDown>
|
<NumericUpDown Width="130" Height="35" Value="512" Minimum="2" Maximum="31743" Name="nudPreSamples"></NumericUpDown>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right">
|
<StackPanel Grid.Column="2" Orientation="Horizontal" HorizontalAlignment="Right">
|
||||||
<TextBlock VerticalAlignment="Center" Margin="0,0,5,0">Post samples:</TextBlock>
|
<TextBlock VerticalAlignment="Center" Margin="0,0,5,0">Post samples:</TextBlock>
|
||||||
<NumericUpDown Width="130" Height="35" Value="1024" Minimum="0" Maximum="32767" Name="nudPostSamples"></NumericUpDown>
|
<NumericUpDown Width="130" Height="35" Value="1024" Minimum="512" Maximum="32767" Name="nudPostSamples"></NumericUpDown>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Grid Grid.Row="1" RowDefinitions="2*,5*">
|
<Grid Grid.Row="1" RowDefinitions="2*,5*">
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace LogicAnalyzer
|
||||||
btnAbort.Click += btnAbort_Click;
|
btnAbort.Click += btnAbort_Click;
|
||||||
sampleMarker.RegionCreated += sampleMarker_RegionCreated;
|
sampleMarker.RegionCreated += sampleMarker_RegionCreated;
|
||||||
sampleMarker.RegionDeleted += sampleMarker_RegionDeleted;
|
sampleMarker.RegionDeleted += sampleMarker_RegionDeleted;
|
||||||
|
sampleMarker.UserMarkerSelected += sampleMarker_UserMarkerSelected;
|
||||||
|
sampleMarker.SamplesDeleted += SampleMarker_SamplesDeleted;
|
||||||
tkInScreen.PropertyChanged += tkInScreen_ValueChanged;
|
tkInScreen.PropertyChanged += tkInScreen_ValueChanged;
|
||||||
scrSamplePos.Scroll += scrSamplePos_ValueChanged;
|
scrSamplePos.Scroll += scrSamplePos_ValueChanged;
|
||||||
mnuOpen.Click += mnuOpen_Click;
|
mnuOpen.Click += mnuOpen_Click;
|
||||||
|
@ -50,6 +52,124 @@ namespace LogicAnalyzer
|
||||||
RefreshPorts();
|
RefreshPorts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async void SampleMarker_SamplesDeleted(object? sender, SamplesEventArgs e)
|
||||||
|
{
|
||||||
|
var lastSample = e.FirstSample + e.SampleCount - 1;
|
||||||
|
var triggerSample = sampleViewer.PreSamples - 1;
|
||||||
|
|
||||||
|
var containsTrigger = e.FirstSample <= triggerSample && lastSample >= triggerSample;
|
||||||
|
|
||||||
|
if(containsTrigger)
|
||||||
|
{
|
||||||
|
await ShowError("Error", "Cannot delete the trigger sample.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var preDelete = sampleViewer.Samples.Take(e.FirstSample);
|
||||||
|
var postDelete = sampleViewer.Samples.Skip(e.FirstSample + e.SampleCount);
|
||||||
|
|
||||||
|
var finalSamples = preDelete.Concat(postDelete).ToArray();
|
||||||
|
|
||||||
|
var finalPreSamples = e.FirstSample > triggerSample ? sampleViewer.PreSamples : sampleViewer.PreSamples - e.SampleCount;
|
||||||
|
|
||||||
|
var regions = sampleViewer.SelectedRegions;
|
||||||
|
List<SelectedSampleRegion> finalRegions = new List<SelectedSampleRegion>();
|
||||||
|
|
||||||
|
foreach(var region in regions)
|
||||||
|
{
|
||||||
|
int minRegion = Math.Min(region.FirstSample, region.LastSample);
|
||||||
|
int maxRegion = Math.Max(region.FirstSample, region.LastSample);
|
||||||
|
|
||||||
|
if (minRegion >= e.FirstSample && maxRegion <= lastSample) //removed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (maxRegion <= e.FirstSample && maxRegion <= lastSample) //Region before delete, do not modify
|
||||||
|
{
|
||||||
|
finalRegions.Add(region);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (minRegion >= e.FirstSample && minRegion >= lastSample) //Region after delete, offset n samples
|
||||||
|
{
|
||||||
|
region.FirstSample -= e.SampleCount;
|
||||||
|
region.LastSample -= e.SampleCount;
|
||||||
|
finalRegions.Add(region);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (minRegion >= e.FirstSample && maxRegion > lastSample) //Begin of region cropped
|
||||||
|
{
|
||||||
|
region.FirstSample = lastSample + 1;
|
||||||
|
region.LastSample = maxRegion;
|
||||||
|
|
||||||
|
if (region.LastSample - region.FirstSample < 1) //Regions smaller than 2 samples are removed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
region.FirstSample -= e.SampleCount;
|
||||||
|
region.LastSample -= e.SampleCount;
|
||||||
|
finalRegions.Add(region);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (minRegion < e.FirstSample && maxRegion <= lastSample) //End of region cropped
|
||||||
|
{
|
||||||
|
region.FirstSample = minRegion;
|
||||||
|
region.LastSample = e.FirstSample;
|
||||||
|
|
||||||
|
if (region.LastSample - region.FirstSample < 1) //Regions smaller than 2 samples are removed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
finalRegions.Add(region);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else //Deleted samples are inside region (not possible, just left for sanity)
|
||||||
|
{
|
||||||
|
region.LastSample -= e.SampleCount;
|
||||||
|
|
||||||
|
if (region.LastSample - region.FirstSample < 1) //Regions smaller than 2 samples are removed
|
||||||
|
continue;
|
||||||
|
|
||||||
|
finalRegions.Add(region);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sampleViewer.BeginUpdate();
|
||||||
|
sampleViewer.Samples = finalSamples;
|
||||||
|
sampleViewer.PreSamples = finalPreSamples;
|
||||||
|
sampleViewer.SamplesInScreen = Math.Min(100, finalSamples.Length / 10);
|
||||||
|
|
||||||
|
if(sampleViewer.FirstSample > finalSamples.Length - 1)
|
||||||
|
sampleViewer.FirstSample = finalSamples.Length - 1;
|
||||||
|
|
||||||
|
sampleViewer.ClearRegions();
|
||||||
|
sampleViewer.ClearAnalyzedChannels();
|
||||||
|
|
||||||
|
if (finalRegions.Count > 0)
|
||||||
|
sampleViewer.AddRegions(finalRegions);
|
||||||
|
|
||||||
|
sampleViewer.EndUpdate();
|
||||||
|
|
||||||
|
sampleMarker.VisibleSamples = sampleViewer.SamplesInScreen;
|
||||||
|
sampleMarker.FirstSample = sampleViewer.FirstSample;
|
||||||
|
sampleMarker.ClearRegions();
|
||||||
|
|
||||||
|
if (finalRegions.Count > 0)
|
||||||
|
sampleMarker.AddRegions(finalRegions);
|
||||||
|
|
||||||
|
scrSamplePos.Maximum = finalSamples.Length - 1;
|
||||||
|
scrSamplePos.Value = e.FirstSample - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sampleMarker_UserMarkerSelected(object? sender, UserMarkerEventArgs e)
|
||||||
|
{
|
||||||
|
sampleViewer.BeginUpdate();
|
||||||
|
|
||||||
|
if (sampleViewer.UserMarker != null && sampleViewer.UserMarker == e.Position)
|
||||||
|
sampleViewer.UserMarker = null;
|
||||||
|
else
|
||||||
|
sampleViewer.UserMarker = e.Position;
|
||||||
|
|
||||||
|
sampleViewer.EndUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void OnOpened(EventArgs e)
|
protected override void OnOpened(EventArgs e)
|
||||||
{
|
{
|
||||||
base.OnOpened(e);
|
base.OnOpened(e);
|
||||||
|
@ -320,26 +440,41 @@ namespace LogicAnalyzer
|
||||||
|
|
||||||
if (settings.TriggerType != 0)
|
if (settings.TriggerType != 0)
|
||||||
{
|
{
|
||||||
if (!driver.StartPatternCapture(settings.Frequency, settings.PreTriggerSamples, settings.PostTriggerSamples, settings.CaptureChannels, settings.TriggerChannel, settings.TriggerBitCount, settings.TriggerPattern, settings.TriggerType == 2 ? true : false))
|
var error = driver.StartPatternCapture(settings.Frequency, settings.PreTriggerSamples, settings.PostTriggerSamples, settings.CaptureChannels, settings.TriggerChannel, settings.TriggerBitCount, settings.TriggerPattern, settings.TriggerType == 2 ? true : false);
|
||||||
{
|
|
||||||
await ShowError("Error", "Device reported error starting capture. Restart the device and try again.");
|
if(error != CaptureError.None)
|
||||||
return;
|
await ShowError(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!driver.StartCapture(settings.Frequency, settings.PreTriggerSamples, settings.PostTriggerSamples, settings.CaptureChannels, settings.TriggerChannel, settings.TriggerInverted))
|
var error = driver.StartCapture(settings.Frequency, settings.PreTriggerSamples, settings.PostTriggerSamples, settings.CaptureChannels, settings.TriggerChannel, settings.TriggerInverted);
|
||||||
{
|
|
||||||
await ShowError("Error", "Device reported error starting capture. Restart the device and try again.");
|
if (error != CaptureError.None)
|
||||||
return;
|
await ShowError(error);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
btnCapture.IsEnabled = false;
|
btnCapture.IsEnabled = false;
|
||||||
btnRepeat.IsEnabled = false;
|
btnRepeat.IsEnabled = false;
|
||||||
btnOpenClose.IsEnabled = false;
|
btnOpenClose.IsEnabled = false;
|
||||||
btnAbort.IsEnabled = true;
|
btnAbort.IsEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task ShowError(CaptureError error)
|
||||||
|
{
|
||||||
|
switch (error)
|
||||||
|
{
|
||||||
|
case CaptureError.Busy:
|
||||||
|
await ShowError("Error", "Device is busy, stop the capture before starting a new one.");
|
||||||
|
return;
|
||||||
|
case CaptureError.BadParams:
|
||||||
|
await ShowError("Error", "Specified parameters are incorrect.\r\n\r\n -Frequency must be between 3.1Khz and 100Mhz\r\n -PreSamples must be between 2 and 31743\r\n -PostSamples must be between 512 and 32767\r\n -Total samples cannot exceed 32767");
|
||||||
|
return;
|
||||||
|
case CaptureError.HardwareError:
|
||||||
|
await ShowError("Error", "Device reported error starting capture. Restart the device and try again.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void scrSamplePos_ValueChanged(object? sender, ScrollEventArgs e)
|
private void scrSamplePos_ValueChanged(object? sender, ScrollEventArgs e)
|
||||||
{
|
{
|
||||||
if (sampleViewer.Samples != null)
|
if (sampleViewer.Samples != null)
|
||||||
|
|
|
@ -45,14 +45,14 @@ namespace SharedDriver
|
||||||
baseStream.ReadTimeout = Timeout.Infinite;
|
baseStream.ReadTimeout = Timeout.Infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StartCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, bool TriggerInverted, Action<CaptureEventArgs>? CaptureCompletedHandler = null)
|
public CaptureError StartCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, bool TriggerInverted, Action<CaptureEventArgs>? CaptureCompletedHandler = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (capturing)
|
if (capturing)
|
||||||
return false;
|
return CaptureError.Busy;
|
||||||
|
|
||||||
if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (16 * 1024) || (PreSamples + PostSamples) >= (32 * 1024) || Frequency > 100000000)
|
if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (30 * 1024 - 1) || PostSamples < 512 || (PreSamples + PostSamples) >= (32 * 1024) || Frequency < 3100 || Frequency > 100000000)
|
||||||
return false;
|
return CaptureError.BadParams;
|
||||||
|
|
||||||
channelCount = Channels.Length;
|
channelCount = Channels.Length;
|
||||||
triggerChannel = Array.IndexOf(Channels, TriggerChannel);
|
triggerChannel = Array.IndexOf(Channels, TriggerChannel);
|
||||||
|
@ -89,18 +89,18 @@ namespace SharedDriver
|
||||||
{
|
{
|
||||||
capturing = true;
|
capturing = true;
|
||||||
Task.Run(() => ReadCapture(PreSamples + PostSamples));
|
Task.Run(() => ReadCapture(PreSamples + PostSamples));
|
||||||
return true;
|
return CaptureError.None;
|
||||||
}
|
}
|
||||||
return false;
|
return CaptureError.HardwareError;
|
||||||
}
|
}
|
||||||
public bool StartPatternCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, int TriggerBitCount, UInt16 TriggerPattern, bool Fast, Action<CaptureEventArgs>? CaptureCompletedHandler = null)
|
public CaptureError StartPatternCapture(int Frequency, int PreSamples, int PostSamples, int[] Channels, int TriggerChannel, int TriggerBitCount, UInt16 TriggerPattern, bool Fast, Action<CaptureEventArgs>? CaptureCompletedHandler = null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (capturing)
|
if (capturing)
|
||||||
return false;
|
return CaptureError.Busy;
|
||||||
|
|
||||||
if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (16 * 1024) || (PreSamples + PostSamples) >= (32 * 1024) || Frequency > 100000000)
|
if (Channels == null || Channels.Length == 0 || PreSamples < 2 || PreSamples > (30 * 1024 - 1) || PostSamples < 512 || (PreSamples + PostSamples) >= (32 * 1024) || Frequency < 3100 || Frequency > 100000000)
|
||||||
return false;
|
return CaptureError.BadParams;
|
||||||
|
|
||||||
channelCount = Channels.Length;
|
channelCount = Channels.Length;
|
||||||
triggerChannel = Array.IndexOf(Channels, TriggerChannel);
|
triggerChannel = Array.IndexOf(Channels, TriggerChannel);
|
||||||
|
@ -138,9 +138,9 @@ namespace SharedDriver
|
||||||
{
|
{
|
||||||
capturing = true;
|
capturing = true;
|
||||||
Task.Run(() => ReadCapture(PreSamples + PostSamples));
|
Task.Run(() => ReadCapture(PreSamples + PostSamples));
|
||||||
return true;
|
return CaptureError.None;
|
||||||
}
|
}
|
||||||
return false;
|
return CaptureError.HardwareError;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool StopCapture()
|
public bool StopCapture()
|
||||||
|
@ -321,6 +321,14 @@ namespace SharedDriver
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum CaptureError
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Busy,
|
||||||
|
BadParams,
|
||||||
|
HardwareError
|
||||||
|
}
|
||||||
|
|
||||||
public class CaptureEventArgs : EventArgs
|
public class CaptureEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public int TriggerChannel { get; set; }
|
public int TriggerChannel { get; set; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user