Updated applications

This commit is contained in:
Agustín Gimenez 2023-01-29 16:59:57 +01:00
parent 2816c8be90
commit bf29561d91
23 changed files with 354 additions and 49 deletions

View File

@ -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...");
} }

View File

@ -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
{ {

View File

@ -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();
}
} }
} }

View File

@ -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);

View File

@ -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; }
}
} }

View File

@ -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>

View File

@ -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,11 +280,47 @@ 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)
{ {
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); ShowDialog(rgn);
} }
@ -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);
// }
//}
} }
} }
} }

View File

@ -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>();
@ -28,6 +30,9 @@ namespace LogicAnalyzer.Controls
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;

View File

@ -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*">

View File

@ -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)

View File

@ -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; }