Skip to content

Commit 3d2d4b3

Browse files
authored
Merge pull request ngscopeclient#880 from fredzo/rigol-dho-support
Rigol dho support enhancement
2 parents ae8f81c + f5effb1 commit 3d2d4b3

File tree

4 files changed

+102
-9
lines changed

4 files changed

+102
-9
lines changed

scopehal/Oscilloscope.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,18 @@ bool Oscilloscope::CanEnableChannel(size_t /*i*/)
119119
return true;
120120
}
121121

122+
int Oscilloscope::GetEnabledChannelCount()
123+
{
124+
int result = 0;
125+
for(size_t i=0; i<GetChannelCount(); i++)
126+
{
127+
if(IsChannelEnabled(i))
128+
result++;
129+
}
130+
return result;
131+
}
132+
133+
122134
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
123135
// Triggering helpers
124136

scopehal/Oscilloscope.h

+7
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ class Oscilloscope : public virtual Instrument
132132
*/
133133
virtual void DisableChannel(size_t i) =0;
134134

135+
/**
136+
@brief Returns the number of enabled channels for this oscilloscope.
137+
138+
@return the number of enabled channels for this oscilloscope.
139+
*/
140+
int GetEnabledChannelCount();
141+
135142
/**
136143
@brief Gets a channel given the hardware name
137144
*/

scopehal/RigolOscilloscope.cpp

+79-9
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ RigolOscilloscope::RigolOscilloscope(SCPITransport* transport)
4949
, m_triggerArmed(false)
5050
, m_triggerWasLive(false)
5151
, m_triggerOneShot(false)
52+
, m_liveMode(false)
5253
{
5354
//Last digit of the model number is the number of channels
5455
if(1 == sscanf(m_model.c_str(), "DS%d", &m_modelNumber))
@@ -107,16 +108,27 @@ RigolOscilloscope::RigolOscilloscope(SCPITransport* transport)
107108

108109
m_transport->SendCommandQueued("CHAN1:BWL " + originalBandwidthLimit);
109110
}
110-
else if(1 == sscanf(m_model.c_str(), "DHO%d", &m_modelNumber) && (m_modelNumber < 1000))
111-
{
111+
else if(1 == sscanf(m_model.c_str(), "DHO%d", &m_modelNumber) && (m_modelNumber < 5000))
112+
{ // Model numbers are :
113+
// - DHO802 (70MHz), DHO804 (70Mhz), DHO812 (100MHz),DHO814 (100MHz)
114+
// - DHO914/DHO914S (125MHz), DHO924/DHO924S (250MHz)
115+
// - DHO1072 (70MHz), DHO1074 (70MHz), DHO1102 (100MHz), DHO1104 (100MHz), DHO1202 (200MHz), DHO1204 (200MHz)
116+
// - DHO4204 (200MHz), DHO4404 (400 MHz), DHO4804 (800MHz)
112117
m_protocol = DHO;
113118

114119
int model_multiplicator = 100;
115-
if(m_modelNumber > 900) // special handling of DHO900 series
116-
{
120+
int model_modulo = 100;
121+
if(m_modelNumber > 1000)
122+
{ // DHO1000 and 4000
123+
model_multiplicator = 10;
124+
model_modulo = 1000;
125+
}
126+
else if(m_modelNumber > 900)
127+
{ // special handling of DHO900 series
117128
model_multiplicator = 125;
118129
}
119-
m_bandwidth = m_modelNumber % 100 / 10 * model_multiplicator; // should also work for DHO1000/DHO4000
130+
m_bandwidth = m_modelNumber % model_modulo / 10 * model_multiplicator;
131+
if(m_bandwidth == 0) m_bandwidth = 70; // Fallback for DHO80x models
120132

121133
m_opt200M = false; // does not exist in 800/900 series
122134
}
@@ -653,6 +665,9 @@ void RigolOscilloscope::SetChannelOffset(size_t i, size_t /*stream*/, float offs
653665

654666
Oscilloscope::TriggerMode RigolOscilloscope::PollTrigger()
655667
{
668+
if(m_liveMode)
669+
return TRIGGER_MODE_TRIGGERED;
670+
656671
auto stat = Trim(m_transport->SendCommandQueuedWithReply(":TRIG:STAT?"));
657672

658673
if(stat != "STOP")
@@ -708,6 +723,7 @@ bool RigolOscilloscope::AcquireData()
708723
maxpoints = 8192; // FIXME
709724
else if(m_protocol == MSO5)
710725
maxpoints = GetSampleDepth(); //You can use 250E6 points too, but it is very slow
726+
711727
unsigned char* temp_buf = new unsigned char[maxpoints + 1];
712728
map<int, vector<UniformAnalogWaveform*>> pending_waveforms;
713729
for(size_t i = 0; i < m_analogChannelCount; i++)
@@ -754,8 +770,17 @@ bool RigolOscilloscope::AcquireData()
754770
&yincrement,
755771
&yorigin,
756772
&yreference);
773+
if(sec_per_sample == 0)
774+
{ // Sometimes the scope might return a null value for xincrement => replace it with a dummy value to prenvent an Arithmetic exception in WaveformArea::RasterizeAnalogOrDigitalWaveform
775+
LogWarning("Got null sec_per_sample value from the scope, forcing it to a dummy non null value to prevent Arithmetic exception.\n");
776+
sec_per_sample = 0.001;
777+
}
757778
fs_per_sample = round(sec_per_sample * FS_PER_SECOND);
758-
//LogDebug("X: %d points, %f origin, ref %f fs/sample %ld\n", npoints, xorigin, xreference, fs_per_sample);
779+
if(m_protocol == DHO)
780+
{ // DHO models return page size instead of memory depth when paginating
781+
npoints = GetSampleDepth();
782+
}
783+
//LogDebug("X: %d points, %f origin, ref %f fs/sample %ld\n", (int) npoints, xorigin, xreference, (long int) fs_per_sample);
759784
//LogDebug("Y: %f inc, %f origin, %f ref\n", yincrement, yorigin, yreference);
760785
}
761786

@@ -775,7 +800,7 @@ bool RigolOscilloscope::AcquireData()
775800
//Downloading the waveform is a pain in the butt, because we can only pull 250K points at a time! (Unless you have a MSO5)
776801
for(size_t npoint = 0; npoint < npoints;)
777802
{
778-
if(m_protocol == MSO5 || m_protocol == DHO)
803+
if(m_protocol == MSO5)
779804
{
780805
//Ask for the data block
781806
m_transport->SendCommandQueued("*WAI");
@@ -899,8 +924,11 @@ bool RigolOscilloscope::AcquireData()
899924
}
900925
else
901926
{
902-
m_transport->SendCommandQueued(":SING");
903-
m_transport->SendCommandQueued("*WAI");
927+
if(!m_liveMode)
928+
{
929+
m_transport->SendCommandQueued(":SING");
930+
m_transport->SendCommandQueued("*WAI");
931+
}
904932
}
905933
m_triggerArmed = true;
906934
}
@@ -910,6 +938,24 @@ bool RigolOscilloscope::AcquireData()
910938
return true;
911939
}
912940

941+
void RigolOscilloscope::PrepareStart()
942+
{
943+
if(m_protocol == DHO)
944+
{
945+
// DHO models need to set raw mode off and on again or vice versa to reset the number of points according to the current memory depth
946+
if(m_liveMode)
947+
{
948+
m_transport->SendCommandQueued(":WAV:MODE RAW");
949+
m_transport->SendCommandQueued(":WAV:MODE NORM");
950+
}
951+
else
952+
{
953+
m_transport->SendCommandQueued(":WAV:MODE NORM");
954+
m_transport->SendCommandQueued(":WAV:MODE RAW");
955+
}
956+
}
957+
}
958+
913959
void RigolOscilloscope::Start()
914960
{
915961
//LogDebug("Start single trigger\n");
@@ -918,6 +964,23 @@ void RigolOscilloscope::Start()
918964
m_transport->SendCommandQueued(":TRIG:EDGE:SWE SING");
919965
m_transport->SendCommandQueued(":RUN");
920966
}
967+
else if(m_protocol == DHO)
968+
{ // Check for memory depth : if it is 1k, switch to live mode for better performance
969+
// Limit live mode to one channel setup to prevent grabbing waveforms from to different triggers on seperate channels
970+
if(GetEnabledChannelCount()==1)
971+
{
972+
m_mdepthValid = false;
973+
GetSampleDepth();
974+
m_liveMode = (m_mdepth == 1000);
975+
}
976+
else
977+
{
978+
m_liveMode = false;
979+
}
980+
PrepareStart();
981+
m_transport->SendCommandQueued(m_liveMode ? ":RUN" : ":SING");
982+
m_transport->SendCommandQueued("*WAI");
983+
}
921984
else
922985
{
923986
m_transport->SendCommandQueued(":SING");
@@ -929,6 +992,9 @@ void RigolOscilloscope::Start()
929992

930993
void RigolOscilloscope::StartSingleTrigger()
931994
{
995+
m_liveMode = false;
996+
m_mdepthValid = false; // Memory depth might have been changed on scope
997+
PrepareStart();
932998
if(m_protocol == DS_OLD)
933999
{
9341000
m_transport->SendCommandQueued(":TRIG:EDGE:SWE SING");
@@ -946,12 +1012,16 @@ void RigolOscilloscope::StartSingleTrigger()
9461012
void RigolOscilloscope::Stop()
9471013
{
9481014
m_transport->SendCommandQueued(":STOP");
1015+
m_liveMode = false;
9491016
m_triggerArmed = false;
9501017
m_triggerOneShot = true;
9511018
}
9521019

9531020
void RigolOscilloscope::ForceTrigger()
9541021
{
1022+
m_liveMode = false;
1023+
m_mdepthValid = false; // Memory depth might have been changed on scope
1024+
PrepareStart();
9551025
if(m_protocol == DS || m_protocol == DHO)
9561026
m_transport->SendCommandQueued(":TFOR");
9571027
else

scopehal/RigolOscilloscope.h

+4
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ class RigolOscilloscope : public virtual SCPIOscilloscope
125125
bool m_triggerWasLive;
126126
bool m_triggerOneShot;
127127

128+
bool m_liveMode;
129+
128130
int m_modelNumber;
129131
unsigned int m_bandwidth;
130132
bool m_opt200M;
@@ -133,6 +135,8 @@ class RigolOscilloscope : public virtual SCPIOscilloscope
133135
void PushEdgeTrigger(EdgeTrigger* trig);
134136
void PullEdgeTrigger();
135137

138+
void PrepareStart();
139+
136140
public:
137141
static std::string GetDriverNameInternal();
138142
OSCILLOSCOPE_INITPROC(RigolOscilloscope)

0 commit comments

Comments
 (0)