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

Commits on Oct 23, 2020

  1. Added to_string_sci()

    azonenberg committed Oct 23, 2020
    Copy the full SHA
    6054c75 View commit details
  2. Copy the full SHA
    ab61546 View commit details
Showing with 151 additions and 8 deletions.
  1. +10 −3 scopehal/DropoutTrigger.cpp
  2. +2 −1 scopehal/DropoutTrigger.h
  3. +124 −4 scopehal/TektronixOscilloscope.cpp
  4. +3 −0 scopehal/TektronixOscilloscope.h
  5. +10 −0 scopehal/scopehal.cpp
  6. +2 −0 scopehal/scopehal.h
13 changes: 10 additions & 3 deletions scopehal/DropoutTrigger.cpp
Original file line number Diff line number Diff line change
@@ -29,6 +29,8 @@

#include "scopehal.h"
#include "DropoutTrigger.h"
#include "LeCroyOscilloscope.h"
#include "TektronixOscilloscope.h"

using namespace std;

@@ -44,14 +46,19 @@ DropoutTrigger::DropoutTrigger(Oscilloscope* scope)
m_parameters[m_typename] = FilterParameter(FilterParameter::TYPE_ENUM, Unit(Unit::UNIT_COUNTS));
m_parameters[m_typename].AddEnumValue("Rising", EDGE_RISING);
m_parameters[m_typename].AddEnumValue("Falling", EDGE_FALLING);
if(dynamic_cast<TektronixOscilloscope*>(scope))
m_parameters[m_typename].AddEnumValue("Any", EDGE_ANY);

m_timename = "Dropout Time";
m_parameters[m_timename] = FilterParameter(FilterParameter::TYPE_INT, Unit(Unit::UNIT_PS));

m_resetname = "Reset Mode";
m_parameters[m_resetname] = FilterParameter(FilterParameter::TYPE_ENUM, Unit(Unit::UNIT_COUNTS));
m_parameters[m_resetname].AddEnumValue("Opposite Edge", RESET_OPPOSITE);
m_parameters[m_resetname].AddEnumValue("None", RESET_NONE);
if(dynamic_cast<LeCroyOscilloscope*>(scope))
{
m_parameters[m_resetname] = FilterParameter(FilterParameter::TYPE_ENUM, Unit(Unit::UNIT_COUNTS));
m_parameters[m_resetname].AddEnumValue("Opposite Edge", RESET_OPPOSITE);
m_parameters[m_resetname].AddEnumValue("None", RESET_NONE);
}
}

DropoutTrigger::~DropoutTrigger()
3 changes: 2 additions & 1 deletion scopehal/DropoutTrigger.h
Original file line number Diff line number Diff line change
@@ -47,7 +47,8 @@ class DropoutTrigger : public Trigger
enum EdgeType
{
EDGE_RISING,
EDGE_FALLING
EDGE_FALLING,
EDGE_ANY
};

void SetType(EdgeType type)
128 changes: 124 additions & 4 deletions scopehal/TektronixOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
#include "TektronixOscilloscope.h"
#include "EdgeTrigger.h"
#include "PulseWidthTrigger.h"
#include "DropoutTrigger.h"

using namespace std;

@@ -2087,6 +2088,7 @@ bool TektronixOscilloscope::SetInterleaving(bool /*combine*/)
vector<string> TektronixOscilloscope::GetTriggerTypes()
{
vector<string> ret;
ret.push_back(DropoutTrigger::GetTriggerName());
ret.push_back(EdgeTrigger::GetTriggerName());
ret.push_back(PulseWidthTrigger::GetTriggerName());
return ret;
@@ -2108,6 +2110,8 @@ void TektronixOscilloscope::PullTrigger()
PullEdgeTrigger();
else if(reply == "WID")
PullPulseWidthTrigger();
else if(reply == "TIMEO")
PullDropoutTrigger();
else
{
LogWarning("Unknown trigger type %s\n", reply.c_str());
@@ -2263,7 +2267,7 @@ void TektronixOscilloscope::PullPulseWidthTrigger()
for(int i=0; i<3; i++)
m_transport->ReadReply();

m_transport->SendCommand("TRIG:A:PULSEW:HIGHL?");//stof scientific notation
m_transport->SendCommand("TRIG:A:PULSEW:HIGHL?");
Unit ps(Unit::UNIT_PS);
et->SetUpperBound(ps.ParseString(m_transport->ReadReply()));

@@ -2301,12 +2305,78 @@ void TektronixOscilloscope::PullPulseWidthTrigger()
}
}


/**
@brief Reads settings for a dropout trigger from the instrument
Note that Tek's UI calls it "timeout" not "dropout" but the functionality is the same.
*/
void TektronixOscilloscope::PullDropoutTrigger()
{
//Clear out any triggers of the wrong type
if( (m_trigger != NULL) && (dynamic_cast<DropoutTrigger*>(m_trigger) != NULL) )
{
delete m_trigger;
m_trigger = NULL;
}

//Create a new trigger if necessary
if(m_trigger == NULL)
m_trigger = new DropoutTrigger(this);
DropoutTrigger* et = dynamic_cast<DropoutTrigger*>(m_trigger);

lock_guard<recursive_mutex> lock(m_mutex);

switch(m_family)
{
case FAMILY_MSO5:
case FAMILY_MSO6:
{
//Source channel
m_transport->SendCommand("TRIG:A:TIMEO:SOU?");
auto reply = m_transport->ReadReply();
et->SetInput(0, StreamDescriptor(GetChannelByHwName(reply), 0), true);

//Trigger level
m_transport->SendCommand("TRIG:A:LEV?");
et->SetLevel(stof(m_transport->ReadReply()));

//For some reason we get 3 more values after this. Discard them.
for(int i=0; i<3; i++)
m_transport->ReadReply();

m_transport->SendCommand("TRIG:A:TIMEO:TIM?");
Unit ps(Unit::UNIT_PS);
et->SetDropoutTime(ps.ParseString(m_transport->ReadReply()));

//TODO: TRIG:A:TIMEO:LOGICQUAL?

//Edge slope
m_transport->SendCommand("TRIG:A:TIMEO:POL?");
reply = Trim(m_transport->ReadReply());
if(reply == "STAYSH")
et->SetType(DropoutTrigger::EDGE_RISING);
else if(reply == "STAYSL")
et->SetType(DropoutTrigger::EDGE_FALLING);
else if(reply == "EIT")
et->SetType(DropoutTrigger::EDGE_ANY);
}
break;

default:
break;
}
}

void TektronixOscilloscope::PushTrigger()
{
auto et = dynamic_cast<EdgeTrigger*>(m_trigger);
auto pt = dynamic_cast<PulseWidthTrigger*>(m_trigger);
auto dt = dynamic_cast<DropoutTrigger*>(m_trigger);
if(pt)
PushPulseWidthTrigger(pt);
else if(dt)
PushDropoutTrigger(dt);

//needs to be last, since pulse width and other more specialized types should be checked first
//but are also derived from EdgeTrigger
@@ -2329,10 +2399,12 @@ void TektronixOscilloscope::PushEdgeTrigger(EdgeTrigger* trig)
case FAMILY_MSO5:
case FAMILY_MSO6:
{
m_transport->SendCommand("TRIG:A:TYP EDGE");

m_transport->SendCommand(string("TRIG:A:EDGE:SOU ") + trig->GetInput(0).m_channel->GetHwname());
m_transport->SendCommand(
string("TRIG:A:LEV:") + trig->GetInput(0).m_channel->GetHwname() + " " +
to_string(trig->GetLevel()));
to_string_sci(trig->GetLevel()));

switch(trig->GetType())
{
@@ -2373,13 +2445,15 @@ void TektronixOscilloscope::PushPulseWidthTrigger(PulseWidthTrigger* trig)
case FAMILY_MSO5:
case FAMILY_MSO6:
{
m_transport->SendCommand("TRIG:A:TYP WID");

m_transport->SendCommand(string("TRIG:A:PULSEW:SOU ") + trig->GetInput(0).m_channel->GetHwname());
m_transport->SendCommand(
string("TRIG:A:LEV:") + trig->GetInput(0).m_channel->GetHwname() + " " +
to_string(trig->GetLevel()));

m_transport->SendCommand(string("TRIG:A:PULSEW:HIGHL ") + to_string(trig->GetUpperBound()*1e-12));
m_transport->SendCommand(string("TRIG:A:PULSEW:LOWL ") + to_string(trig->GetLowerBound()*1e-12));
m_transport->SendCommand(string("TRIG:A:PULSEW:HIGHL ") + to_string_sci(trig->GetUpperBound()*1e-12));
m_transport->SendCommand(string("TRIG:A:PULSEW:LOWL ") + to_string_sci(trig->GetLowerBound()*1e-12));

if(trig->GetType() == EdgeTrigger::EDGE_RISING)
m_transport->SendCommand("TRIG:A:PULSEW:POL POS");
@@ -2423,6 +2497,52 @@ void TektronixOscilloscope::PushPulseWidthTrigger(PulseWidthTrigger* trig)
}
}

/**
@brief Pushes settings for a dropout trigger to the instrument
*/
void TektronixOscilloscope::PushDropoutTrigger(DropoutTrigger* trig)
{
lock_guard<recursive_mutex> lock(m_mutex);

switch(m_family)
{
case FAMILY_MSO5:
case FAMILY_MSO6:
{
m_transport->SendCommand("TRIG:A:TYP TIMEO");

m_transport->SendCommand(string("TRIG:A:TIMEO:SOU ") + trig->GetInput(0).m_channel->GetHwname());
m_transport->SendCommand(
string("TRIG:A:LEV:") + trig->GetInput(0).m_channel->GetHwname() + " " +
to_string(trig->GetLevel()));

switch(trig->GetType())
{
case DropoutTrigger::EDGE_RISING:
m_transport->SendCommand("TRIG:A:TIMEO:POL STAYSH");
break;

case DropoutTrigger::EDGE_FALLING:
m_transport->SendCommand("TRIG:A:TIMEO:POL STAYSL");
break;

case DropoutTrigger::EDGE_ANY:
m_transport->SendCommand("TRIG:A:TIMEO:POL EIT");
break;

default:
break;
}

m_transport->SendCommand(string("TRIG:A:TIMEO:TIM ") + to_string_sci(trig->GetDropoutTime()*1e-12));
}
break;

default:
break;
}
}

vector<Oscilloscope::DigitalBank> TektronixOscilloscope::GetDigitalBanks()
{
vector<DigitalBank> ret;
3 changes: 3 additions & 0 deletions scopehal/TektronixOscilloscope.h
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@

class EdgeTrigger;
class PulseWidthTrigger;
class DropoutTrigger;

/**
@brief Driver for Tektronix oscilloscopes
@@ -223,6 +224,8 @@ class TektronixOscilloscope
void PushEdgeTrigger(EdgeTrigger* trig);
void PullPulseWidthTrigger();
void PushPulseWidthTrigger(PulseWidthTrigger* trig);
void PullDropoutTrigger();
void PushDropoutTrigger(DropoutTrigger* trig);

//Helpers for figuring out type of a channel by the index
bool IsAnalog(size_t index)
10 changes: 10 additions & 0 deletions scopehal/scopehal.cpp
Original file line number Diff line number Diff line change
@@ -397,3 +397,13 @@ float FreqToPhase(float hz)
{
return 2 * M_PI * hz;
}

/**
@brief Like std::to_string, but output in scientific notation
*/
string to_string_sci(double d)
{
char tmp[32];
snprintf(tmp, sizeof(tmp), "%e", d);
return tmp;
}
2 changes: 2 additions & 0 deletions scopehal/scopehal.h
Original file line number Diff line number Diff line change
@@ -93,6 +93,8 @@ std::string Trim(const std::string& str);
std::string TrimQuotes(const std::string& str);
std::string BaseName(const std::string& path);

std::string to_string_sci(double d);

void TransportStaticInit();
void DriverStaticInit();