Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2f756a8c0eeb
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1962ddcf3016
Choose a head ref
  • 13 commits
  • 5 files changed
  • 2 contributors

Commits on May 24, 2020

  1. Copy the full SHA
    12a9063 View commit details
  2. Copy the full SHA
    1667b58 View commit details

Commits on May 25, 2020

  1. Copy the full SHA
    0a39cf6 View commit details
  2. Copy the full SHA
    dbafbe8 View commit details
  3. Copy the full SHA
    2686d0e View commit details
  4. Copy the full SHA
    878d3e5 View commit details
  5. Copy the full SHA
    1a70fb3 View commit details
  6. Copy the full SHA
    730168f View commit details
  7. Copy the full SHA
    802fc89 View commit details

Commits on May 26, 2020

  1. Copy the full SHA
    df7b2b6 View commit details
  2. Copy the full SHA
    ab7268b View commit details
  3. Cosmetics.

    tomverbeure committed May 26, 2020
    Copy the full SHA
    2e8a96d View commit details
  4. Merge pull request #124 from tomverbeure/sds2000x

    Make data acquisition work on Siglent SDS2304X
    azonenberg authored May 26, 2020
    Copy the full SHA
    1962ddc View commit details
Showing with 94 additions and 29 deletions.
  1. +1 −1 log
  2. +9 −2 scopehal/LeCroyOscilloscope.cpp
  3. +1 −0 scopehal/LeCroyOscilloscope.h
  4. +80 −25 scopehal/SiglentSCPIOscilloscope.cpp
  5. +3 −1 scopehal/SiglentSCPIOscilloscope.h
2 changes: 1 addition & 1 deletion log
Submodule log updated from d27a7b to 4df744
11 changes: 9 additions & 2 deletions scopehal/LeCroyOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -114,6 +114,8 @@ void LeCroyOscilloscope::IdentifyHardware()
m_fwVersion = version;

//Look up model info
m_modelid = MODEL_UNKNOWN;

if(m_model.find("WS3") == 0)
m_modelid = MODEL_WAVESURFER_3K;
else if(m_model.find("HDO9") == 0)
@@ -124,8 +126,13 @@ void LeCroyOscilloscope::IdentifyHardware()
m_modelid = MODEL_WAVERUNNER_8K;
else if(m_model.find("SDA3") == 0)
m_modelid = MODEL_SDA_3K;
else
m_modelid = MODEL_UNKNOWN;
else if (m_vendor.compare("SIGLENT") == 0)
{
// TODO: if LeCroy and Siglent classes get split, then this should obviously
// move to the Siglent class.
if (m_model.compare(0, 4, "SDS2") == 0 && m_model.back() == 'X')
m_modelid = MODEL_SIGLENT_SDS2000X;
}

//TODO: better way of doing this?
if(m_model.find("HD") != string::npos)
1 change: 1 addition & 0 deletions scopehal/LeCroyOscilloscope.h
Original file line number Diff line number Diff line change
@@ -145,6 +145,7 @@ class LeCroyOscilloscope
MODEL_HDO_9K,
MODEL_DDA_5K,
MODEL_SDA_3K,
MODEL_SIGLENT_SDS2000X,

MODEL_UNKNOWN
};
105 changes: 80 additions & 25 deletions scopehal/SiglentSCPIOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -39,7 +39,12 @@ using namespace std;

SiglentSCPIOscilloscope::SiglentSCPIOscilloscope(SCPITransport* transport)
: LeCroyOscilloscope(transport)
, m_acquiredDataIsSigned(false)
{
if (m_modelid == MODEL_SIGLENT_SDS2000X)
{
m_acquiredDataIsSigned = true;
}
}

SiglentSCPIOscilloscope::~SiglentSCPIOscilloscope()
@@ -55,30 +60,77 @@ string SiglentSCPIOscilloscope::GetDriverNameInternal()
return "siglent";
}

// parses out length, does no other validation. requires 17 bytes at header.
uint32_t SiglentSCPIOscilloscope::ReadWaveHeader(char *header)
// Somewhat arbitrary. No header has been seen that's larger than 17...
static const int maxWaveHeaderSize = 40;

// "WF?" commands return data that starts with a header.
// On a Siglent SDS2304X, the header of "C0: WF? DESC looks like this: "ALL,#9000000346"
// On other Siglent scopes, a header may look like this: "C1:WF ALL,#9000000070"
// So the size of the header is unknown due to the variable lenghth prefix.

// Returns -1 if no valid header was seen.
// Otherwise, it returns the size of the data chunk that follows the header.
int SiglentSCPIOscilloscope::ReadWaveHeader(char *header)
{
m_transport->ReadRawData(16, (unsigned char*)header);
int i = 0;

// Scan the prefix until ',' is seen.
// We don't want to overfetch, so just get stuff one byte at time...
bool comma_seen = false;
while(!comma_seen && i<maxWaveHeaderSize-12) // -12: we need space for the size part of the header
{
m_transport->ReadRawData(1, (unsigned char *)(header+i));
comma_seen = (header[i] == ',');
++i;
}
header[i] = '\0';

if (strlen(header) != 16)
if (!comma_seen)
{
LogError("Unexpected descriptor header %s\n", header);
return 0;
LogError("WaveHeader: no end of prefix seen in header (%s)\n", header);
return -1;
}
LogDebug("got header: %s\n", header);
return atoi(&header[8]);

// We now expect "#9nnnnnnnnn" (11 characters), where 'n' is a digit.
int start_of_size = i;

m_transport->ReadRawData(11, (unsigned char *)(header+start_of_size));
header[start_of_size+11] = '\0';

bool header_conformant = true;
header_conformant &= (header[start_of_size] == '#');
header_conformant &= (header[start_of_size+1] == '9');
for(i=2; i<11;++i)
header_conformant &= isdigit(header[start_of_size+i]);

header[start_of_size+11] = '\0';

if (!header_conformant)
{
LogError("WaveHeader: header non-conformant (%s)\n", header);
return -1;
}

int data_chunk_size = atoi(&header[start_of_size+2]);

LogDebug("WaveHeader: size = %d (%s)\n", data_chunk_size, header);
return data_chunk_size;

m_transport->ReadRawData(15, (unsigned char*)header);
header[15] = 0;
}

void SiglentSCPIOscilloscope::ReadWaveDescriptorBlock(SiglentWaveformDesc_t *descriptor, unsigned int /*channel*/)
{
char header[17] = {0};
uint32_t headerLength = 0;
char header[maxWaveHeaderSize] = {0};
int headerLength = 0;

headerLength = ReadWaveHeader(header);
LogDebug("header length: %d\n", headerLength);

if(headerLength != sizeof(struct SiglentWaveformDesc_t))
{
LogError("Unexpected header length: %u\n", headerLength);
LogError("Unexpected header length: %d\n", headerLength);
}

m_transport->ReadRawData(sizeof(struct SiglentWaveformDesc_t), (unsigned char*)descriptor);
@@ -96,9 +148,8 @@ bool SiglentSCPIOscilloscope::AcquireData(bool toQueue)
double start = GetTime();


//Read the wavedesc for every enabled channel in batch mode first
//Read the wavedesc for every enabled channel
vector<struct SiglentWaveformDesc_t*> wavedescs;
char tmp[128];
string cmd;
bool enabled[4] = {false};
BulkCheckChannelEnableState();
@@ -111,24 +162,24 @@ bool SiglentSCPIOscilloscope::AcquireData(bool toQueue)
if(enabled[i])
{
m_transport->SendCommand(m_channels[i]->GetHwname() + ":WF? DESC");
// TODO: a bunch of error checking...
ReadWaveDescriptorBlock(wavedescs[i], i);
LogDebug("name %s, number: %u\n",wavedescs[i]->InstrumentName,
wavedescs[i]->InstrumentNumber);

}
}

// grab the actual waveforms

//TODO: WFSU in outer loop and WF in inner loop
unsigned int num_sequences = 1;
for(unsigned int i=0; i<m_analogChannelCount; i++)
for(unsigned int chan_nr=0; chan_nr<m_analogChannelCount; chan_nr++)
{
//If the channel is invisible, don't waste time capturing data
struct SiglentWaveformDesc_t *wavedesc = wavedescs[i];
struct SiglentWaveformDesc_t *wavedesc = wavedescs[chan_nr];
if(string(wavedesc->DescName).empty())
{
m_channels[i]->SetData(NULL);
m_channels[chan_nr]->SetData(NULL);
continue;
}

@@ -174,23 +225,24 @@ bool SiglentSCPIOscilloscope::AcquireData(bool toQueue)
tstruc.tm_isdst = now->tm_isdst;
cap->m_startTimestamp = mktime(&tstruc);
cap->m_timescale = round(interval);
for(unsigned int j=0; j<num_sequences; j++)
for(unsigned int seq_nr=0; seq_nr<num_sequences; seq_nr++)
{
LogDebug("Channel %u block %u\n", i, j);
LogDebug("Channel %u block %u\n", chan_nr, seq_nr);

//Ask for the segment of interest
//(segment number is ignored for non-segmented waveforms)
cmd = "WAVEFORM_SETUP SP,0,NP,0,FP,0,SN,";
if(num_sequences > 1)
{
snprintf(tmp, sizeof(tmp), "%u", j + 1); //segment 0 = "all", 1 = first part of capture
char tmp[128];
snprintf(tmp, sizeof(tmp), "%u", seq_nr + 1); //segment 0 = "all", 1 = first part of capture
cmd += tmp;
m_transport->SendCommand(cmd);
}

//Read the actual waveform data
cmd = "C1:WF? DAT2";
cmd[1] += i;
cmd[1] += chan_nr;
m_transport->SendCommand(cmd);
char header[17] = {0};
size_t wavesize = ReadWaveHeader(header);
@@ -201,11 +253,11 @@ bool SiglentSCPIOscilloscope::AcquireData(bool toQueue)
m_transport->ReadReply();

double trigtime = 0;
if( (num_sequences > 1) && (j > 0) )
if( (num_sequences > 1) && (seq_nr > 0) )
{
//If a multi-segment capture, ask for the trigger time data
cmd = "C1:WF? TIME";
cmd[1] += i;
cmd[1] += chan_nr;
m_transport->SendCommand(cmd);

trigtime = ReadWaveHeader(header);
@@ -236,12 +288,15 @@ bool SiglentSCPIOscilloscope::AcquireData(bool toQueue)
{
cap->m_offsets[i] = i+trigtime_samples;
cap->m_durations[i] = 1;
cap->m_samples[i] = data[i] * v_gain - v_off;
if (m_acquiredDataIsSigned)
cap->m_samples[i] = (int8_t)data[i] * v_gain - v_off;
else
cap->m_samples[i] = data[i] * v_gain - v_off;
}
}

//Done, update the data
m_channels[i]->SetData(cap);
m_channels[chan_nr]->SetData(cap);
}

double dt = GetTime() - start;
4 changes: 3 additions & 1 deletion scopehal/SiglentSCPIOscilloscope.h
Original file line number Diff line number Diff line change
@@ -55,7 +55,9 @@ class SiglentSCPIOscilloscope
protected:

void ReadWaveDescriptorBlock(SiglentWaveformDesc_t *descriptor, unsigned int channel);
uint32_t ReadWaveHeader(char *header);
int ReadWaveHeader(char *header);

bool m_acquiredDataIsSigned;

public:
static std::string GetDriverNameInternal();