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

Commits on Dec 20, 2020

  1. Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    0f4600a View commit details

Commits on Dec 21, 2020

  1. Merge pull request #389 from miek/nth_edge_burst

    AgilentOscilloscope: support Nth edge burst trigger
    azonenberg authored Dec 21, 2020
    Copy the full SHA
    fc1e983 View commit details
Showing with 272 additions and 1 deletion.
  1. +95 −1 scopehal/AgilentOscilloscope.cpp
  2. +5 −0 scopehal/AgilentOscilloscope.h
  3. +1 −0 scopehal/CMakeLists.txt
  4. +87 −0 scopehal/NthEdgeBurstTrigger.cpp
  5. +82 −0 scopehal/NthEdgeBurstTrigger.h
  6. +2 −0 scopehal/scopehal.cpp
96 changes: 95 additions & 1 deletion scopehal/AgilentOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
#include "AgilentOscilloscope.h"
#include "EdgeTrigger.h"
#include "PulseWidthTrigger.h"
#include "NthEdgeBurstTrigger.h"

using namespace std;

@@ -683,6 +684,8 @@ void AgilentOscilloscope::PullTrigger()
PullEdgeTrigger();
else if (reply == "GLIT")
PullPulseWidthTrigger();
else if (reply == "EBUR")
PullNthEdgeBurstTrigger();

//Unrecognized trigger type
else
@@ -730,6 +733,47 @@ void AgilentOscilloscope::PullEdgeTrigger()
GetTriggerSlope(et, m_transport->ReadReply());
}

void AgilentOscilloscope::PullNthEdgeBurstTrigger()
{
//Clear out any triggers of the wrong type
if( (m_trigger != NULL) && (dynamic_cast<NthEdgeBurstTrigger*>(m_trigger) != NULL) )
{
delete m_trigger;
m_trigger = NULL;
}

//Create a new trigger if necessary
if(m_trigger == NULL)
m_trigger = new NthEdgeBurstTrigger(this);
auto bt = dynamic_cast<NthEdgeBurstTrigger*>(m_trigger);

lock_guard<recursive_mutex> lock(m_mutex);

//Source
m_transport->SendCommand("TRIG:EDGE:SOUR?");
string reply = m_transport->ReadReply();
auto chan = GetChannelByHwName(reply);
bt->SetInput(0, StreamDescriptor(chan, 0), true);
if(!chan)
LogWarning("Unknown trigger source %s\n", reply.c_str());

//Level
m_transport->SendCommand("TRIG:EDGE:LEV?");
bt->SetLevel(stof(m_transport->ReadReply()));

//Slope
m_transport->SendCommand("TRIG:EBUR:SLOP?");
GetTriggerSlope(bt, m_transport->ReadReply());

//Idle time
m_transport->SendCommand("TRIG:EBUR:IDLE?");
bt->SetIdleTime(stof(m_transport->ReadReply()) * FS_PER_SECOND);

//Edge number
m_transport->SendCommand("TRIG:EBUR:COUN?");
bt->SetEdgeNumber(stoi(m_transport->ReadReply()));
}

void AgilentOscilloscope::PullPulseWidthTrigger()
{
//Clear out any triggers of the wrong type
@@ -815,6 +859,19 @@ void AgilentOscilloscope::GetTriggerSlope(EdgeTrigger* trig, string reply)
LogWarning("Unknown trigger slope %s\n", reply.c_str());
}

/**
@brief Processes the slope for an Nth edge burst trigger
*/
void AgilentOscilloscope::GetTriggerSlope(NthEdgeBurstTrigger* trig, string reply)
{
if (reply == "POS")
trig->SetSlope(NthEdgeBurstTrigger::EDGE_RISING);
else if (reply == "NEG")
trig->SetSlope(NthEdgeBurstTrigger::EDGE_FALLING);
else
LogWarning("Unknown trigger slope %s\n", reply.c_str());
}

/**
@brief Parses a trigger condition
*/
@@ -835,9 +892,12 @@ Trigger::Condition AgilentOscilloscope::GetCondition(string reply)

void AgilentOscilloscope::PushTrigger()
{
auto bt = dynamic_cast<NthEdgeBurstTrigger*>(m_trigger);
auto pt = dynamic_cast<PulseWidthTrigger*>(m_trigger);
auto et = dynamic_cast<EdgeTrigger*>(m_trigger);
if(pt)
if(bt)
PushNthEdgeBurstTrigger(bt);
else if(pt)
PushPulseWidthTrigger(pt);
// Must go last
else if(et)
@@ -867,6 +927,22 @@ void AgilentOscilloscope::PushEdgeTrigger(EdgeTrigger* trig)
PushSlope("TRIG:SLOPE", trig->GetType());
}

/**
@brief Pushes settings for a Nth edge burst trigger to the instrument
*/
void AgilentOscilloscope::PushNthEdgeBurstTrigger(NthEdgeBurstTrigger* trig)
{
lock_guard<recursive_mutex> lock(m_mutex);

m_transport->SendCommand("TRIG:MODE EBUR");
m_transport->SendCommand("TRIG:EDGE:SOURCE " +
trig->GetInput(0).m_channel->GetHwname());
PushFloat("TRIG:EDGE:LEV", trig->GetLevel());
PushSlope("TRIG:EBUR:SLOP", trig->GetSlope());
PushFloat("TRIG:EBUR:IDLE", trig->GetIdleTime() * SECONDS_PER_FS);
m_transport->SendCommand("TRIG:EBUR:COUNT " + to_string(trig->GetEdgeNumber()));
}

/**
@brief Pushes settings for a pulse width trigger to the instrument
*/
@@ -942,11 +1018,29 @@ void AgilentOscilloscope::PushSlope(string path, EdgeTrigger::EdgeType slope)
m_transport->SendCommand(path + " " + slope_str);
}

void AgilentOscilloscope::PushSlope(string path, NthEdgeBurstTrigger::EdgeType slope)
{
string slope_str;
switch(slope)
{
case EdgeTrigger::EDGE_RISING:
slope_str = "POS";
break;
case EdgeTrigger::EDGE_FALLING:
slope_str = "NEG";
break;
default:
return;
}
m_transport->SendCommand(path + " " + slope_str);
}

vector<string> AgilentOscilloscope::GetTriggerTypes()
{
vector<string> ret;
ret.push_back(EdgeTrigger::GetTriggerName());
ret.push_back(PulseWidthTrigger::GetTriggerName());
ret.push_back(NthEdgeBurstTrigger::GetTriggerName());
return ret;
}

5 changes: 5 additions & 0 deletions scopehal/AgilentOscilloscope.h
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@

#include "EdgeTrigger.h"
#include "PulseWidthTrigger.h"
#include "NthEdgeBurstTrigger.h"

class AgilentOscilloscope : public SCPIOscilloscope
{
@@ -112,16 +113,20 @@ class AgilentOscilloscope : public SCPIOscilloscope
bool m_triggerOneShot;

void PullEdgeTrigger();
void PullNthEdgeBurstTrigger();
void PullPulseWidthTrigger();

void GetTriggerSlope(EdgeTrigger* trig, std::string reply);
void GetTriggerSlope(NthEdgeBurstTrigger* trig, std::string reply);
Trigger::Condition GetCondition(std::string reply);

void PushEdgeTrigger(EdgeTrigger* trig);
void PushNthEdgeBurstTrigger(NthEdgeBurstTrigger* trig);
void PushPulseWidthTrigger(PulseWidthTrigger* trig);
void PushCondition(std::string path, Trigger::Condition cond);
void PushFloat(std::string path, float f);
void PushSlope(std::string path, EdgeTrigger::EdgeType slope);
void PushSlope(std::string path, NthEdgeBurstTrigger::EdgeType slope);

public:
static std::string GetDriverNameInternal();
1 change: 1 addition & 0 deletions scopehal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -56,6 +56,7 @@ set(SCOPEHAL_SOURCES
DropoutTrigger.cpp
EdgeTrigger.cpp
GlitchTrigger.cpp
NthEdgeBurstTrigger.cpp
PulseWidthTrigger.cpp
RuntTrigger.cpp
SerialTrigger.cpp
87 changes: 87 additions & 0 deletions scopehal/NthEdgeBurstTrigger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2020 Mike Walters *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

#include "scopehal.h"
#include "NthEdgeBurstTrigger.h"

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Construction / destruction

NthEdgeBurstTrigger::NthEdgeBurstTrigger(Oscilloscope* scope)
: Trigger(scope)
{
CreateInput("din");

m_slopename = "Slope";
m_parameters[m_slopename] = FilterParameter(FilterParameter::TYPE_ENUM, Unit(Unit::UNIT_COUNTS));
m_parameters[m_slopename].AddEnumValue("Rising", EDGE_RISING);
m_parameters[m_slopename].AddEnumValue("Falling", EDGE_FALLING);

m_idletimename = "Idle time";
m_parameters[m_idletimename] = FilterParameter(FilterParameter::TYPE_INT, Unit(Unit::UNIT_FS));

m_edgenumbername = "Edge number";
m_parameters[m_edgenumbername] = FilterParameter(FilterParameter::TYPE_INT, Unit(Unit::UNIT_COUNTS));

}

NthEdgeBurstTrigger::~NthEdgeBurstTrigger()
{

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Accessors

string NthEdgeBurstTrigger::GetTriggerName()
{
return "Nth Edge Burst";
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Input validation

bool NthEdgeBurstTrigger::ValidateChannel(size_t i, StreamDescriptor stream)
{
//We only can take one input
if(i > 0)
return false;

//There has to be a signal to trigger on
if(stream.m_channel == NULL)
return false;

//It has to be from the same instrument we're trying to trigger on
if(stream.m_channel->GetScope() != m_scope)
return false;

return true;
}
82 changes: 82 additions & 0 deletions scopehal/NthEdgeBurstTrigger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2020 Mike Walters *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
* following conditions are met: *
* *
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
* following disclaimer. *
* *
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
* following disclaimer in the documentation and/or other materials provided with the distribution. *
* *
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
* derived from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
***********************************************************************************************************************/

/**
@file
@author Mike Walters
@brief Declaration of NthEdgeBurstTrigger
*/
#ifndef NthEdgeBurstTrigger_h
#define NthEdgeBurstTrigger_h

/**
@brief Nth Edge Burst Trigger
*/
class NthEdgeBurstTrigger : public Trigger
{
public:
NthEdgeBurstTrigger(Oscilloscope* scope);
virtual ~NthEdgeBurstTrigger();

enum EdgeType
{
EDGE_RISING,
EDGE_FALLING,
};

void SetSlope(EdgeType type)
{ m_parameters[m_slopename].SetIntVal(type); }

EdgeType GetSlope()
{ return (EdgeType) m_parameters[m_slopename].GetIntVal(); }

void SetIdleTime(int64_t idle)
{ m_parameters[m_idletimename].SetIntVal(idle); }

int64_t GetIdleTime()
{ return m_parameters[m_idletimename].GetIntVal(); }

void SetEdgeNumber(int64_t edge)
{ m_parameters[m_edgenumbername].SetIntVal(edge); }

int64_t GetEdgeNumber()
{ return m_parameters[m_edgenumbername].GetIntVal(); }

virtual bool ValidateChannel(size_t i, StreamDescriptor stream);

static std::string GetTriggerName();
TRIGGER_INITPROC(NthEdgeBurstTrigger);

protected:
std::string m_slopename;
std::string m_idletimename;
std::string m_edgenumbername;
};

#endif
2 changes: 2 additions & 0 deletions scopehal/scopehal.cpp
Original file line number Diff line number Diff line change
@@ -50,6 +50,7 @@
#include "DropoutTrigger.h"
#include "EdgeTrigger.h"
#include "GlitchTrigger.h"
#include "NthEdgeBurstTrigger.h"
#include "PulseWidthTrigger.h"
#include "RuntTrigger.h"
#include "SlewRateTrigger.h"
@@ -274,6 +275,7 @@ void DriverStaticInit()
AddTriggerClass(DropoutTrigger);
AddTriggerClass(EdgeTrigger);
AddTriggerClass(GlitchTrigger);
AddTriggerClass(NthEdgeBurstTrigger);
AddTriggerClass(PulseWidthTrigger);
AddTriggerClass(RuntTrigger);
AddTriggerClass(SlewRateTrigger);