Skip to content

Commit 8a29a06

Browse files
committed
Partial Doxygen coverage of TektronixOscilloscope
1 parent f4a2e7f commit 8a29a06

File tree

3 files changed

+116
-1
lines changed

3 files changed

+116
-1
lines changed

scopehal/TektronixOscilloscope.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
* *
2828
***********************************************************************************************************************/
2929

30+
/**
31+
@file
32+
@author Andrew D. Zonenberg
33+
@brief Implementation of TektronixOscilloscope
34+
35+
@ingroup scopedrivers
36+
*/
37+
3038
#include "scopehal.h"
3139
#include "TektronixOscilloscope.h"
3240
#include "EdgeTrigger.h"
@@ -41,6 +49,11 @@ using namespace std;
4149
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
4250
// Construction / destruction
4351

52+
/**
53+
@brief Initialize the driver
54+
55+
@param transport SCPITransport connected to the scope
56+
*/
4457
TektronixOscilloscope::TektronixOscilloscope(SCPITransport* transport)
4558
: SCPIDevice(transport)
4659
, SCPIInstrument(transport)
@@ -305,6 +318,7 @@ TektronixOscilloscope::~TektronixOscilloscope()
305318
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
306319
// Accessors
307320

321+
///@brief Return the constant driver name string "tektronix"
308322
string TektronixOscilloscope::GetDriverNameInternal()
309323
{
310324
return "tektronix";
@@ -342,6 +356,9 @@ string TektronixOscilloscope::GetProbeName(size_t i)
342356
return m_probeNames[i];
343357
}
344358

359+
/**
360+
@brief Look at each input channel and determine what kind of probe, if any, is connected
361+
*/
345362
void TektronixOscilloscope::DetectProbes()
346363
{
347364
std::vector<bool> currentlyEnabled;
@@ -1553,6 +1570,12 @@ bool TektronixOscilloscope::AcquireData()
15531570
return true;
15541571
}
15551572

1573+
/**
1574+
@brief Parses a waveform preamble
1575+
1576+
@param[in] preamble_in Raw string preamble
1577+
@param[out] preamble_out Parsed preamble data
1578+
*/
15561579
bool TektronixOscilloscope::ReadPreamble(string& preamble_in, mso56_preamble& preamble_out)
15571580
{
15581581
size_t semicolons = std::count(preamble_in.begin(), preamble_in.end(), ';');
@@ -1623,6 +1646,19 @@ bool TektronixOscilloscope::ReadPreamble(string& preamble_in, mso56_preamble& pr
16231646
return false;
16241647
}
16251648

1649+
/**
1650+
@brief Attempt to recover synchronization between ngscopeclient and the scope-side SCPI stack.
1651+
1652+
This involves a lot of ugly hacks while attempting to undo behavior the scope should never have had in the first
1653+
place (keeping application layer protocol state across client disconnect/reconnect events).
1654+
1655+
We flush the receive buffer twice at the scope side, throw away anything in the socket RX buffer, then send a
1656+
PRBS-3 of two different query commands with predictable output. By cross-correlating the replies with the sent
1657+
commands, we can determine how many lines worth of garbage were in the instrument's TX buffer, discard them,
1658+
and recover sync.
1659+
1660+
In theory. It doesn't always work and sometimes things are completely hosed until the scope reboots.
1661+
*/
16261662
void TektronixOscilloscope::ResynchronizeSCPI()
16271663
{
16281664
LogTrace("Resynchronizing\n");
@@ -1726,6 +1762,13 @@ void TektronixOscilloscope::ResynchronizeSCPI()
17261762
*/
17271763
}
17281764

1765+
/**
1766+
@brief Acquire data from a MSO5 or MSO6 scope
1767+
1768+
@param[out] pending_waveforms Map of channel number -> waveform
1769+
1770+
@return True on success, false on failure
1771+
*/
17291772
bool TektronixOscilloscope::AcquireDataMSO56(map<int, vector<WaveformBase*> >& pending_waveforms)
17301773
{
17311774
//Seems like we might need a command before reading data after the trigger?
@@ -2110,12 +2153,22 @@ bool TektronixOscilloscope::AcquireDataMSO56(map<int, vector<WaveformBase*> >& p
21102153
return true;
21112154
}
21122155

2156+
/**
2157+
@brief Checks if the channel enable state of a channel is up to date
2158+
2159+
@param chan Channel index
2160+
2161+
@return True if up to date, false if not
2162+
*/
21132163
bool TektronixOscilloscope::IsEnableStateDirty(size_t chan)
21142164
{
21152165
lock_guard<recursive_mutex> lock(m_cacheMutex);
21162166
return m_channelEnableStatusDirty.find(chan) != m_channelEnableStatusDirty.end();
21172167
}
21182168

2169+
/**
2170+
@brief Flushes pending channel enable/disable commands
2171+
*/
21192172
void TektronixOscilloscope::FlushChannelEnableStates()
21202173
{
21212174
//Push all previous commands to the scope, then mark channel enable states as up to date

scopehal/TektronixOscilloscope.h

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@
2727
* *
2828
***********************************************************************************************************************/
2929

30+
/**
31+
@file
32+
@author Andrew D. Zonenberg
33+
@brief Declaration of TektronixOscilloscope
34+
35+
@ingroup scopedrivers
36+
*/
37+
3038
#ifndef TektronixOscilloscope_h
3139
#define TektronixOscilloscope_h
3240

@@ -39,6 +47,7 @@ class WindowTrigger;
3947

4048
/**
4149
@brief Driver for Tektronix oscilloscopes
50+
@ingroup scopedrivers
4251
4352
Tek scopes appear to adhere strictly to the LXI-style request-response model.
4453
Sending a new command while another is currently executing will result in one or both commands aborting.
@@ -56,6 +65,12 @@ class WindowTrigger;
5665
Prints a status register, not quite sure what this does
5766
ALLEV?
5867
Prints the error log in a somewhat confusing and not-human-readable format
68+
69+
Other gotchas to be aware of: if you send a command that is malformed or the scope is not in the correct state for
70+
(e.g. querying status of a MSO channel when there is no MSO probe connected to that channel), it will be dropped
71+
silently and the scope may hang for a few seconds before processing more commands. Resync after this is difficult.
72+
73+
Just don't do it.
5974
*/
6075
class TektronixOscilloscope
6176
: public virtual SCPIOscilloscope
@@ -206,9 +221,18 @@ class TektronixOscilloscope
206221
virtual int64_t GetResolutionBandwidth() override;
207222

208223
protected:
224+
225+
///@brief External trigger
209226
OscilloscopeChannel* m_extTrigChannel;
227+
228+
///@brief Function generator output
210229
FunctionGeneratorChannel* m_awgChannel;
211230

231+
/**
232+
@brief Binary waveform header
233+
234+
TODO: link relevant documentation
235+
*/
212236
struct mso56_preamble
213237
{
214238
int byte_num;
@@ -249,32 +273,69 @@ class TektronixOscilloscope
249273
bool AcquireDataMSO56(std::map<int, std::vector<WaveformBase*> >& pending_waveforms);
250274
void DetectProbes();
251275

252-
//hardware analog channel count, independent of LA option etc
276+
///@brief Hardware analog channel count, independent of LA option etc
253277
unsigned int m_analogChannelCount;
254278

279+
///@brief Type of probe connected to a hardware channel
255280
enum ProbeType
256281
{
282+
///@brief Standard high impedance probe
257283
PROBE_TYPE_ANALOG,
284+
285+
///@brief 250K ohm high bandwidth probe
258286
PROBE_TYPE_ANALOG_250K,
287+
288+
///@brief Current probe
259289
PROBE_TYPE_ANALOG_CURRENT,
290+
291+
///@brief 8-bit logic pod
260292
PROBE_TYPE_DIGITAL_8BIT
261293
};
262294

263295
//config cache
296+
297+
///@brief Cached map of <channel ID, offset>
264298
std::map<size_t, float> m_channelOffsets;
299+
300+
///@brief Cached map of <channel ID, full scale range>
265301
std::map<size_t, float> m_channelVoltageRanges;
302+
303+
///@brief Cached map of <channel ID, coupling>
266304
std::map<size_t, OscilloscopeChannel::CouplingType> m_channelCouplings;
305+
306+
///@brief Cached map of <channel ID, attenuation>
267307
std::map<size_t, double> m_channelAttenuations;
308+
309+
///@brief Cached map of <channel ID, bandwidth limiter>
268310
std::map<size_t, int> m_channelBandwidthLimits;
311+
312+
///@brief Cached map of <channel ID, enable flag>
269313
std::map<int, bool> m_channelsEnabled;
314+
315+
///@brief True if m_triggerChannel is valid, false if out of sync
270316
bool m_triggerChannelValid;
317+
318+
///@brief Index of the channel selected for triggering
271319
size_t m_triggerChannel;
320+
321+
///@brief True if m_sampleRate is valid, false if out of sync
272322
bool m_sampleRateValid;
323+
324+
///@brief Acquisition sample rate, in samples/sec
273325
uint64_t m_sampleRate;
326+
327+
///@brief True if m_sampleDepth is valid, false if out of sync
274328
bool m_sampleDepthValid;
329+
330+
///@brief Acquisition memory depth, in samples
275331
uint64_t m_sampleDepth;
332+
333+
///@brief True if m_triggerOffset is valid, false if out of sync
276334
bool m_triggerOffsetValid;
335+
336+
///@brief Offset from start of wavefrom to trigger position
277337
int64_t m_triggerOffset;
338+
278339
std::map<size_t, int64_t> m_channelDeskew;
279340
std::map<size_t, ProbeType> m_probeTypes;
280341
std::map<size_t, std::string> m_probeNames;

scopehal/TestWaveformSource.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
* POSSIBILITY OF SUCH DAMAGE. *
2727
* *
2828
***********************************************************************************************************************/
29+
2930
/**
3031
@file
3132
@author Andrew D. Zonenberg

0 commit comments

Comments
 (0)