@@ -98,6 +98,9 @@ using namespace libm2k;
9898using namespace libm2k ::context;
9999using namespace std ::placeholders;
100100
101+ constexpr int MAX_BUFFER_SIZE_STREAM = 1024 * 1024 ;
102+ constexpr int MAX_KERNEL_BUFFERS = 64 ;
103+
101104Oscilloscope::Oscilloscope (struct iio_context *ctx, Filter *filt,
102105 ToolMenuItem *toolMenuItem,
103106 QJSEngine *engine, ToolLauncher *parent) :
@@ -159,7 +162,7 @@ Oscilloscope::Oscilloscope(struct iio_context *ctx, Filter *filt,
159162 if (m_m2k_analogin) {
160163 symmBufferMode = make_shared<SymmetricBufferMode>();
161164 symmBufferMode->setSampleRates (m_m2k_analogin->getAvailableSampleRates ());
162- symmBufferMode->setEntireBufferMaxSize (64000 );
165+ symmBufferMode->setEntireBufferMaxSize (MAX_BUFFER_SIZE_STREAM );
163166 symmBufferMode->setTriggerBufferMaxSize (8192 ); // 8192 is what hardware supports
164167 symmBufferMode->setTimeDivisionCount (plot.xAxisNumDiv ());
165168 }
@@ -547,7 +550,7 @@ Oscilloscope::Oscilloscope(struct iio_context *ctx, Filter *filt,
547550 {" h" , 36E2 }
548551 }, tr (" Position" ),
549552 -timeBase->maxValue () * 5 ,
550- 36E2 ,
553+ 36E3 ,
551554 true , false , this );
552555 voltsPerDiv = new ScaleSpinButton ({
553556// {"μVolts", 1E-6},
@@ -563,8 +566,8 @@ Oscilloscope::Oscilloscope(struct iio_context *ctx, Filter *filt,
563566 -25 , 25 , true , false , this );
564567
565568 plot.setOffsetInterval (-DBL_MAX, DBL_MAX);
566- plot.setTimeTriggerInterval (-timeBase-> maxValue () * 5 ,
567- timeBase->maxValue () * 5 );
569+ plot.setTimeTriggerInterval (-36E2 ,
570+ timeBase->maxValue () * 5 );
568571
569572 ch_ui = new Ui::ChannelSettings ();
570573 ch_ui->setupUi (ui->channelSettings );
@@ -3594,7 +3597,7 @@ void Oscilloscope::onCmbMemoryDepthChanged(QString value)
35943597 power = ceil (log2 (active_plot_sample_count));
35953598 }
35963599 fft_plot_size = pow (2 , power);
3597- fft_size = active_sample_count ;
3600+ fft_size = active_plot_sample_count ;
35983601 onFFT_view_toggled (fft_is_visible);
35993602
36003603 updateBufferPreviewer ();
@@ -3603,6 +3606,8 @@ void Oscilloscope::onCmbMemoryDepthChanged(QString value)
36033606 toggle_blockchain_flow (true );
36043607 }
36053608 resetStreamingFlag (true );
3609+ double maxT = (1 << 13 ) * (1.0 / active_sample_rate) - 1.0 / active_sample_rate * active_plot_sample_count / 2.0 ;
3610+ plot.setTimeTriggerInterval (-36E2 , maxT);
36063611}
36073612
36083613void Oscilloscope::setSinksDisplayOneBuffer (bool val)
@@ -3654,14 +3659,52 @@ void adiscope::Oscilloscope::onHorizScaleValueChanged(double value)
36543659
36553660 ch_ui->cmbMemoryDepth ->setCurrentIndex (0 );
36563661 if (timeBase->value () >= TIMEBASE_THRESHOLD) {
3657- plot_samples_sequentially = true ;
3658- if (active_sample_count != -active_trig_sample_count) {
3659- active_sample_count = ((-active_trig_sample_count + 3 ) / 4 ) * 4 ;
3660- setSinksDisplayOneBuffer (false );
3661- plot.setXAxisNumPoints (active_plot_sample_count);
3662- resetStreamingFlag (true );
3662+ plot_samples_sequentially = true ; // streaming
3663+ const int minKernelBuffers = 4 ;
3664+ const int oneBufferMaxSize = 2 * 1024 * 1024 ; // 2M
3665+ int m_currentKernelBuffers = minKernelBuffers;
3666+ if (active_trig_sample_count < 0 ) {
3667+ active_sample_count = -active_trig_sample_count;
3668+ m_currentKernelBuffers = (active_plot_sample_count / active_sample_count) + 1 ;
3669+ active_sample_count = (( active_sample_count + 3 ) / 4 ) * 4 ;
3670+ m_currentKernelBuffers = (m_currentKernelBuffers > MAX_KERNEL_BUFFERS) ? MAX_KERNEL_BUFFERS : m_currentKernelBuffers;
3671+ m_currentKernelBuffers = (m_currentKernelBuffers < minKernelBuffers) ? minKernelBuffers : m_currentKernelBuffers;
3672+ } else { // still streaming but without trigger contraints
3673+ /* ensure we have the minimum amount of kernel buffers to fit the buffer */
3674+ while (active_plot_sample_count > (m_currentKernelBuffers * oneBufferMaxSize)
3675+ && m_currentKernelBuffers < MAX_KERNEL_BUFFERS) {
3676+ m_currentKernelBuffers++;
3677+ }
3678+
3679+ /* ensure we don't spend more than 100ms on a acquiring a buffer if we can
3680+ * further divide it into smaller buffers */
3681+ const double maxCaptureDuration = 0.1 ;
3682+ while (((static_cast <double >(active_plot_sample_count) / active_sample_rate)
3683+ / static_cast <double >(m_currentKernelBuffers)) > maxCaptureDuration
3684+ && m_currentKernelBuffers < MAX_KERNEL_BUFFERS) {
3685+ m_currentKernelBuffers++;
3686+ }
3687+ uint64_t chunk_size = active_plot_sample_count / m_currentKernelBuffers;
3688+ uint64_t chunkSizeBeforeAdjust = chunk_size;
3689+ chunk_size = 4 * (chunk_size / 4 );
3690+
3691+ /* If the chunk_size was not divisible by 4 in the first place we would get a smaller value for it. */
3692+ if (chunk_size + 4 <= oneBufferMaxSize && chunkSizeBeforeAdjust != chunk_size) {
3693+ chunk_size += 4 ;
3694+ }
3695+
3696+ // If the buffer size is > 64 * 4M we need to cap the chunk_size to 4M
3697+ if (chunk_size > oneBufferMaxSize) {
3698+ chunk_size = oneBufferMaxSize;
3699+ }
3700+ active_sample_count = chunk_size;
36633701 }
3702+ setSinksDisplayOneBuffer (false );
3703+ plot.setXAxisNumPoints (active_plot_sample_count);
3704+ resetStreamingFlag (true );
3705+ iio->set_kernel_buffer_count (m_currentKernelBuffers);
36643706 } else {
3707+ iio->set_kernel_buffer_count ();
36653708 plot_samples_sequentially = false ;
36663709 setSinksDisplayOneBuffer (true );
36673710 plot.setXAxisNumPoints (0 );
@@ -3698,6 +3741,8 @@ void adiscope::Oscilloscope::onHorizScaleValueChanged(double value)
36983741 timePosition->setValue (-params.timePos );
36993742 }
37003743
3744+ iio->set_device_timeout ((active_sample_count / active_sample_rate) * 1000 + 100 );
3745+
37013746 for (unsigned int i = 0 ; i < nb_channels; i++) {
37023747 iio->set_buffer_size (ids[i], active_sample_count);
37033748 dc_cancel.at (i)->set_buffer_size (active_sample_count);
@@ -3708,10 +3753,6 @@ void adiscope::Oscilloscope::onHorizScaleValueChanged(double value)
37083753 setDigitalPlotCurvesParams ();
37093754 }
37103755
3711-
3712- iio->set_device_timeout ((active_sample_count / active_sample_rate) * 1000 + 100 );
3713-
3714-
37153756 if (started) {
37163757 iio->unlock ();
37173758 }
@@ -3729,13 +3770,16 @@ void adiscope::Oscilloscope::onHorizScaleValueChanged(double value)
37293770 power = ceil (log2 (active_plot_sample_count));
37303771 }
37313772 fft_plot_size = pow (2 , power);
3732- fft_size = active_sample_count ;
3773+ fft_size = active_plot_sample_count ;
37333774 onFFT_view_toggled (fft_is_visible);
37343775
37353776 // Change the sensitivity of time position control
37363777 timePosition->setStep (value / 10 );
37373778
37383779 updateBufferPreviewer ();
3780+
3781+ double maxT = (1 << 13 ) * (1.0 / active_sample_rate) - 1.0 / active_sample_rate * active_plot_sample_count / 2.0 ;
3782+ plot.setTimeTriggerInterval (-36E2 , maxT);
37393783}
37403784
37413785bool adiscope::Oscilloscope::gainUpdateNeeded ()
0 commit comments