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: 7073816b1703
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: f00c551df855
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Sep 26, 2020

  1. Copy the full SHA
    d2311b5 View commit details
  2. TektronixOscilloscope: Implemented Get/SetDeskewForChannel(). At this…

    … point basic functionality for analog-only usage works. No advanced triggers supported, only edge. No digital channel support. Fixes #13.
    azonenberg committed Sep 26, 2020
    Copy the full SHA
    f00c551 View commit details
Showing with 115 additions and 7 deletions.
  1. +112 −7 scopehal/TektronixOscilloscope.cpp
  2. +3 −0 scopehal/TektronixOscilloscope.h
119 changes: 112 additions & 7 deletions scopehal/TektronixOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -44,6 +44,8 @@ TektronixOscilloscope::TektronixOscilloscope(SCPITransport* transport)
, m_sampleRate(0)
, m_sampleDepthValid(false)
, m_sampleDepth(0)
, m_triggerOffsetValid(false)
, m_triggerOffset(0)
, m_triggerArmed(false)
, m_triggerOneShot(false)
, m_bandwidth(1000)
@@ -84,6 +86,7 @@ TektronixOscilloscope::TektronixOscilloscope(SCPITransport* transport)
m_transport->SendCommand("CONFIG:ANALO:BANDW?"); //Figure out what bandwidth we have
m_bandwidth = stof(m_transport->ReadReply()) * 1e-6; //(so we know what probe bandwidth is)
m_transport->SendCommand("HOR:MODE MAN"); //Enable manual sample rate and record length
m_transport->SendCommand("HOR:DEL:MOD ON"); //Horizontal position is in time units
break;

default:
@@ -273,9 +276,11 @@ void TektronixOscilloscope::FlushConfigCache()
m_channelCouplings.clear();
m_channelsEnabled.clear();
m_probeTypes.clear();
m_channelDeskew.clear();

m_sampleRateValid = false;
m_sampleDepthValid = false;
m_triggerOffsetValid = false;

delete m_trigger;
m_trigger = NULL;
@@ -1265,24 +1270,124 @@ void TektronixOscilloscope::SetSampleRate(uint64_t rate)
}
}

void TektronixOscilloscope::SetTriggerOffset(int64_t /*offset*/)
void TektronixOscilloscope::SetTriggerOffset(int64_t offset)
{
//FIXME
lock_guard<recursive_mutex> lock(m_mutex);

switch(m_family)
{
case FAMILY_MSO5:
case FAMILY_MSO6:
{
//Instrument reports position of trigger from the midpoint of the display
//but we want to know position from the start of the capture
double capture_len_sec = 1.0 * GetSampleDepth() / GetSampleRate();
double offset_sec = offset * 1e-12f;
double center_offset_sec = capture_len_sec/2 - offset_sec;

m_transport->SendCommand(string("HOR:DELAY:TIME ") + to_string(center_offset_sec));

//Don't update the cache because the scope is likely to round the offset we ask for.
//If we query the instrument later, the cache will be updated then.
m_triggerOffsetValid = false;
}

default:
break;
}
}

int64_t TektronixOscilloscope::GetTriggerOffset()
{
//FIXME
return 0;
if(m_triggerOffsetValid)
return m_triggerOffset;

lock_guard<recursive_mutex> lock(m_mutex);

switch(m_family)
{
case FAMILY_MSO5:
case FAMILY_MSO6:
{
//Instrument reports position of trigger from the midpoint of the display
m_transport->SendCommand("HOR:DELAY:TIME?");
double center_offset_sec = stod(m_transport->ReadReply());

//but we want to know position from the start of the capture
double capture_len_sec = 1.0 * GetSampleDepth() / GetSampleRate();
double offset_sec = capture_len_sec/2 - center_offset_sec;

//All good, convert to ps and we're done
m_triggerOffset = round(offset_sec * 1e12);
m_triggerOffsetValid = true;
return m_triggerOffset;
}

default:
return 0;
}
}

void TektronixOscilloscope::SetDeskewForChannel(size_t /*channel*/, int64_t /*skew*/)
void TektronixOscilloscope::SetDeskewForChannel(size_t channel, int64_t skew)
{
//Don't update the cache because the scope is likely to round the offset we ask for.
//If we query the instrument later, the cache will be updated then.
{
lock_guard<recursive_mutex> lock(m_cacheMutex);
auto it = m_channelDeskew.find(channel);
if(it != m_channelDeskew.end())
m_channelDeskew.erase(it);
}

lock_guard<recursive_mutex> lock(m_mutex);

switch(m_family)
{
case FAMILY_MSO5:
case FAMILY_MSO6:
//Tek's skew convention has positive values move the channel EARLIER, so we need to flip sign
m_transport->SendCommand(m_channels[channel]->GetHwname() + ":DESK " + to_string(-skew) + "E-12");
break;

default:
break;
}
}

int64_t TektronixOscilloscope::GetDeskewForChannel(size_t /*channel*/)
int64_t TektronixOscilloscope::GetDeskewForChannel(size_t channel)
{
return 0;
//Cannot deskew digital/trigger channels
//TODO: are flex digital channels deskewable?
if(channel >= m_analogChannelCount)
return 0;

//Early out if the value is in cache
{
lock_guard<recursive_mutex> lock(m_cacheMutex);
if(m_channelDeskew.find(channel) != m_channelDeskew.end())
return m_channelDeskew[channel];
}

int64_t deskew = 0;
{
lock_guard<recursive_mutex> lock(m_mutex);
switch(m_family)
{
case FAMILY_MSO5:
case FAMILY_MSO6:
//Tek's skew convention has positive values move the channel EARLIER, so we need to flip sign
m_transport->SendCommand(m_channels[channel]->GetHwname() + ":DESK?");
deskew = -round(1e12 * stof(m_transport->ReadReply()));
break;

default:
break;
}
}

lock_guard<recursive_mutex> lock(m_cacheMutex);
m_channelDeskew[channel] = deskew;
return deskew;
}

bool TektronixOscilloscope::IsInterleaving()
3 changes: 3 additions & 0 deletions scopehal/TektronixOscilloscope.h
Original file line number Diff line number Diff line change
@@ -141,6 +141,9 @@ class TektronixOscilloscope : public SCPIOscilloscope
uint64_t m_sampleRate;
bool m_sampleDepthValid;
uint64_t m_sampleDepth;
bool m_triggerOffsetValid;
int64_t m_triggerOffset;
std::map<size_t, int64_t> m_channelDeskew;
std::map<size_t, ProbeType> m_probeTypes;

bool m_triggerArmed;