Skip to content

Commit 3388cbe

Browse files
authored
Merge pull request #911 from fredzo/oscilloscope-download-progress-api
Oscilloscope download progress API
2 parents 27e0926 + bf21ef6 commit 3388cbe

37 files changed

+337
-58
lines changed

scopehal/DemoOscilloscope.cpp

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ bool DemoOscilloscope::AcquireData()
491491
if(!m_triggerArmed)
492492
return false;
493493

494+
// prepare all channels to be 'about to download'
495+
ChannelsDownloadStarted();
496+
494497
//cap waveform rate at 50 wfm/s to avoid saturating cpu
495498
std::this_thread::sleep_for(std::chrono::microseconds(20 * 1000));
496499

@@ -531,38 +534,51 @@ bool DemoOscilloscope::AcquireData()
531534
if(!m_channelsEnabled[i])
532535
continue;
533536

537+
// Lambda passed to generate waveform methods to update "download" percentage
538+
auto updateProgress = [i,this](float progress)
539+
{
540+
this->ChannelsDownloadStatusUpdate(i, InstrumentChannel::DownloadState::DOWNLOAD_IN_PROGRESS, progress);
541+
};
542+
this->ChannelsDownloadStatusUpdate(i, InstrumentChannel::DownloadState::DOWNLOAD_IN_PROGRESS, 0.0);
534543
switch(i)
535544
{
536545
case 0:
537546
waveforms[i] = m_source[i]->GenerateNoisySinewave(
538-
0.9, 0.0, 1e6, sampleperiod, depth, noise[0]);
547+
0.9, 0.0, 1e6, sampleperiod, depth, updateProgress, noise[0]);
539548
break;
540549

541550
case 1:
542551
waveforms[i] = m_source[i]->GenerateNoisySinewaveSum(
543-
0.9, 0.0, M_PI_4, 1e6, sweepPeriod, sampleperiod, depth, noise[1]);
552+
0.9, 0.0, M_PI_4, 1e6, sweepPeriod, sampleperiod, depth, updateProgress, noise[1]);
544553
break;
545554

546555
case 2:
556+
547557
waveforms[i] = m_source[i]->GeneratePRBS31(
548-
*m_cmdBuf[i], m_queue[i], 0.9, 96969.6, sampleperiod, depth, lpf2, noise[2]);
558+
*m_cmdBuf[i], m_queue[i], 0.9, 96969.6, sampleperiod, depth,
559+
updateProgress,
560+
lpf2, noise[2]);
549561
break;
550562

551563
case 3:
552564
waveforms[i] = m_source[i]->Generate8b10b(
553-
*m_cmdBuf[i], m_queue[i], 0.9, 800e3, sampleperiod, depth, lpf3, noise[3]);
565+
*m_cmdBuf[i], m_queue[i], 0.9, 800e3, sampleperiod, depth, updateProgress, lpf3, noise[3]);
554566
break;
555567

556568
default:
557569
break;
558570
}
559571

560572
waveforms[i]->MarkModifiedFromCpu();
573+
this->ChannelsDownloadStatusUpdate(i, InstrumentChannel::DownloadState::DOWNLOAD_FINISHED, 1.0);
561574
}
562575

563576
SequenceSet s;
564577
for(int i=0; i<4; i++)
578+
{
565579
s[GetOscilloscopeChannel(i)] = waveforms[i];
580+
this->ChannelsDownloadStatusUpdate(i, InstrumentChannel::DownloadState::DOWNLOAD_NONE, 0.0);
581+
}
566582

567583
//Timestamp the waveform(s)
568584
double now = GetTime();

scopehal/InstrumentChannel.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,3 +151,21 @@ bool InstrumentChannel::ShouldPersistWaveform()
151151
//Default to persisting everything
152152
return true;
153153
}
154+
155+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
156+
// Download progress
157+
158+
InstrumentChannel::DownloadState InstrumentChannel::GetDownloadState()
159+
{
160+
return DownloadState::DOWNLOAD_UNKNOWN;
161+
}
162+
163+
float InstrumentChannel::GetDownloadProgress()
164+
{
165+
return 0.0;
166+
}
167+
168+
double InstrumentChannel::GetDownloadStartTime()
169+
{
170+
return 0.0;
171+
}

scopehal/InstrumentChannel.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,32 @@ class InstrumentChannel : public FlowGraphNode
239239
VIS_SHOW,
240240
} m_visibilityMode;
241241

242+
/**
243+
@brief Enum values to be mapped to GetDownloadState() int result value for specific channel download states
244+
*/
245+
enum DownloadState
246+
{
247+
DOWNLOAD_UNKNOWN,
248+
DOWNLOAD_NONE, ///< No download is pending (e.g. the scope is in stop mode)
249+
DOWNLOAD_WAITING, ///< This channel is waiting to be downloaded (i.e. scope is triggered but previous channels are currently beeing downloaded)
250+
DOWNLOAD_IN_PROGRESS, ///< Download has started
251+
DOWNLOAD_FINISHED ///< Download is finished
252+
};
253+
254+
/**
255+
@brief Returns the current download state of this channel.
256+
257+
The returned int value can either be an integer ranging from 0 to 100 corresponding to the percentage of the waveform that has already been downloaded
258+
or a (negative) int value to be mapped to the OscilloscopeChannel::DownloadState enum
259+
*/
260+
virtual DownloadState GetDownloadState();
261+
262+
/// returns the current completion of the download (on the range [0, 1]), if not DOWNLOAD_UNKNOWN
263+
virtual float GetDownloadProgress();
264+
265+
/// returns the start time of a download, if we are DOWNLOAD_IN_PROGRESS; undefined, otherwise
266+
virtual double GetDownloadStartTime();
267+
242268
protected:
243269

244270
virtual void ClearStreams();

scopehal/LeCroyOscilloscope.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1054,6 +1054,7 @@ void LeCroyOscilloscope::FlushConfigCache()
10541054

10551055
m_channelVoltageRanges.clear();
10561056
m_channelOffsets.clear();
1057+
m_channelDigitalThresholds.clear();
10571058
m_channelsEnabled.clear();
10581059
m_channelDeskew.clear();
10591060
m_probeIsActive.clear();
@@ -4054,13 +4055,24 @@ float LeCroyOscilloscope::GetDigitalThreshold(size_t channel)
40544055
if( (channel < m_digitalChannelBase) || (m_digitalChannelCount == 0) )
40554056
return 0;
40564057

4058+
{
4059+
lock_guard<recursive_mutex> lock(m_cacheMutex);
4060+
4061+
if(m_channelDigitalThresholds.find(channel) != m_channelDigitalThresholds.end())
4062+
return m_channelDigitalThresholds[channel];
4063+
}
4064+
40574065
string reply;
40584066
if(channel <= m_digitalChannels[7]->GetIndex() )
40594067
reply = m_transport->SendCommandQueuedWithReply("VBS? 'return = app.LogicAnalyzer.MSxxThreshold0'");
40604068
else
40614069
reply = m_transport->SendCommandQueuedWithReply("VBS? 'return = app.LogicAnalyzer.MSxxThreshold1'");
40624070

4063-
return atof(reply.c_str());
4071+
float result = atof(reply.c_str());
4072+
4073+
lock_guard<recursive_mutex> lock(m_cacheMutex);
4074+
m_channelDigitalThresholds[channel] = result;
4075+
return result;
40644076
}
40654077

40664078
void LeCroyOscilloscope::SetDigitalHysteresis(size_t channel, float level)

scopehal/LeCroyOscilloscope.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ class LeCroyOscilloscope
352352
//Cached configuration
353353
std::map<size_t, float> m_channelVoltageRanges;
354354
std::map<size_t, float> m_channelOffsets;
355+
std::map<size_t, float> m_channelDigitalThresholds;
355356
std::map<size_t, size_t> m_channelNavg;
356357
std::map<int, bool> m_channelsEnabled;
357358
bool m_sampleRateValid;

scopehal/Oscilloscope.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -856,6 +856,31 @@ bool Oscilloscope::IsInverted(size_t /*i*/)
856856
return false;
857857
}
858858

859+
void Oscilloscope::ChannelsDownloadStarted()
860+
{
861+
for (size_t i = 0; i < m_channels.size(); i++)
862+
{
863+
auto chan = GetOscilloscopeChannel(i);
864+
if (chan == nullptr)
865+
continue;
866+
867+
chan->m_downloadState = InstrumentChannel::DownloadState::DOWNLOAD_WAITING;
868+
chan->m_downloadProgress = 0.0;
869+
chan->m_downloadStartTime = GetTime();
870+
}
871+
}
872+
873+
void Oscilloscope::ChannelsDownloadStatusUpdate(size_t ch, InstrumentChannel::DownloadState state, float progress)
874+
{
875+
auto chan = GetOscilloscopeChannel(ch);
876+
if (chan == nullptr)
877+
return;
878+
879+
chan->m_downloadState = state;
880+
chan->m_downloadProgress = progress;
881+
}
882+
883+
859884
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
860885
// Trigger configuration
861886

scopehal/Oscilloscope.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,15 @@ class Oscilloscope : public virtual Instrument
384384
*/
385385
virtual bool IsInverted(size_t i);
386386

387+
protected:
388+
389+
/// @brief Helper method called by drivers to reset all channels to "waiting to download" state.
390+
void ChannelsDownloadStarted();
391+
392+
/// @brief Helper method called by drivers to set one channel's download status.
393+
void ChannelsDownloadStatusUpdate(size_t ch, InstrumentChannel::DownloadState state, float progress);
394+
395+
public:
387396
//Triggering
388397
enum TriggerMode
389398
{

scopehal/OscilloscopeChannel.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ OscilloscopeChannel::OscilloscopeChannel(
6161
Stream::StreamType stype,
6262
size_t index)
6363
: InstrumentChannel(scope, hwname, color, xunit, yunit, stype, index)
64+
, m_downloadState(DownloadState::DOWNLOAD_UNKNOWN)
65+
, m_downloadProgress(0.0)
66+
, m_downloadStartTime(0.0)
6467
, m_refcount(0)
6568
{
6669
}
@@ -341,3 +344,18 @@ void OscilloscopeChannel::SetInputMux(size_t select)
341344
if(m_instrument)
342345
GetScope()->SetInputMux(m_index, select);
343346
}
347+
348+
InstrumentChannel::DownloadState OscilloscopeChannel::GetDownloadState()
349+
{
350+
return m_downloadState;
351+
}
352+
353+
float OscilloscopeChannel::GetDownloadProgress()
354+
{
355+
return m_downloadProgress;
356+
}
357+
358+
double OscilloscopeChannel::GetDownloadStartTime()
359+
{
360+
return m_downloadStartTime;
361+
}

scopehal/OscilloscopeChannel.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ class OscilloscopeChannel : public InstrumentChannel
145145
virtual void SetInputMux(size_t select);
146146

147147
void SetDefaultDisplayName();
148+
149+
virtual DownloadState GetDownloadState() override;
150+
virtual float GetDownloadProgress() override;
151+
virtual double GetDownloadStartTime() override;
152+
153+
private:
154+
// to be accessed by Oscilloscope to update download status
155+
DownloadState m_downloadState;
156+
float m_downloadProgress;
157+
double m_downloadStartTime;
158+
148159
protected:
149160
void SharedCtorInit(Unit unit);
150161

scopehal/RSRTO6Oscilloscope.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ void RSRTO6Oscilloscope::FlushConfigCache()
243243
m_channelOffsets.clear();
244244
m_channelVoltageRanges.clear();
245245
m_channelsEnabled.clear();
246+
m_channelDigitalThresholds.clear();
246247
m_channelCouplings.clear();
247248
m_channelAttenuations.clear();
248249

@@ -656,8 +657,21 @@ bool RSRTO6Oscilloscope::IsDigitalThresholdConfigurable()
656657

657658
float RSRTO6Oscilloscope::GetDigitalThreshold(size_t channel)
658659
{
659-
// Cache?
660-
return stof(m_transport->SendCommandQueuedWithReply("DIG" + to_string(HWDigitalNumber(channel)) + ":THR?"));
660+
if( (channel < m_digitalChannelBase) || (m_digitalChannelCount == 0) )
661+
return 0;
662+
663+
{
664+
lock_guard<recursive_mutex> lock(m_cacheMutex);
665+
666+
if(m_channelDigitalThresholds.find(channel) != m_channelDigitalThresholds.end())
667+
return m_channelDigitalThresholds[channel];
668+
}
669+
670+
float result = stof(m_transport->SendCommandQueuedWithReply("DIG" + to_string(HWDigitalNumber(channel)) + ":THR?"));
671+
672+
lock_guard<recursive_mutex> lock(m_cacheMutex);
673+
m_channelDigitalThresholds[channel] = result;
674+
return result;
661675
}
662676

663677
void RSRTO6Oscilloscope::SetDigitalThreshold(size_t channel, float level)

0 commit comments

Comments
 (0)