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

Commits on Jun 9, 2020

  1. Copy the full SHA
    879cd17 View commit details
  2. Copy the full SHA
    ae8f488 View commit details
  3. Copy the full SHA
    fcb7568 View commit details
46 changes: 46 additions & 0 deletions scopehal/ProtocolDecoder.cpp
Original file line number Diff line number Diff line change
@@ -558,6 +558,52 @@ void ProtocolDecoder::SampleOnAnyEdges(DigitalWaveform* data, DigitalWaveform* c
}
}

/**
@brief Samples a digital waveform on all edges of a clock
The sampling rate of the data and clock signals need not be equal or uniform.
The sampled waveform has a time scale in picoseconds regardless of the incoming waveform's time scale.
@param data The data signal to sample
@param clock The clock signal to use
@param samples Output waveform
*/
void ProtocolDecoder::SampleOnAnyEdges(DigitalBusWaveform* data, DigitalWaveform* clock, DigitalBusWaveform& samples)
{
samples.clear();

size_t ndata = 0;
size_t len = clock->m_offsets.size();
size_t dlen = data->m_samples.size();
for(size_t i=1; i<len; i++)
{
//Throw away clock samples until we find an edge
if(clock->m_samples[i] == clock->m_samples[i-1])
continue;

//Throw away data samples until the data is synced with us
int64_t clkstart = clock->m_offsets[i] * clock->m_timescale;
while( (ndata < dlen) && (data->m_offsets[ndata] * data->m_timescale < clkstart) )
ndata ++;
if(ndata >= dlen)
break;

//Extend the previous sample's duration (if any) to our start
size_t ssize = samples.m_samples.size();
if(ssize)
{
size_t last = ssize - 1;
samples.m_durations[last] = clkstart - samples.m_offsets[last];
}

//Add the new sample
samples.m_offsets.push_back(clkstart);
samples.m_durations.push_back(1);
samples.m_samples.push_back(data->m_samples[ndata]);
}
}

/**
@brief Find zero crossings in a waveform, interpolating as necessary
*/
1 change: 1 addition & 0 deletions scopehal/ProtocolDecoder.h
Original file line number Diff line number Diff line change
@@ -233,6 +233,7 @@ class ProtocolDecoder : public OscilloscopeChannel
//Samples a digital channel on the edges of another channel.
//The two channels need not be the same sample rate.
void SampleOnAnyEdges(DigitalWaveform* data, DigitalWaveform* clock, DigitalWaveform& samples);
void SampleOnAnyEdges(DigitalBusWaveform* data, DigitalWaveform* clock, DigitalBusWaveform& samples);
void SampleOnRisingEdges(DigitalWaveform* data, DigitalWaveform* clock, DigitalWaveform& samples);
void SampleOnRisingEdges(DigitalBusWaveform* data, DigitalWaveform* clock, DigitalBusWaveform& samples);
void SampleOnFallingEdges(DigitalWaveform* data, DigitalWaveform* clock, DigitalWaveform& samples);
2 changes: 1 addition & 1 deletion scopehal/SCPITransport.cpp
Original file line number Diff line number Diff line change
@@ -66,6 +66,6 @@ SCPITransport* SCPITransport::CreateTransport(string transport, string args)
if(m_createprocs.find(transport) != m_createprocs.end())
return m_createprocs[transport](args);

LogError("Invalid transport name");
LogError("Invalid transport name \"%s\"\n", transport.c_str());
return NULL;
}
1 change: 1 addition & 0 deletions scopeprotocols/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ set(SCOPEPROTOCOLS_SOURCES
Ethernet100BaseTDecoder.cpp
EthernetAutonegotiationDecoder.cpp
EthernetGMIIDecoder.cpp
EthernetRGMIIDecoder.cpp
EthernetProtocolDecoder.cpp
EyeBitRateMeasurementDecoder.cpp
EyeDecoder2.cpp
179 changes: 179 additions & 0 deletions scopeprotocols/EthernetRGMIIDecoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/***********************************************************************************************************************
* *
* 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 "scopeprotocols.h"
#include <algorithm>

using namespace std;

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

EthernetRGMIIDecoder::EthernetRGMIIDecoder(string color)
: EthernetProtocolDecoder(color)
{
//Digital inputs, so need to undo some stuff for the PHY layer decodes
m_signalNames.clear();
m_channels.clear();

//Add inputs. Make data be the first, because we normally want the overlay shown there.
m_signalNames.push_back("data");
m_channels.push_back(NULL);
m_signalNames.push_back("clk");
m_channels.push_back(NULL);
m_signalNames.push_back("ctl");
m_channels.push_back(NULL);
}

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

string EthernetRGMIIDecoder::GetProtocolName()
{
return "Ethernet - RGMII";
}

bool EthernetRGMIIDecoder::ValidateChannel(size_t i, OscilloscopeChannel* channel)
{
if(channel->GetType() != OscilloscopeChannel::CHANNEL_TYPE_DIGITAL)
return false;

switch(i)
{
case 0:
if(channel->GetWidth() == 4)
return true;
break;

case 1:
case 2:
case 3:
if(channel->GetWidth() == 1)
return true;
break;
}

return false;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Actual decoder logic

void EthernetRGMIIDecoder::SetDefaultName()
{
char hwname[256];
snprintf(hwname, sizeof(hwname), "RGMII(%s)", m_channels[0]->m_displayname.c_str());
m_hwname = hwname;
m_displayname = m_hwname;
}

void EthernetRGMIIDecoder::Refresh()
{
ClearPackets();

//Get the input data
for(int i=0; i<4; i++)
{
if(m_channels[i] == NULL)
{
SetData(NULL);
return;
}
}
auto data = dynamic_cast<DigitalBusWaveform*>(m_channels[0]->GetData());
auto clk = dynamic_cast<DigitalWaveform*>(m_channels[1]->GetData());
auto ctl = dynamic_cast<DigitalWaveform*>(m_channels[2]->GetData());
if( (data == NULL) || (clk == NULL) || (ctl == NULL) )
{
SetData(NULL);
return;
}

//Sample everything on the clock edges
DigitalWaveform dctl;
DigitalBusWaveform ddata;
SampleOnAnyEdges(ctl, clk, dctl);
SampleOnAnyEdges(data, clk, ddata);

//Need a reasonable number of samples or there's no point in decoding.
//Cut off the last sample since we're DDR.
size_t len = min(dctl.m_samples.size(), ddata.m_samples.size());
if(len < 100)
{
SetData(NULL);
return;
}
len --;

//Create the output capture
auto cap = new EthernetWaveform;
cap->m_timescale = 1;
cap->m_startTimestamp = data->m_startTimestamp;
cap->m_startPicoseconds = data->m_startPicoseconds;

for(size_t i=0; i < len; i++)
{
if(!dctl.m_samples[i])
continue;

//Set of recovered bytes and timestamps
vector<uint8_t> bytes;
vector<uint64_t> starts;
vector<uint64_t> ends;

//TODO: handle error signal (ignored for now)
while( (i < len) && (dctl.m_samples[i]) )
{
//Start time
starts.push_back(ddata.m_offsets[i]);

//Convert bits to bytes
uint8_t dval = 0;
for(size_t j=0; j<8; j++)
{
if(j < 4)
{
if(ddata.m_samples[i][j])
dval |= (1 << j);
}
else if(ddata.m_samples[i+1][j-4])
dval |= (1 << j);
}
bytes.push_back(dval);

ends.push_back(ddata.m_offsets[i+1] + ddata.m_durations[i+1]);
i += 2;
}

//Crunch the data
BytesToFrames(bytes, starts, ends, cap);
}

SetData(cap);
}
54 changes: 54 additions & 0 deletions scopeprotocols/EthernetRGMIIDecoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/***********************************************************************************************************************
* *
* 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 EthernetRGMIIDecoder
*/
#ifndef EthernetRGMIIDecoder_h
#define EthernetRGMIIDecoder_h

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

class EthernetRGMIIDecoder : public EthernetProtocolDecoder
{
public:
EthernetRGMIIDecoder(std::string color);

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

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

PROTOCOL_DECODER_INITPROC(EthernetRGMIIDecoder)
};

#endif
1 change: 1 addition & 0 deletions scopeprotocols/scopeprotocols.cpp
Original file line number Diff line number Diff line change
@@ -55,6 +55,7 @@ void ScopeProtocolStaticInit()
AddDecoderClass(Ethernet10BaseTDecoder);
AddDecoderClass(Ethernet100BaseTDecoder);
AddDecoderClass(EthernetGMIIDecoder);
AddDecoderClass(EthernetRGMIIDecoder);
AddDecoderClass(EthernetAutonegotiationDecoder);
AddDecoderClass(EyeBitRateMeasurementDecoder);
AddDecoderClass(EyeDecoder2);
1 change: 1 addition & 0 deletions scopeprotocols/scopeprotocols.h
Original file line number Diff line number Diff line change
@@ -55,6 +55,7 @@
#include "EthernetProtocolDecoder.h" //must be before all other ethernet decodes
#include "EthernetAutonegotiationDecoder.h"
#include "EthernetGMIIDecoder.h"
#include "EthernetRGMIIDecoder.h"
#include "Ethernet10BaseTDecoder.h"
#include "Ethernet100BaseTDecoder.h"
#include "EyeBitRateMeasurementDecoder.h"