Skip to content

Commit e094e02

Browse files
committed
Trigger interpolation
1 parent fd82bfc commit e094e02

6 files changed

Lines changed: 41 additions & 12 deletions

File tree

source/TS.NET.Engine/Servers/DataServer.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,10 +139,27 @@ protected override void OnReceived(byte[] buffer, long offset, long size)
139139
for (byte channelIndex = 0; channelIndex < processing.CurrentChannelCount; channelIndex++)
140140
{
141141
ThunderscopeChannel thunderscopeChannel = configuration.Channels[channelIndex];
142-
143142
chHeader.chNum = channelIndex;
144143
chHeader.scale = (float)(thunderscopeChannel.ActualVoltFullScale / 255.0);
145144
chHeader.offset = (float)thunderscopeChannel.VoltOffset;
145+
// If this is the trigger channel and the data is triggered, then run trigger interpolation and set trigphase value
146+
if ((((int)bridge.Processing.TriggerChannel) - 1) == channelIndex && bridge.Triggered)
147+
{
148+
var signedData = bridge.AcquiredRegionI8;
149+
// Get the trigger index. If it's greater than 0, then do trigger interpolation.
150+
int index = (int)(bridge.Processing.TriggerDelayFs / femtosecondsPerSample);
151+
if (index > 0)
152+
{
153+
float fa = (chHeader.scale * signedData[index - 1]) - chHeader.offset;
154+
float fb = (chHeader.scale * signedData[index]) - chHeader.offset;
155+
float triggerLevel = (chHeader.scale * bridge.Processing.TriggerLevel) + chHeader.offset;
156+
float slope = fb - fa;
157+
float delta = triggerLevel - fa;
158+
float trigphase = delta / slope;
159+
chHeader.trigphase = femtosecondsPerSample * (1 - trigphase);
160+
//logger.LogTrace("Trigger phase: {0:F6}, first {1}, second {2}", chHeader.trigphase, fa, fb);
161+
}
162+
}
146163

147164
Send(new ReadOnlySpan<byte>(&chHeader, sizeof(ChannelHeader)));
148165
bytesSent += (ulong)sizeof(ChannelHeader);

source/TS.NET.Engine/Tasks/ProcessingThread.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ private static void Loop(
327327
var bridgeSpan = bridge.AcquiringRegionI8;
328328
uint endOffset = (uint)triggerChannelBuffer.Length - captureEndIndices[i];
329329
circularBuffer1.Read(bridgeSpan.Slice(0, channelLength), endOffset);
330-
bridge.DataWritten();
330+
bridge.DataWritten(triggered: true);
331331
bridge.SwitchRegionIfNeeded();
332332

333333
if (singleTriggerLatch) // If this was a single trigger, reset the singleTrigger & runTrigger latches
@@ -345,7 +345,7 @@ private static void Loop(
345345
{
346346
var bridgeSpan = bridge.AcquiringRegionI8;
347347
circularBuffer1.Read(bridgeSpan.Slice(0, channelLength), 0);
348-
bridge.DataWritten();
348+
bridge.DataWritten(triggered: false);
349349
bridge.SwitchRegionIfNeeded();
350350
forceTriggerLatch = false;
351351

@@ -405,7 +405,7 @@ private static void Loop(
405405
uint endOffset = (uint)triggerChannelBuffer.Length - captureEndIndices[i];
406406
circularBuffer1.Read(bridgeSpan.Slice(0, channelLength), endOffset);
407407
circularBuffer2.Read(bridgeSpan.Slice(channelLength, channelLength), endOffset);
408-
bridge.DataWritten();
408+
bridge.DataWritten(triggered: true);
409409
bridge.SwitchRegionIfNeeded();
410410

411411
if (singleTriggerLatch) // If this was a single trigger, reset the singleTrigger & runTrigger latches
@@ -424,7 +424,7 @@ private static void Loop(
424424
var bridgeSpan = bridge.AcquiringRegionI8;
425425
circularBuffer1.Read(bridgeSpan.Slice(0, channelLength), 0);
426426
circularBuffer2.Read(bridgeSpan.Slice(channelLength, channelLength), 0);
427-
bridge.DataWritten();
427+
bridge.DataWritten(triggered: false);
428428
bridge.SwitchRegionIfNeeded();
429429
forceTriggerLatch = false;
430430

@@ -493,7 +493,7 @@ private static void Loop(
493493
circularBuffer2.Read(bridgeSpan.Slice(channelLength, channelLength), endOffset);
494494
circularBuffer3.Read(bridgeSpan.Slice(channelLength + channelLength, channelLength), endOffset);
495495
circularBuffer4.Read(bridgeSpan.Slice(channelLength + channelLength + channelLength, channelLength), endOffset);
496-
bridge.DataWritten();
496+
bridge.DataWritten(triggered: true);
497497
bridge.SwitchRegionIfNeeded();
498498

499499
if (singleTriggerLatch) // If this was a single trigger, reset the singleTrigger & runTrigger latches
@@ -514,7 +514,7 @@ private static void Loop(
514514
circularBuffer2.Read(bridgeSpan.Slice(channelLength, channelLength), 0);
515515
circularBuffer3.Read(bridgeSpan.Slice(channelLength + channelLength, channelLength), 0);
516516
circularBuffer4.Read(bridgeSpan.Slice(channelLength + channelLength + channelLength, channelLength), 0);
517-
bridge.DataWritten();
517+
bridge.DataWritten(triggered: false);
518518
bridge.SwitchRegionIfNeeded();
519519
forceTriggerLatch = false;
520520

@@ -575,7 +575,7 @@ void SingleChannelStream(int channelLength)
575575
streamSampleCounter -= channelLength;
576576
var bridgeSpan = bridge.AcquiringRegionI8;
577577
circularBuffer1.Read(bridgeSpan.Slice(0, channelLength), 0); // TODO - work out if this should be zero?
578-
bridge.DataWritten();
578+
bridge.DataWritten(triggered: false);
579579
bridge.SwitchRegionIfNeeded();
580580
}
581581
}
@@ -588,7 +588,7 @@ void DualChannelStream(int channelLength)
588588
var bridgeSpan = bridge.AcquiringRegionI8;
589589
circularBuffer1.Read(bridgeSpan.Slice(0, channelLength), 0); // TODO - work out if this should be zero?
590590
circularBuffer2.Read(bridgeSpan.Slice(channelLength, channelLength), 0);
591-
bridge.DataWritten();
591+
bridge.DataWritten(triggered: false);
592592
bridge.SwitchRegionIfNeeded();
593593
}
594594
}
@@ -603,7 +603,7 @@ void QuadChannelStream(int channelLength)
603603
circularBuffer2.Read(bridgeSpan.Slice(channelLength, channelLength), 0);
604604
circularBuffer3.Read(bridgeSpan.Slice(channelLength + channelLength, channelLength), 0);
605605
circularBuffer4.Read(bridgeSpan.Slice(channelLength + channelLength + channelLength, channelLength), 0);
606-
bridge.DataWritten();
606+
bridge.DataWritten(triggered: false);
607607
bridge.SwitchRegionIfNeeded();
608608
}
609609
}

source/TS.NET/Memory/Structs/ThunderscopeDataBridgeHeader.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ internal struct ThunderscopeDataBridgeHeader
2727
internal ThunderscopeHardwareConfig Hardware; // 2 + 4*32, read only from UI perspective, UI uses SCPI interface to change configuration
2828
internal ThunderscopeProcessingConfig Processing; // 37 bytes, read only from UI perspective, UI uses SCPI interface to change configuration
2929
internal ThunderscopeDataMonitoring Monitoring; // 16 bytes, Read only from UI perspective, UI optionally displays these values
30+
internal bool Triggered; // Indicate if acquired data was triggered (i.e. to run trigger interpolation or not)
3031

3132
// BridgeConfig is set once from config file or hard coded
3233
// HardwareConfig, ProcessingConfig & DataMonitoring is runtime variable

source/TS.NET/Memory/Structs/ThunderscopeProcessingConfig.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ public struct ThunderscopeProcessingConfig // Idempotent so that UI doesn't ha
1616
public short TriggerLevel; // Uint: count (typically raw ADC value)
1717
public ushort TriggerHysteresis; // Unit: count (typically raw ADC value)
1818

19-
2019
public BoxcarAveraging BoxcarAveraging; // U32
2120
}
2221
}

source/TS.NET/Memory/ThunderscopeDataBridgeReader.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,15 @@ public ThunderscopeDataMonitoring Monitoring
115115
}
116116
}
117117

118+
public bool Triggered
119+
{
120+
get
121+
{
122+
GetHeader();
123+
return header.Triggered;
124+
}
125+
}
126+
118127
public bool RequestAndWaitForData(int millisecondsTimeout)
119128
{
120129
// Firstly check if any data has already been loaded

source/TS.NET/Memory/ThunderscopeDataBridgeWriter.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class ThunderscopeDataBridgeWriter : IDisposable
2121
private bool dataRequested = false;
2222
private bool acquiringRegionFilledAndWaitingForReader = false;
2323
private readonly uint cachedDataWidth;
24+
private bool triggered = false;
2425

2526
public Span<sbyte> AcquiringRegionI8 { get { return GetAcquiringRegionI8(); } }
2627
public ThunderscopeDataMonitoring Monitoring { get { return header.Monitoring; } }
@@ -121,17 +122,19 @@ public void SwitchRegionIfNeeded()
121122
ThunderscopeMemoryAcquiringRegion.RegionB => ThunderscopeMemoryAcquiringRegion.RegionA,
122123
_ => throw new InvalidDataException("Enum value not handled, add enum value to switch")
123124
};
125+
header.Triggered = triggered;
124126
SetHeader();
125127
dataResponseSemaphore.Release(); // Allow UI to use the acquired region
126128
}
127129
}
128130

129-
public void DataWritten()
131+
public void DataWritten(bool triggered)
130132
{
131133
header.Monitoring.TotalAcquisitions++;
132134
if (acquiringRegionFilledAndWaitingForReader)
133135
header.Monitoring.DroppedAcquisitions++;
134136
acquiringRegionFilledAndWaitingForReader = true;
137+
this.triggered = triggered;
135138
SetHeader();
136139
}
137140

0 commit comments

Comments
 (0)