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

Commits on Sep 16, 2020

  1. Copy the full SHA
    d41f98d View commit details
Showing with 219 additions and 1 deletion.
  1. +1 −0 scopehal/CMakeLists.txt
  2. +60 −0 scopehal/LeCroyOscilloscope.cpp
  3. +3 −1 scopehal/LeCroyOscilloscope.h
  4. +83 −0 scopehal/WindowTrigger.cpp
  5. +70 −0 scopehal/WindowTrigger.h
  6. +2 −0 scopehal/scopehal.cpp
1 change: 1 addition & 0 deletions scopehal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -38,6 +38,7 @@ set(SCOPEHAL_SOURCES
Trigger.cpp
EdgeTrigger.cpp
PulseWidthTrigger.cpp
WindowTrigger.cpp

Instrument.cpp
FunctionGenerator.cpp
60 changes: 60 additions & 0 deletions scopehal/LeCroyOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -36,6 +36,7 @@

#include "EdgeTrigger.h"
#include "PulseWidthTrigger.h"
#include "WindowTrigger.h"

using namespace std;

@@ -3139,6 +3140,8 @@ void LeCroyOscilloscope::PullTrigger()
PullEdgeTrigger();
else if (reply == "Width")
PullPulseWidthTrigger();
else if (reply == "Window")
PullWindowTrigger();

//Unrecognized trigger type
else
@@ -3257,6 +3260,33 @@ void LeCroyOscilloscope::ProcessTriggerSlope(EdgeTrigger* trig, string reply)
LogWarning("Unknown trigger slope %s\n", reply.c_str());
}

/**
@brief Reads settings for a window trigger from the instrument
*/
void LeCroyOscilloscope::PullWindowTrigger()
{
//Clear out any triggers of the wrong type
if( (m_trigger != NULL) && (dynamic_cast<WindowTrigger*>(m_trigger) != NULL) )
{
delete m_trigger;
m_trigger = NULL;
}

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

//Lower bound
Unit v(Unit::UNIT_VOLTS);
m_transport->SendCommand("VBS? 'return = app.Acquisition.Trigger.Window.LowerLevel'");
wt->SetLowerBound(v.ParseString(m_transport->ReadReply()));

//Upper bound
m_transport->SendCommand("VBS? 'return = app.Acquisition.Trigger.Window.UpperLevel'");
wt->SetUpperBound(v.ParseString(m_transport->ReadReply()));
}

void LeCroyOscilloscope::PushTrigger()
{
lock_guard<recursive_mutex> lock(m_mutex);
@@ -3273,6 +3303,7 @@ void LeCroyOscilloscope::PushTrigger()
//The rest depends on the type
auto et = dynamic_cast<EdgeTrigger*>(m_trigger);
auto pt = dynamic_cast<PulseWidthTrigger*>(m_trigger);
auto wt = dynamic_cast<WindowTrigger*>(m_trigger);
if(pt)
{
m_transport->SendCommand("VBS? 'app.Acquisition.Trigger.Type = \"Width\"");
@@ -3283,6 +3314,11 @@ void LeCroyOscilloscope::PushTrigger()
m_transport->SendCommand("VBS? 'app.Acquisition.Trigger.Type = \"Edge\"");
PushEdgeTrigger(et, "app.Acquisition.Trigger.Edge");
}
else if(wt)
{
m_transport->SendCommand("VBS? 'app.Acquisition.Trigger.Type = \"Window\"");
PushWindowTrigger(wt);
}

else
LogWarning("Unknown trigger type (not an edge)\n");
@@ -3370,6 +3406,29 @@ void LeCroyOscilloscope::PushPulseWidthTrigger(PulseWidthTrigger* trig)
m_transport->SendCommand(tmp);
}

/**
@brief Pushes settings for a window trigger to the instrument
*/
void LeCroyOscilloscope::PushWindowTrigger(WindowTrigger* trig)
{
//Lower bound
char tmp[128];
snprintf(
tmp,
sizeof(tmp),
"VBS? 'app.Acquisition.Trigger.Window.LowerLevel = %f'",
trig->GetLowerBound());
m_transport->SendCommand(tmp);

//Upper bound bound
snprintf(
tmp,
sizeof(tmp),
"VBS? 'app.Acquisition.Trigger.Window.UpperLevel = %f'",
trig->GetUpperBound());
m_transport->SendCommand(tmp);
}

/**
@brief Removes whitespace from the start and end of a string
*/
@@ -3407,6 +3466,7 @@ vector<string> LeCroyOscilloscope::GetTriggerTypes()
vector<string> ret;
ret.push_back(EdgeTrigger::GetTriggerName());
ret.push_back(PulseWidthTrigger::GetTriggerName());
ret.push_back(WindowTrigger::GetTriggerName());

//TODO m_hasI2cTrigger m_hasSpiTrigger m_hasUartTrigger
return ret;
4 changes: 3 additions & 1 deletion scopehal/LeCroyOscilloscope.h
Original file line number Diff line number Diff line change
@@ -31,10 +31,10 @@
#define LeCroyOscilloscope_h

#include <mutex>
#include "../xptools/Socket.h"

class EdgeTrigger;
class PulseWidthTrigger;
class WindowTrigger;

/**
@brief A Teledyne LeCroy oscilloscope using the MAUI/XStream command set.
@@ -203,11 +203,13 @@ class LeCroyOscilloscope
protected:
void PullEdgeTrigger();
void PullPulseWidthTrigger();
void PullWindowTrigger();
void PullTriggerSource(Trigger* trig);
void ProcessTriggerSlope(EdgeTrigger* trig, std::string reply);

void PushEdgeTrigger(EdgeTrigger* trig, std::string tree);
void PushPulseWidthTrigger(PulseWidthTrigger* trig);
void PushWindowTrigger(WindowTrigger* trig);

void BulkCheckChannelEnableState();

83 changes: 83 additions & 0 deletions scopehal/WindowTrigger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* 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 "WindowTrigger.h"

using namespace std;

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

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

//Redefine the upper level signal name
m_parameters.clear();
m_levelname = "Upper Bound";
m_parameters[m_levelname] = FilterParameter(FilterParameter::TYPE_FLOAT, Unit(Unit::UNIT_VOLTS));

m_lowername = "Lower Bound";
m_parameters[m_lowername] = FilterParameter(FilterParameter::TYPE_FLOAT, Unit(Unit::UNIT_VOLTS));
}

WindowTrigger::~WindowTrigger()
{

}

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

string WindowTrigger::GetTriggerName()
{
return "Window";
}

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

bool WindowTrigger::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;
}
70 changes: 70 additions & 0 deletions scopehal/WindowTrigger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/***********************************************************************************************************************
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2020 Andrew D. Zonenberg *
* 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 Andrew D. Zonenberg
@brief Declaration of WindowTrigger
*/
#ifndef WindowTrigger_h
#define WindowTrigger_h

/**
@brief Window trigger - detect when the signal leaves a specified range
*/
class WindowTrigger : public Trigger
{
public:
WindowTrigger(Oscilloscope* scope);
virtual ~WindowTrigger();

virtual bool ValidateChannel(size_t i, StreamDescriptor stream);

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

//Upper bound of range is the base class "trigger level"
float GetUpperBound()
{ return GetLevel(); }

void SetUpperBound(float f)
{ SetLevel(f); }

//Lower bound
float GetLowerBound()
{ return m_parameters[m_lowername].GetFloatVal(); }

void SetLowerBound(float level)
{ m_parameters[m_lowername].SetFloatVal(level); }

protected:
std::string m_lowername;
};

#endif
2 changes: 2 additions & 0 deletions scopehal/scopehal.cpp
Original file line number Diff line number Diff line change
@@ -48,6 +48,7 @@

#include "EdgeTrigger.h"
#include "PulseWidthTrigger.h"
#include "WindowTrigger.h"

#ifndef _WIN32
#include <dlfcn.h>
@@ -118,6 +119,7 @@ void DriverStaticInit()

AddTriggerClass(EdgeTrigger);
AddTriggerClass(PulseWidthTrigger);
AddTriggerClass(WindowTrigger);
}

string GetDefaultChannelColor(int i)