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

Commits on Jul 31, 2020

  1. Fixed incorrect interpolation in Touchstone files with significant ga…

    …in/attenuation near DC. Fixed bug where de-embed/channel emulation filters would output garbage during the phase shift window. Fixes #204.
    azonenberg committed Jul 31, 2020
    Copy the full SHA
    0e54ac9 View commit details
Showing with 48 additions and 4 deletions.
  1. +18 −1 scopehal/TouchstoneParser.cpp
  2. +13 −2 scopehal/TouchstoneParser.h
  3. +17 −1 scopeprotocols/DeEmbedDecoder.cpp
19 changes: 18 additions & 1 deletion scopehal/TouchstoneParser.cpp
Original file line number Diff line number Diff line change
@@ -49,7 +49,7 @@ SParameterPoint SParameterVector::InterpolatePoint(float frequency) const

//If out of range, clip
if(frequency < m_points[0].m_frequency)
return SParameterPoint(frequency, 1, 0);
return SParameterPoint(frequency, m_points[0].m_amplitude, 0);
else if(frequency > m_points[len-1].m_frequency)
return SParameterPoint(frequency, 0, 0);
else
@@ -161,6 +161,23 @@ SParameterVector& SParameterVector::operator *=(const SParameterVector& rhs)
return *this;
}

/**
@brief Gets the group delay at a given bin
*/
float SParameterVector::GetGroupDelay(size_t bin)
{
if(bin+1 >= m_points.size())
return 0;

auto a = m_points[bin];
auto b = m_points[bin+1+1];

//frequency is in Hz, not rad/sec, so we need to convert
float dfreq = (b.m_frequency - a.m_frequency) * 2*M_PI;

return (a.m_phase - b.m_phase) / dfreq;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// TouchstoneParser

15 changes: 13 additions & 2 deletions scopehal/TouchstoneParser.h
Original file line number Diff line number Diff line change
@@ -68,9 +68,19 @@ class SParameterVector

std::vector<SParameterPoint> m_points;

float GetGroupDelay(size_t bin);

size_t size()
{ return m_points.size(); }

SParameterVector& operator *=(const SParameterVector& rhs);

SParameterPoint operator[](size_t i)
{ return m_points[i]; }
};

typedef std::pair<int, int> SPair;

/**
@brief Touchstone (SxP) file parser
*/
@@ -87,8 +97,6 @@ class TouchstoneParser
void Clear();
bool Load(std::string fname);

typedef std::pair<int, int> SPair;

/**
@brief Sample a single point from a single S-parameter
*/
@@ -97,6 +105,9 @@ class TouchstoneParser

TouchstoneParser& operator *=(const TouchstoneParser& rhs);

SParameterVector& operator[] (SPair pair)
{ return *m_params[pair]; }

protected:
void Allocate();

18 changes: 17 additions & 1 deletion scopeprotocols/DeEmbedDecoder.cpp
Original file line number Diff line number Diff line change
@@ -292,17 +292,33 @@ void DeEmbedDecoder::DoRefresh(bool invert)
ffts_execute(plan, &rdout[0], &ddout[0]);
ffts_free(plan);

//Calculate maximum group delay for the first few S-parameter bins (approx propagation delay of the channel)
auto& s21 = m_sparams[SPair(2,1)];
float max_delay = 0;
for(size_t i=0; i<s21.size()-1 && i<50; i++)
max_delay = max(max_delay, s21.GetGroupDelay(i));
int64_t groupdelay_samples = ceil( (max_delay * 1e12) / din->m_timescale);

//Set up output and copy timestamps
auto cap = new AnalogWaveform;
cap->m_startTimestamp = din->m_startTimestamp;
cap->m_startPicoseconds = din->m_startPicoseconds;
cap->m_timescale = din->m_timescale;

//Calculate bounds for the *meaningful* output data.
//Since we're phase shifting, there's gonna be some garbage response at one end of the channel.
size_t istart = 0;
size_t iend = npoints;
if(invert)
iend -= groupdelay_samples;
else
istart += groupdelay_samples;

//Copy waveform data after rescaling
float scale = 1.0f / npoints;
float vmin = FLT_MAX;
float vmax = -FLT_MAX;
for(size_t i=0; i<npoints; i++)
for(size_t i=istart; i<iend; i++)
{
cap->m_offsets.push_back(din->m_offsets[i]);
cap->m_durations.push_back(din->m_durations[i]);