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: 2c1fba224d6b
Choose a base ref
...
head repository: ngscopeclient/scopehal
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 66155fdda952
Choose a head ref

Commits on Feb 24, 2020

  1. [WIP] Agilent

    miek committed Feb 24, 2020

    Unverified

    This user has not yet uploaded their public signing key.
    Copy the full SHA
    2f6fbe1 View commit details
  2. agilent: Correct y offsets

    miek committed Feb 24, 2020
    Copy the full SHA
    8a22aaf View commit details
  3. Copy the full SHA
    0a6a3de View commit details
  4. agilent: Query trigger level

    miek committed Feb 24, 2020
    Copy the full SHA
    cd5b177 View commit details
  5. Copy the full SHA
    6883bfb View commit details
  6. agilent: Get 16-bit data

    miek committed Feb 24, 2020
    Copy the full SHA
    e5e40f6 View commit details
  7. Copy the full SHA
    6c87b19 View commit details
  8. Copy the full SHA
    cb9ee60 View commit details
  9. agilent: Fix polling

    miek committed Feb 24, 2020
    Copy the full SHA
    b5157ab View commit details
  10. agilent: Set trigger voltage

    miek committed Feb 24, 2020
    Copy the full SHA
    32962a3 View commit details
  11. Copy the full SHA
    f84e637 View commit details
  12. Copy the full SHA
    50097fe View commit details
  13. Copy the full SHA
    55d44bb View commit details
  14. Copy the full SHA
    f157e3d View commit details

Commits on Feb 25, 2020

  1. agilent; Fix trace colours

    miek committed Feb 25, 2020
    Copy the full SHA
    3fdea66 View commit details
  2. agilent: Update copyright string

    miek committed Feb 25, 2020
    Copy the full SHA
    fe1ae2d View commit details
  3. Copy the full SHA
    3fa5d2d View commit details
  4. Copy the full SHA
    51ab695 View commit details
  5. Copy the full SHA
    1beb09f View commit details
  6. Copy the full SHA
    3d7fbfa View commit details
  7. Merge pull request #91 from miek/agilent

    Initial Agilent 5/6/7000 series support (see #74)
    azonenberg authored Feb 25, 2020
    Copy the full SHA
    c6e83f7 View commit details
  8. Copy the full SHA
    f26436c View commit details
  9. Copy the full SHA
    7aa15f2 View commit details
  10. Copy the full SHA
    29d855a View commit details
  11. Copy the full SHA
    cf07d14 View commit details
  12. Removed a bunch of bitrotted Cairo rendering code that's no longer be…

    …ing used and caused problems with new warning mode
    azonenberg committed Feb 25, 2020
    Copy the full SHA
    77af237 View commit details
  13. scopehal/AgilentOscilloscope: Improve model number parsing robustness

    The model number don't all have the same format. Here we just strip all
    non-digit and then convert to int to get the model number. (and derive
    the number of channels)
    
    Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
    smunaut committed Feb 25, 2020
    Copy the full SHA
    3264cc5 View commit details
  14. scopehal/AgilentOscilloscope: Improve option parsing

    - This removes the "(d)" at the end of options that denote demo options
    - This removes the weird "0" meaningless options that the MOSX 3000
      returns
    
    Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
    smunaut committed Feb 25, 2020
    Copy the full SHA
    a935f29 View commit details
  15. scopehal/AgilentOscilloscope: In PollTrigger, check if armed

    If we're waiting for a trigger at all, then a non-run mode means
    nothing ...
    
    Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
    smunaut committed Feb 25, 2020
    Copy the full SHA
    c101f3b View commit details
  16. Merge pull request #92 from smunaut/msox

    Agilent Improvement to make it work on MSOX 3000 series
    azonenberg authored Feb 25, 2020
    Copy the full SHA
    36404a5 View commit details
  17. scopehal/AgilentScope: Fix build warnings

    Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
    smunaut committed Feb 25, 2020
    Copy the full SHA
    c3f9343 View commit details
  18. Merge pull request #93 from smunaut/msox

    scopehal/AgilentScope: Fix build warnings
    azonenberg authored Feb 25, 2020
    Copy the full SHA
    d8b29ef View commit details

Commits on Feb 26, 2020

  1. acquire data work

    four0four committed Feb 26, 2020
    Copy the full SHA
    febc879 View commit details
  2. acquire data work

    four0four committed Feb 26, 2020
    Copy the full SHA
    774cb57 View commit details
  3. Copy the full SHA
    66155fd View commit details
2 changes: 1 addition & 1 deletion graphwidget
677 changes: 677 additions & 0 deletions scopehal/AgilentOscilloscope.cpp

Large diffs are not rendered by default.

121 changes: 72 additions & 49 deletions scopeprotocols/EyeDecoder.h → scopehal/AgilentOscilloscope.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* Copyright (c) 2012-2020 Andrew D. Zonenberg, Mike Walters *
* All rights reserved. *
* *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
@@ -27,60 +27,83 @@
* *
***********************************************************************************************************************/

/**
@file
@author Andrew D. Zonenberg
@brief Declaration of EyeDecoder
*/
#ifndef EyeDecoder_h
#define EyeDecoder_h
#ifndef AgilentOscilloscope_h
#define AgilentOscilloscope_h

#include "../scopehal/ProtocolDecoder.h"

class EyeCapture;

class EyeDecoder : public ProtocolDecoder
class AgilentOscilloscope : public SCPIOscilloscope
{
public:
EyeDecoder(std::string color);

virtual void Refresh();
virtual ChannelRenderer* CreateRenderer();

virtual bool NeedsConfig();
virtual bool IsOverlay();

static std::string GetProtocolName();
virtual void SetDefaultName();

virtual bool ValidateChannel(size_t i, OscilloscopeChannel* channel);

int64_t GetUIWidth()
{ return m_uiWidth; }
AgilentOscilloscope(SCPITransport* transport);
virtual ~AgilentOscilloscope();

double GetUIWidthFractional()
{ return m_uiWidthFractional; }

PROTOCOL_DECODER_INITPROC(EyeDecoder)
public:
//Device information
virtual unsigned int GetInstrumentTypes();

virtual void FlushConfigCache();

//Channel configuration
virtual bool IsChannelEnabled(size_t i);
virtual void EnableChannel(size_t i);
virtual void DisableChannel(size_t i);
virtual OscilloscopeChannel::CouplingType GetChannelCoupling(size_t i);
virtual void SetChannelCoupling(size_t i, OscilloscopeChannel::CouplingType type);
virtual double GetChannelAttenuation(size_t i);
virtual void SetChannelAttenuation(size_t i, double atten);
virtual int GetChannelBandwidthLimit(size_t i);
virtual void SetChannelBandwidthLimit(size_t i, unsigned int limit_mhz);
virtual double GetChannelVoltageRange(size_t i);
virtual void SetChannelVoltageRange(size_t i, double range);
virtual OscilloscopeChannel* GetExternalTrigger();
virtual double GetChannelOffset(size_t i);
virtual void SetChannelOffset(size_t i, double offset);

//Triggering
virtual void ResetTriggerConditions();
virtual Oscilloscope::TriggerMode PollTrigger();
virtual bool AcquireData(bool toQueue = false);
virtual void Start();
virtual void StartSingleTrigger();
virtual void Stop();
virtual bool IsTriggerArmed();
virtual size_t GetTriggerChannelIndex();
virtual void SetTriggerChannelIndex(size_t i);
virtual float GetTriggerVoltage();
virtual void SetTriggerVoltage(float v);
virtual Oscilloscope::TriggerType GetTriggerType();
virtual void SetTriggerType(Oscilloscope::TriggerType type);
virtual void SetTriggerForChannel(OscilloscopeChannel* channel, std::vector<TriggerType> triggerbits);

virtual std::vector<uint64_t> GetSampleRatesNonInterleaved();
virtual std::vector<uint64_t> GetSampleRatesInterleaved();
virtual std::set<InterleaveConflict> GetInterleaveConflicts();
virtual std::vector<uint64_t> GetSampleDepthsNonInterleaved();
virtual std::vector<uint64_t> GetSampleDepthsInterleaved();

protected:
int64_t m_uiWidth; //integer samples
double m_uiWidthFractional; //fractional samples, for more precision over long captures

bool DetectModulationLevels(AnalogCapture* din, EyeCapture* cap);
bool CalculateUIWidth(AnalogCapture* din, EyeCapture* cap);

bool MeasureEyeOpenings(
EyeCapture* cap,
std::map<int64_t, std::map<float, int64_t> >& pixmap);

bool GenerateEyeData(
AnalogCapture* din,
EyeCapture* cap,
std::map<int64_t, std::map<float, int64_t> >& pixmap);

bool MeasureRiseFallTimes(AnalogCapture* din, EyeCapture* cap);
int GetCodeForVoltage(float v, EyeCapture* cap);
OscilloscopeChannel* m_extTrigChannel;

//Mutexing for thread safety
std::recursive_mutex m_mutex;
std::recursive_mutex m_cacheMutex;

//hardware analog channel count, independent of LA option etc
unsigned int m_analogChannelCount;

//config cache
std::map<size_t, double> m_channelOffsets;
std::map<size_t, double> m_channelVoltageRanges;
std::map<size_t, OscilloscopeChannel::CouplingType> m_channelCouplings;
std::map<size_t, double> m_channelAttenuations;
std::map<size_t, int> m_channelBandwidthLimits;
std::map<int, bool> m_channelsEnabled;
bool m_triggerChannelValid;
size_t m_triggerChannel;
bool m_triggerLevelValid;
float m_triggerLevel;

bool m_triggerArmed;
bool m_triggerOneShot;
};

#endif
179 changes: 14 additions & 165 deletions scopehal/AnalogRenderer.cpp
Original file line number Diff line number Diff line change
@@ -53,146 +53,36 @@ AnalogRenderer::AnalogRenderer(OscilloscopeChannel* channel)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Rendering

float AnalogRenderer::pixels_to_volts(float p, bool offset)
{
float plotheight = m_height - 2*m_padding;
p = ( p / (plotheight * m_yscale) );

if(offset)
return p - m_yoffset;
else
return p;
}

float AnalogRenderer::volts_to_pixels(float v, bool offset)
{
float plotheight = m_height - 2*m_padding;
if(offset)
v += m_yoffset;
return v * plotheight * m_yscale;
}

void AnalogRenderer::RenderStartCallback(
const Cairo::RefPtr<Cairo::Context>& cr,
int width,
int visleft,
int visright,
vector<time_range>& ranges)
const Cairo::RefPtr<Cairo::Context>& /*cr*/,
int /*width*/,
int /*visleft*/,
int /*visright*/,
vector<time_range>& /*ranges*/)
{
ChannelRenderer::RenderStartCallback(cr, width, visleft, visright, ranges);

float ytop = m_ypos + m_padding;
float ybot = m_ypos + m_height - m_padding;
float plotheight = m_height - 2*m_padding;
float halfheight = plotheight/2;
float ymid = halfheight + ytop;

//Volts from the center line of our graph to the top. May not be the max value in the signal.
float volts_per_half_span = pixels_to_volts(halfheight, false);

//Decide what voltage step to use. Pick from a list (in volts)
float selected_step = PickStepSize(volts_per_half_span);

//Calculate grid positions
m_gridmap.clear();
m_gridmap[0] = 0;
for(float dv=0; ; dv += selected_step)
{
//Need to flip signs on offset so it goes in the right direction all the time
float yt = ymid - volts_to_pixels(dv + m_yoffset, false);
float yb = ymid + volts_to_pixels(dv - m_yoffset, false);

//Stop if we're off the edge
if( (yb > ybot) && (yt < ytop) )
break;

if(yb <= ybot)
m_gridmap[-dv] = yb;
if(yt >= ytop)
m_gridmap[dv] = yt;
}

//Center line is solid
cr->set_source_rgba(0.7, 0.7, 0.7, 1.0);
cr->move_to(visleft, ymid - volts_to_pixels(0));
cr->line_to(visright, ymid - volts_to_pixels(0));
cr->stroke();

//Dotted lines above and below
vector<double> dashes;
dashes.push_back(2);
dashes.push_back(2);
cr->set_dash(dashes, 0);
for(auto it : m_gridmap)
{
if(it.second == ymid) //no dots on center line
continue;
cr->move_to(visleft, it.second);
cr->line_to(visright, it.second);
}
cr->stroke();
cr->unset_dash();
//no longer used, will be removed in future refactoring
}

void AnalogRenderer::RenderSampleCallback(
const Cairo::RefPtr<Cairo::Context>& cr,
size_t i,
float xstart,
float xend,
const Cairo::RefPtr<Cairo::Context>& /*cr*/,
size_t /*i*/,
float /*xstart*/,
float /*xend*/,
int /*visleft*/,
int /*visright*/
)
{
float ytop = m_ypos + m_padding;
float ybot = m_ypos + m_height - m_padding;
float plotheight = m_height - 2*m_padding;
float halfheight = plotheight/2;
float ymid = halfheight + ytop;

AnalogCapture* capture = dynamic_cast<AnalogCapture*>(m_channel->GetData());
if(capture == NULL)
return;

const AnalogSample& sample = capture->m_samples[i];

//Calculate position. If the sample would go off the edge of our render, crop it
//0 volts is by default the center of our display area
float y = ymid - volts_to_pixels(sample.m_sample);
if(y < ytop)
y = ytop;
if(y > ybot)
y = ybot;

//Move to initial position if first sample
if(i == 0)
cr->move_to(xstart, y);

//Draw at the middle
float xmid = (xend-xstart)/2 + xstart;

//Render
cr->line_to(xmid, y);
//no longer used, will be removed in future refactoring
}

void AnalogRenderer::RenderEndCallback(
const Cairo::RefPtr<Cairo::Context>& cr,
const Cairo::RefPtr<Cairo::Context>& /*cr*/,
int /*width*/,
int /*visleft*/,
int visright,
int /*visright*/,
vector<time_range>& /*ranges*/)
{
float ytop = m_ypos + m_padding;
float plotheight = m_height - 2*m_padding;

//Draw the actual plot
Gdk::Color color(m_channel->m_displaycolor);
cr->set_source_rgb(color.get_red_p(), color.get_green_p(), color.get_blue_p());
cr->stroke();

//and then the text for the Y axis scale
DrawVerticalAxisLabels(cr, visright, ytop, plotheight, m_gridmap);

cr->restore();
//no longer used, will be removed in future refactoring
}

float AnalogRenderer::PickStepSize(float volts_per_half_span, int min_steps, int max_steps)
@@ -247,44 +137,3 @@ float AnalogRenderer::PickStepSize(float volts_per_half_span, int min_steps, int
//if no hits
return 1;
}

void AnalogRenderer::DrawVerticalAxisLabels(
const Cairo::RefPtr<Cairo::Context>& cr,
int visright,
float ytop,
float plotheight,
map<float, float>& gridmap,
bool show_units)
{
//Draw background for the Y axis labels
int lineheight, linewidth;
GetStringWidth(cr, "500 mV_xxx", false, linewidth, lineheight);
float lmargin = 5;
float textleft = visright - (linewidth + lmargin);
cr->set_source_rgba(0, 0, 0, 0.5);
cr->rectangle(textleft, ytop, linewidth, plotheight);
cr->fill();

//Draw text for the Y axis labels
cr->set_source_rgba(1.0, 1.0, 1.0, 1.0);
for(auto it : gridmap)
{
float v = it.first;
char tmp[32];

if(!show_units)
snprintf(tmp, sizeof(tmp), "%.0f", v);
else if(fabs(v) < 1)
snprintf(tmp, sizeof(tmp), "%.0f mV", v*1000);
else
snprintf(tmp, sizeof(tmp), "%.3f V", v);

float y = it.second - lineheight/2;
if(y < ytop)
continue;
if(y > (ytop + plotheight))
continue;
DrawString(textleft + lmargin, y, cr, tmp, false);
}
cr->begin_new_path();
}
13 changes: 0 additions & 13 deletions scopehal/AnalogRenderer.h
Original file line number Diff line number Diff line change
@@ -71,21 +71,8 @@ class AnalogRenderer : public ChannelRenderer
float m_yscale;
float m_yoffset;

protected:
std::map<float, float> m_gridmap;
float pixels_to_volts(float p, bool offset = true);
float volts_to_pixels(float v, bool offset = true);

public:
static float PickStepSize(float volts_per_half_span, int min_steps = 2, int max_steps = 5);

static void DrawVerticalAxisLabels(
const Cairo::RefPtr<Cairo::Context>& cr,
int visright,
float ytop,
float plotheight,
std::map<float, float>& gridmap,
bool show_units = true);
};

#endif
1 change: 1 addition & 0 deletions scopehal/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ set(SCOPEHAL_SOURCES
Oscilloscope.cpp
SCPIOscilloscope.cpp
OscilloscopeChannel.cpp
AgilentOscilloscope.cpp
AntikernelLogicAnalyzer.cpp
LeCroyOscilloscope.cpp
LeCroyVICPOscilloscope.cpp
22 changes: 4 additions & 18 deletions scopehal/ChannelRenderer.cpp
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2017 Andrew D. Zonenberg *
* 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 *
@@ -79,20 +79,6 @@ void ChannelRenderer::MakePathSignalBody(
if(xstart + 2*rounding > xend)
rounding = (xend - xstart) / 2;

/*
//If the signal is really tiny, shrink the offset so we dont make Xs
if( (xstart + xoff) > xend)
xoff = (xend - xstart) / 2;
cr->move_to(xstart + xoff, ybot);
cr->line_to(xstart, ymid);
cr->line_to(xstart + xoff, ytop);
cr->line_to(xend - xoff, ytop);
cr->line_to(xend, ymid);
cr->line_to(xend - xoff, ybot);
cr->line_to(xstart + xoff, ybot);
*/

cr->begin_new_sub_path();
cr->arc(xstart + rounding, ytop + rounding, rounding, M_PI, M_PI*1.5f); //top left corner
cr->move_to(xstart + rounding, ytop); //top edge
@@ -116,8 +102,9 @@ void ChannelRenderer::RenderComplexSignal(
string str,
Gdk::Color color)
{
Pango::FontDescription font("sans normal 10");
int width = 0, sheight = 0;
GetStringWidth(cr, str, true, width, sheight);
GetStringWidth(cr, str, width, sheight, font);

//First-order guess of position: center of the value
float xp = xstart + (xend-xstart)/2;
@@ -199,7 +186,7 @@ void ChannelRenderer::RenderComplexSignal(
str_render = "..." + str.substr(str.length() - len - 1);

int twidth = 0, theight = 0;
GetStringWidth(cr, str_render, true, twidth, theight);
GetStringWidth(cr, str_render, twidth, theight, font);
if(twidth < available_width)
{
//Re-center text in available space
@@ -215,7 +202,6 @@ void ChannelRenderer::RenderComplexSignal(
cr->save();
Glib::RefPtr<Pango::Layout> tlayout = Pango::Layout::create (cr);
cr->move_to(xp, ymid - sheight/2);
Pango::FontDescription font("sans normal 10");
font.set_weight(Pango::WEIGHT_NORMAL);
tlayout->set_font_description(font);
tlayout->set_text(str_render);
53 changes: 1 addition & 52 deletions scopehal/LeCroyOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -66,58 +66,7 @@ void LeCroyOscilloscope::SharedCtorInit()
true);
m_channels.push_back(m_extTrigChannel);

//Desired format for waveform data
//Only use increased bit depth if the scope actually puts content there!
if(m_highDefinition)
SendCommand("COMM_FORMAT DEF9,WORD,BIN");
else
SendCommand("COMM_FORMAT DEF9,BYTE,BIN");

//Clear the state-change register to we get rid of any history we don't care about
PollTrigger();
}

void LeCroyOscilloscope::IdentifyHardware()
{
//Turn off headers (complicate parsing and add fluff to the packets)
SendCommand("CHDR OFF", true);

//Ask for the ID
SendCommand("*IDN?", true);
string reply = ReadSingleBlockString();
char vendor[128] = "";
char model[128] = "";
char serial[128] = "";
char version[128] = "";
if(4 != sscanf(reply.c_str(), "%127[^,],%127[^,],%127[^,],%127s", vendor, model, serial, version))
{
LogError("Bad IDN response %s\n", reply.c_str());
return;
}
m_vendor = vendor;
m_model = model;
m_serial = serial;
m_fwVersion = version;

//Look up model info
if(m_model.find("WS3") == 0)
m_modelid = MODEL_WAVESURFER_3K;
else if(m_model.find("HDO9") == 0)
m_modelid = MODEL_HDO_9K;
else if(m_model.find("DDA5") == 0)
m_modelid = MODEL_DDA_5K;
else if(m_model.find("WAVERUNNER8") == 0)
m_modelid = MODEL_WAVERUNNER_8K;
else
m_modelid = MODEL_UNKNOWN;

//TODO: better way of doing this?
if(m_model.find("HD") != string::npos)
m_highDefinition = true;
}

void LeCroyOscilloscope::DetectOptions()
{
//Look at options and see if we have digital channels too
SendCommand("*OPT?", true);
string reply = ReadSingleBlockString(true);
if(reply.length() > 3)
90 changes: 0 additions & 90 deletions scopehal/build.yml

This file was deleted.

2 changes: 0 additions & 2 deletions scopeprotocols/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -16,9 +16,7 @@ set(SCOPEPROTOCOLS_SOURCES
EthernetAutonegotiationRenderer.cpp
EthernetProtocolDecoder.cpp
EthernetRenderer.cpp
EyeDecoder.cpp
EyeDecoder2.cpp
EyeRenderer.cpp
FFTDecoder.cpp
I2CDecoder.cpp
I2CRenderer.cpp
814 changes: 0 additions & 814 deletions scopeprotocols/EyeDecoder.cpp

This file was deleted.

151 changes: 149 additions & 2 deletions scopeprotocols/EyeDecoder2.cpp
Original file line number Diff line number Diff line change
@@ -29,7 +29,6 @@

#include "../scopehal/scopehal.h"
#include "EyeDecoder2.h"
#include "EyeRenderer.h"
#include <algorithm>

using namespace std;
@@ -150,7 +149,7 @@ EyeDecoder2::EyeDecoder2(string color)

ChannelRenderer* EyeDecoder2::CreateRenderer()
{
return new EyeRenderer(this);
return NULL;
}

bool EyeDecoder2::ValidateChannel(size_t i, OscilloscopeChannel* channel)
@@ -198,6 +197,154 @@ double EyeDecoder2::GetVoltageRange()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Actual decoder logic

/*
bool EyeDecoder::DetectModulationLevels(AnalogCapture* din, EyeCapture* cap)
{
LogDebug("Detecting modulation levels\n");
LogIndenter li;
//Find the min/max voltage of the signal (used to set default bounds for the render).
//Additionally, generate a histogram of voltages. We need this to configure the trigger(s) correctly
//and do measurements on the eye opening(s) - since MLT-3, PAM-x, etc have multiple openings.
cap->m_minVoltage = 999;
cap->m_maxVoltage = -999;
map<int, int64_t> vhist; //1 mV bins
for(size_t i=0; i<din->m_samples.size(); i++)
{
AnalogSample sin = din->m_samples[i];
float f = sin;
vhist[f * 1000] ++;
if(f > cap->m_maxVoltage)
cap->m_maxVoltage = f;
if(f < cap->m_minVoltage)
cap->m_minVoltage = f;
}
LogDebug("Voltage range is %.3f to %.3f V\n", cap->m_minVoltage, cap->m_maxVoltage);
//Crunch the histogram to find the number of signal levels in use.
//We're looking for peaks of significant height (25% of maximum or more) and not too close to another peak.
float dv = cap->m_maxVoltage - cap->m_minVoltage;
int neighborhood = floor(dv * 50); //dV/20 converted to mV
LogDebug("Looking for levels at least %d mV apart\n", neighborhood);
int64_t maxpeak = 0;
for(auto it : vhist)
{
if(it.second > maxpeak)
maxpeak = it.second;
}
LogDebug("Highest histogram peak is %ld points\n", maxpeak);
int64_t peakthresh = maxpeak/8;
int64_t second_peak = 0;
double second_weighted = 0;
for(auto it : vhist)
{
int64_t count = it.second;
//If we're pretty close to a taller peak (within neighborhood mV) then don't do anything
int mv = it.first;
bool bigger = false;
for(int v=mv-neighborhood; v<=mv+neighborhood; v++)
{
auto jt = vhist.find(v);
if(jt == vhist.end())
continue;
if(jt->second > count)
{
bigger = true;
continue;
}
}
if(bigger)
continue;
//Search the neighborhood around us and do a weighted average to find the center of the bin
int64_t weighted = 0;
int64_t wcount = 0;
for(int v=mv-neighborhood; v<=mv+neighborhood; v++)
{
auto jt = vhist.find(v);
if(jt == vhist.end())
continue;
int64_t c = jt->second;
wcount += c;
weighted += c*v;
}
if(count < peakthresh)
{
//Skip peaks that aren't tall enough... but still save the second highest
if(count > second_peak)
{
second_peak = count;
second_weighted = weighted * 1e-3f / wcount;
}
continue;
}
cap->m_signalLevels.push_back(weighted * 1e-3f / wcount);
}
//Special case: if the signal has only one level it might be NRZ with a really low duty cycle
//Add the second highest peak in this case
if(cap->m_signalLevels.size() == 1)
cap->m_signalLevels.push_back(second_weighted);
sort(cap->m_signalLevels.begin(), cap->m_signalLevels.end());
LogDebug(" Signal appears to be using %d-level modulation\n", (int)cap->m_signalLevels.size());
for(auto v : cap->m_signalLevels)
LogDebug(" %6.3f V\n", v);
//Now that signal levels are sorted, make sure they're spaced well.
//If we have levels that are too close to each other, skip them
for(size_t i=0; i<cap->m_signalLevels.size()-1; i++)
{
float delta = fabs(cap->m_signalLevels[i] - cap->m_signalLevels[i+1]);
LogDebug("Delta at i=%zu is %.3f\n", i, delta);
//TODO: fine tune this threshold adaptively based on overall signal amplitude?
if(delta < 0.175)
{
LogIndenter li;
LogDebug("Too small\n");
//Remove the innermost point (closer to zero)
//This is us if we're positive, but the next one if negative!
if(cap->m_signalLevels[i] < 0)
cap->m_signalLevels.erase(cap->m_signalLevels.begin() + (i+1) );
else
cap->m_signalLevels.erase(cap->m_signalLevels.begin() + i);
}
}
//Figure out decision points (eye centers)
//FIXME: This doesn't work well for PAM! Only MLT*
for(size_t i=0; i<cap->m_signalLevels.size()-1; i++)
{
float vlo = cap->m_signalLevels[i];
float vhi = cap->m_signalLevels[i+1];
cap->m_decisionPoints.push_back(vlo + (vhi-vlo)/2);
}
//LogDebug(" Decision points:\n");
//for(auto v : cap->m_decisionPoints)
// LogDebug(" %6.3f V\n", v);
//Sanity check
if(cap->m_signalLevels.size() < 2)
{
LogDebug("Couldn't find at least two distinct symbol voltages\n");
delete cap;
return false;
}
return true;
}
*/

void EyeDecoder2::Refresh()
{
static double total_time = 0;
2 changes: 1 addition & 1 deletion scopeprotocols/EyeDecoder2.h
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@
* *
* ANTIKERNEL v0.1 *
* *
* Copyright (c) 2012-2019 Andrew D. Zonenberg *
* 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 *
796 changes: 0 additions & 796 deletions scopeprotocols/EyeRenderer.cpp

This file was deleted.

188 changes: 0 additions & 188 deletions scopeprotocols/EyeRenderer.h

This file was deleted.

2 changes: 1 addition & 1 deletion scopeprotocols/FFTDecoder.cpp
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@
#include "../scopehal/scopehal.h"
#include "FFTDecoder.h"
#include "../scopehal/AnalogRenderer.h"
#include <ffts/ffts.h>
#include <ffts.h>

using namespace std;

82 changes: 0 additions & 82 deletions scopeprotocols/build.yml

This file was deleted.

1 change: 0 additions & 1 deletion scopeprotocols/scopeprotocols.h
Original file line number Diff line number Diff line change
@@ -52,7 +52,6 @@
#include "EthernetProtocolDecoder.h"
#include "Ethernet10BaseTDecoder.h"
#include "Ethernet100BaseTDecoder.h"
#include "EyeDecoder.h"
#include "EyeDecoder2.h"
#include "FFTDecoder.h"
#include "IBM8b10bDecoder.h"