@@ -123,8 +123,8 @@ private static unsafe void Loop(
123123 ChannelCount = initialChannelCount ,
124124 ChannelDataLength = settings . MaxCaptureLength ,
125125 ChannelDataType = ThunderscopeDataType . I8 ,
126+ Mode = Mode . Auto ,
126127 TriggerChannel = TriggerChannel . Channel1 ,
127- TriggerMode = TriggerMode . Auto ,
128128 TriggerType = TriggerType . Edge ,
129129 TriggerDelayFs = 0 ,
130130 TriggerHoldoffFs = 0 ,
@@ -180,9 +180,9 @@ private static unsafe void Loop(
180180 TriggerIndices = new int [ ThunderscopeMemory . Length / 1000 ] , // 1000 samples is the minimum window width
181181 CaptureEndIndices = new int [ ThunderscopeMemory . Length / 1000 ] // 1000 samples is the minimum window width
182182 } ;
183- bool runMode = true ;
184- bool forceTriggerLatch = false ; // "Latch" because it will reset state back to false. If the force is invoked and a trigger happens anyway, it will be reset (effectively ignoring it and only updating the bridge once).
183+ bool runMode = false ;
185184 bool singleTriggerLatch = false ; // "Latch" because it will reset state back to false. When reset, runTrigger will be set to false.
185+ Mode modeAfterForce = processingConfig . Mode ;
186186
187187 // Variables for Auto triggering
188188 Stopwatch autoTimeoutTimer = Stopwatch . StartNew ( ) ;
@@ -200,49 +200,49 @@ private static unsafe void Loop(
200200 {
201201 switch ( request )
202202 {
203- case ProcessingRunDto processingStartTriggerDto :
204- runMode = true ;
205- processingConfig . TriggerMode = TriggerMode . Auto ; // To do: cache the last setting of AUTO/NORMAL/STREAM and use it here
203+ case ProcessingRunDto processingRunDto :
206204 captureBuffer . Reset ( ) ;
207- hardwareRequestChannel . Write ( new HardwareStartRequest ( ) ) ;
205+ StartHardware ( ) ;
208206 logger . LogDebug ( $ "{ nameof ( ProcessingRunDto ) } ") ;
209207 break ;
210- case ProcessingStopDto processingStopTriggerDto :
211- runMode = false ;
212- hardwareRequestChannel . Write ( new HardwareStopRequest ( ) ) ;
208+ case ProcessingStopDto processingStopDto :
209+ StopHardware ( ) ;
213210 logger . LogDebug ( $ "{ nameof ( ProcessingStopDto ) } ") ;
214211 break ;
215- case ProcessingForceTriggerDto processingForceTriggerDto : // Force only works in RUN mode, and finishes in RUN
216- if ( runMode ) // Ignore the force if not in run mode, to prevent a glitch when going STOP > RUN (with a FORCE armed)
217- {
218- forceTriggerLatch = true ;
219- captureBuffer . Reset ( ) ;
220- logger . LogDebug ( $ "{ nameof ( ProcessingForceTriggerDto ) } armed") ;
221- }
222- else
223- {
224- logger . LogDebug ( $ "{ nameof ( ProcessingForceTriggerDto ) } not armed") ;
225- }
212+ case ProcessingGetModeRequest processingGetModeRequest :
213+ processingResponseChannel . Write ( new ProcessingGetModeResponse ( processingConfig . Mode ) ) ;
214+ logger . LogDebug ( $ "{ nameof ( ProcessingGetModeRequest ) } ") ;
226215 break ;
227- case ProcessingSetTriggerModeDto processingSetTriggerModeDto :
228- processingConfig . TriggerMode = processingSetTriggerModeDto . Mode ;
229- switch ( processingSetTriggerModeDto . Mode )
216+ case ProcessingSetModeDto processingSetModeDto :
217+ singleTriggerLatch = false ;
218+ captureBuffer . Reset ( ) ; // To do: consider if resetting capture buffer is right in all mode change scenarios
219+ switch ( processingSetModeDto . Mode )
230220 {
231- case TriggerMode . Normal :
232- case TriggerMode . Stream :
233- singleTriggerLatch = false ;
221+ case Mode . Normal : // NORMAL/STREAM/AUTO use RUN/STOP on user demand
222+ case Mode . Stream :
223+ processingConfig . Mode = processingSetModeDto . Mode ;
234224 break ;
235- case TriggerMode . Single : // Single works in both RUN/STOP, and finishes in STOP
236- runMode = true ;
225+ case Mode . Auto :
226+ autoTimeoutTimer . Restart ( ) ;
227+ processingConfig . Mode = processingSetModeDto . Mode ;
228+ break ;
229+ case Mode . Single : // SINGLE forces runMode.
230+ if ( runMode != true )
231+ {
232+ StartHardware ( ) ;
233+ }
237234 singleTriggerLatch = true ;
235+ processingConfig . Mode = processingSetModeDto . Mode ;
238236 break ;
239- case TriggerMode . Auto :
240- singleTriggerLatch = false ;
241- autoTimeoutTimer . Restart ( ) ;
237+ case Mode . Force : // FORCE is ignored if not in runMode.
238+ if ( runMode )
239+ {
240+ modeAfterForce = processingConfig . Mode ;
241+ processingConfig . Mode = processingSetModeDto . Mode ;
242+ }
242243 break ;
243244 }
244- captureBuffer . Reset ( ) ;
245- logger . LogDebug ( $ "{ nameof ( ProcessingSetTriggerModeDto ) } (mode: { processingConfig . TriggerMode } )") ;
245+ logger . LogDebug ( $ "{ nameof ( ProcessingSetModeDto ) } (mode: { processingConfig . Mode } )") ;
246246 break ;
247247 case ProcessingSetTriggerSourceDto processingSetTriggerSourceDto :
248248 processingConfig . TriggerChannel = processingSetTriggerSourceDto . Channel ;
@@ -427,11 +427,11 @@ private static unsafe void Loop(
427427
428428 if ( runMode )
429429 {
430- switch ( processingConfig . TriggerMode )
430+ switch ( processingConfig . Mode )
431431 {
432- case TriggerMode . Normal :
433- case TriggerMode . Single :
434- case TriggerMode . Auto :
432+ case Mode . Normal :
433+ case Mode . Single :
434+ case Mode . Auto :
435435 if ( cachedHardwareConfig . IsTriggerChannelAnEnabledChannel ( processingConfig . TriggerChannel ) )
436436 {
437437 // Load in the trigger buffer from the correct shuffle buffer
@@ -492,29 +492,26 @@ private static unsafe void Loop(
492492 if ( singleTriggerLatch ) // If this was a single trigger, reset the singleTrigger & runTrigger latches
493493 {
494494 singleTriggerLatch = false ;
495- runMode = false ;
495+ StopHardware ( ) ;
496496 break ;
497497 }
498498 }
499499 streamSampleCounter = 0 ;
500500 autoTimeoutTimer . Restart ( ) ; // Restart the auto timeout as a normal trigger happened
501501 }
502502 }
503- if ( forceTriggerLatch ) // This will always run, despite whether a trigger has happened or not (so from the user perspective, the UI might show one misaligned waveform during normal triggering; this is intended)
504- {
505- Capture ( triggered : false , triggerChannelCaptureIndex : 0 , offset : 0 ) ;
506-
507- forceTriggerLatch = false ;
508-
509- streamSampleCounter = 0 ;
510- autoTimeoutTimer . Restart ( ) ; // Restart the auto timeout as a force trigger happened
511- }
512- else if ( processingConfig . TriggerMode == TriggerMode . Auto && autoTimeoutTimer . ElapsedMilliseconds > autoTimeout )
503+ if ( processingConfig . Mode == Mode . Auto && autoTimeoutTimer . ElapsedMilliseconds > autoTimeout )
513504 {
514505 StreamCapture ( ) ;
515506 }
516507 break ;
517- case TriggerMode . Stream :
508+ case Mode . Force : // Mode.Force is a latching mode - it'll return back to one of the other modes
509+ Capture ( triggered : false , triggerChannelCaptureIndex : 0 , offset : 0 ) ;
510+ processingConfig . Mode = modeAfterForce ;
511+ streamSampleCounter = 0 ;
512+ autoTimeoutTimer . Restart ( ) ; // Restart the auto timeout as a force trigger happened
513+ break ;
514+ case Mode . Stream :
518515 StreamCapture ( ) ;
519516 break ;
520517 }
@@ -540,6 +537,18 @@ private static unsafe void Loop(
540537 }
541538
542539 // Locally scoped methods for deduplication
540+ void StartHardware ( )
541+ {
542+ runMode = true ;
543+ hardwareRequestChannel . Write ( new HardwareStartRequest ( ) ) ;
544+ }
545+
546+ void StopHardware ( )
547+ {
548+ runMode = false ;
549+ hardwareRequestChannel . Write ( new HardwareStopRequest ( ) ) ;
550+ }
551+
543552 void SwitchTrigger ( )
544553 {
545554 triggerI8 = processingConfig . TriggerType switch
0 commit comments