From 2ee58ed4944c99422c33128bbb4d09a0c24e49a7 Mon Sep 17 00:00:00 2001 From: Quentin Berthet Date: Tue, 16 Dec 2025 22:06:48 +0100 Subject: [PATCH 1/5] Revert "LeCroy: disable averaging on WaveSurfer 3000 family scopes because the command seems to be different. See #1026" This reverts commit 73076de7a3136752cfe3efb33aac9987526f4ae8. --- scopehal/LeCroyOscilloscope.cpp | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/scopehal/LeCroyOscilloscope.cpp b/scopehal/LeCroyOscilloscope.cpp index 5dfef6da..4755f97a 100644 --- a/scopehal/LeCroyOscilloscope.cpp +++ b/scopehal/LeCroyOscilloscope.cpp @@ -3710,19 +3710,11 @@ void LeCroyOscilloscope::SetSampleRate(uint64_t rate) bool LeCroyOscilloscope::CanAverage(size_t i) { - //Disable averaging on WS3K series (https://github.com/ngscopeclient/scopehal/issues/1026) - if(m_modelid == MODEL_WAVESURFER_3K) - return false; - return (i < m_analogChannelCount); } size_t LeCroyOscilloscope::GetNumAverages(size_t i) { - //Disable averaging on WS3K series (https://github.com/ngscopeclient/scopehal/issues/1026) - if(m_modelid == MODEL_WAVESURFER_3K) - return 1; - //not meaningful for trigger or digital channels if(i > m_analogChannelCount) return 1; @@ -3744,10 +3736,6 @@ size_t LeCroyOscilloscope::GetNumAverages(size_t i) void LeCroyOscilloscope::SetNumAverages(size_t i, size_t navg) { - //Disable averaging on WS3K series (https://github.com/ngscopeclient/scopehal/issues/1026) - if(m_modelid == MODEL_WAVESURFER_3K) - return; - //not meaningful for trigger or digital channels if(i > m_analogChannelCount) return; From b4cb57b523eb621534fb3ce5b3ff75ae80fd6da1 Mon Sep 17 00:00:00 2001 From: Quentin Berthet Date: Tue, 16 Dec 2025 22:16:47 +0100 Subject: [PATCH 2/5] LeCroyOscilloscope: Handle averaging for WaveSurfer3K Fixes #1026 and partially fixes #996 --- scopehal/LeCroyOscilloscope.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/scopehal/LeCroyOscilloscope.cpp b/scopehal/LeCroyOscilloscope.cpp index 4755f97a..8c5523d8 100644 --- a/scopehal/LeCroyOscilloscope.cpp +++ b/scopehal/LeCroyOscilloscope.cpp @@ -3725,8 +3725,15 @@ size_t LeCroyOscilloscope::GetNumAverages(size_t i) return m_channelNavg[i]; } - auto reply = Trim(m_transport->SendCommandQueuedWithReply( - string("VBS? 'return = app.Acquisition.") + GetOscilloscopeChannel(i)->GetHwname() + ".AverageSweeps'")); + // Averaging on WS3K series is not handled per channel + // (https://github.com/ngscopeclient/scopehal/issues/1026) + std::string reply; + if(m_modelid == MODEL_WAVESURFER_3K) + reply = Trim(m_transport->SendCommandQueuedWithReply( + string("VBS? 'return = app.Acquisition.Horizontal.AverageSweeps'"))); + else + reply = Trim(m_transport->SendCommandQueuedWithReply( + string("VBS? 'return = app.Acquisition.") + GetOscilloscopeChannel(i)->GetHwname() + ".AverageSweeps'")); auto navg = stoi(reply); lock_guard lock(m_cacheMutex); @@ -3740,9 +3747,15 @@ void LeCroyOscilloscope::SetNumAverages(size_t i, size_t navg) if(i > m_analogChannelCount) return; - m_transport->SendCommandQueued( - string("VBS? 'app.Acquisition.") + GetOscilloscopeChannel(i)->GetHwname() + ".AverageSweeps = " + - to_string(navg) + "'"); + // Averaging on WS3K series not handled per channel + // (https://github.com/ngscopeclient/scopehal/issues/1026) + if(m_modelid == MODEL_WAVESURFER_3K) + m_transport->SendCommandQueued( + string("VBS? 'app.Acquisition.Horizontal.AverageSweeps = ") + to_string(navg) + "'"); + else + m_transport->SendCommandQueued( + string("VBS? 'app.Acquisition.") + GetOscilloscopeChannel(i)->GetHwname() + + ".AverageSweeps = " + to_string(navg) + "'"); lock_guard lock(m_cacheMutex); m_channelNavg[i] = navg; From 07effbf7d9448631e0375f214edb20c510c0e131 Mon Sep 17 00:00:00 2001 From: Quentin Berthet Date: Wed, 17 Dec 2025 01:09:01 +0100 Subject: [PATCH 3/5] LeCroyOscilloscope: Fix GetProbeName() for WaveSurfer 3k --- scopehal/LeCroyOscilloscope.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/scopehal/LeCroyOscilloscope.cpp b/scopehal/LeCroyOscilloscope.cpp index 8c5523d8..a5bc71e8 100644 --- a/scopehal/LeCroyOscilloscope.cpp +++ b/scopehal/LeCroyOscilloscope.cpp @@ -1716,6 +1716,20 @@ string LeCroyOscilloscope::GetProbeName(size_t i) if(i >= m_analogChannelCount) return ""; + if(m_modelid == MODEL_WAVESURFER_3K) + { + // Wavesurfer 3K does not report the lack of mux like other LeCroy scopes: + // .ActiveInput and .ProbeName properties do not exist, but .ConnectedProbe does + // (Note that there seems to be a .View property that indicates if a channel is visible and thus active, + // but it doesn't seem to affect the .ConnectedProbe property so we can ignore it. + auto name = Trim(m_transport->SendCommandQueuedWithReply( + string("VBS? 'return = app.Acquisition.") + GetOscilloscopeChannel(i)->GetHwname() + ".ConnectedProbe'")); + if(name == "None") + return ""; + else + return name; + } + //Step 1: Determine which input is active. //There's always a mux selector in software, even if only one is present on the physical acquisition board string prefix = string("app.Acquisition.") + GetOscilloscopeChannel(i)->GetHwname(); From fca4d738072f30a9c2e325628d151c0c889c4910 Mon Sep 17 00:00:00 2001 From: Quentin Berthet Date: Sun, 28 Dec 2025 11:51:30 +0100 Subject: [PATCH 4/5] LeCroyOscilloscope: WS3k: Use HorScale to set sample rate --- scopehal/LeCroyOscilloscope.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/scopehal/LeCroyOscilloscope.cpp b/scopehal/LeCroyOscilloscope.cpp index a5bc71e8..672a6eef 100644 --- a/scopehal/LeCroyOscilloscope.cpp +++ b/scopehal/LeCroyOscilloscope.cpp @@ -3715,6 +3715,36 @@ void LeCroyOscilloscope::SetSampleDepth(uint64_t depth) void LeCroyOscilloscope::SetSampleRate(uint64_t rate) { + if(m_modelid == MODEL_WAVESURFER_3K) + { + //Wavesurfer 3K does not support setting sample rate directly. + //Approximate by adjusting time/div to yield the requested rate for the current depth. + if(rate == 0) + { + LogWarning("Wavesurfer 3K sample rate request was zero, cannot set\n"); + m_sampleRateValid = false; + return; + } + + auto depth = GetSampleDepth(); + if(depth == 0) + { + LogWarning("Wavesurfer 3K returned zero depth, cannot set sample rate\n"); + m_sampleRateValid = false; + return; + } + + double sec_per_div = (static_cast(depth) / static_cast(rate)) / 10.0; + m_transport->SendCommandQueued( + string("VBS? 'app.Acquisition.Horizontal.HorScale = ") + to_string_sci(sec_per_div) + "'"); + + //Flush the cache to force a read so we know the actual rate we got. + m_sampleRateValid = false; + m_memoryDepthValid = false; + m_triggerOffsetValid = false; + return; + } + m_transport->SendCommandQueued(string("VBS? 'app.Acquisition.Horizontal.SampleRate = ") + to_string(rate) + "'"); m_sampleRate = rate; From 192abec12540ebeee78604ad290367b63389cde1 Mon Sep 17 00:00:00 2001 From: Quentin Berthet Date: Sun, 28 Dec 2025 11:55:15 +0100 Subject: [PATCH 5/5] LeCroyOscilloscope: WS3k goes up to 2GS/s in non interleaved mode --- scopehal/LeCroyOscilloscope.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scopehal/LeCroyOscilloscope.cpp b/scopehal/LeCroyOscilloscope.cpp index 672a6eef..08773728 100644 --- a/scopehal/LeCroyOscilloscope.cpp +++ b/scopehal/LeCroyOscilloscope.cpp @@ -3364,6 +3364,13 @@ vector LeCroyOscilloscope::GetSampleRatesNonInterleaved() ret.push_back(20 * g); break; + case MODEL_WAVESURFER_3K: + ret.push_back(200 * m); + ret.push_back(500 * m); + ret.push_back(1 * g); + ret.push_back(2 * g); + break; + default: break; }