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

Commits on Aug 2, 2020

  1. Copy the full SHA
    d25d710 View commit details
Showing with 324 additions and 0 deletions.
  1. +1 −0 scopeprotocols/CMakeLists.txt
  2. +237 −0 scopeprotocols/Ethernet64b66bDecoder.cpp
  3. +84 −0 scopeprotocols/Ethernet64b66bDecoder.h
  4. +1 −0 scopeprotocols/scopeprotocols.cpp
  5. +1 −0 scopeprotocols/scopeprotocols.h
1 change: 1 addition & 0 deletions scopeprotocols/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ set(SCOPEPROTOCOLS_SOURCES
Ethernet10BaseTDecoder.cpp
Ethernet100BaseTDecoder.cpp
Ethernet1000BaseXDecoder.cpp
Ethernet64b66bDecoder.cpp
EthernetAutonegotiationDecoder.cpp
EthernetGMIIDecoder.cpp
EthernetRGMIIDecoder.cpp
237 changes: 237 additions & 0 deletions scopeprotocols/Ethernet64b66bDecoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/***********************************************************************************************************************
* *
* 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 Implementation of Ethernet64b66bDecoder
*/

#include "../scopehal/scopehal.h"
#include "Ethernet64b66bDecoder.h"

using namespace std;

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

Ethernet64b66bDecoder::Ethernet64b66bDecoder(string color)
: ProtocolDecoder(OscilloscopeChannel::CHANNEL_TYPE_COMPLEX, color, CAT_SERIAL)
{
//Set up channels
m_signalNames.push_back("data");
m_channels.push_back(NULL);

m_signalNames.push_back("clk");
m_channels.push_back(NULL);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Factory methods

bool Ethernet64b66bDecoder::NeedsConfig()
{
//baud rate has to be set
return true;
}

bool Ethernet64b66bDecoder::ValidateChannel(size_t i, OscilloscopeChannel* channel)
{
if( (i == 0) && (channel->GetType() == OscilloscopeChannel::CHANNEL_TYPE_DIGITAL) && (channel->GetWidth() == 1) )
return true;
if( (i == 1) && (channel->GetType() == OscilloscopeChannel::CHANNEL_TYPE_DIGITAL) && (channel->GetWidth() == 1) )
return true;
return false;
}

string Ethernet64b66bDecoder::GetProtocolName()
{
return "64b/66b";
}

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

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

void Ethernet64b66bDecoder::Refresh()
{
//Get the input data
if( (m_channels[0] == NULL) || (m_channels[1] == NULL) )
{
SetData(NULL);
return;
}
auto din = dynamic_cast<DigitalWaveform*>(m_channels[0]->GetData());
auto clkin = dynamic_cast<DigitalWaveform*>(m_channels[1]->GetData());
if( (din == NULL) || (clkin == NULL) )
{
SetData(NULL);
return;
}

//Create the capture
auto cap = new Ethernet64b66bWaveform;
cap->m_timescale = 1;
cap->m_startTimestamp = din->m_startTimestamp;
cap->m_startPicoseconds = din->m_startPicoseconds;

//Record the value of the data stream at each clock edge
DigitalWaveform data;
SampleOnAnyEdges(din, clkin, data);

//Look at each phase and figure out block alignment
size_t end = data.m_offsets.size() - 66;
size_t best_offset = 0;
size_t best_errors = end;
for(size_t offset=0; offset < 66; offset ++)
{
size_t errors = 0;
for(size_t i=offset; i<end; i+= 66)
{
if(data.m_samples[i] == data.m_samples[i+1])
errors ++;
}

if(errors < best_errors)
{
best_offset = offset;
best_errors = errors;
}
}


//Decode the actual data
bool first = true;
uint64_t lfsr = 0;

for(size_t i=best_offset; i<end; i += 66)
{
//Extract the header bits
uint8_t header =
(data.m_samples[i] ? 2 : 0) |
(data.m_samples[i+1] ? 1 : 0);

//Extract the data bits and descramble them.
uint64_t codeword = 0;
for(size_t j=0; j<64; j++)
{
bool b = data.m_samples[i + 2 + j];

codeword >>= 1;
if(b ^ ( (lfsr >> 38) & 1) ^ ( (lfsr >> 57) & 1) )
codeword |= 0x8000000000000000L;

lfsr = (lfsr << 1) | b;
}

//Need to swap bit/byte ordering around a bunch.
uint64_t bytes[8] =
{
(codeword >> 56) & 0xff,
(codeword >> 48) & 0xff,
(codeword >> 40) & 0xff,
(codeword >> 32) & 0xff,
(codeword >> 24) & 0xff,
(codeword >> 16) & 0xff,
(codeword >> 8) & 0xff,
(codeword >> 0) & 0xff,
};

codeword =
(bytes[7] << 56) |
(bytes[6] << 48) |
(bytes[5] << 40) |
(bytes[4] << 32) |
(bytes[3] << 24) |
(bytes[2] << 16) |
(bytes[1] << 8) |
bytes[0];

//Just prime the scrambler, we can't decode yet
if(first)
first = false;

//Process descrambled data
else
{
cap->m_offsets.push_back(data.m_offsets[i] - data.m_durations[i]/2);
cap->m_durations.push_back(data.m_offsets[i+66] - data.m_offsets[i]);
cap->m_samples.push_back(Ethernet64b66bSymbol(header, codeword));
}
}

SetData(cap);
}

Gdk::Color Ethernet64b66bDecoder::GetColor(int i)
{
auto capture = dynamic_cast<Ethernet64b66bWaveform*>(GetData());
if(capture != NULL)
{
const Ethernet64b66bSymbol& s = capture->m_samples[i];

switch(s.m_header)
{
case 1:
return m_standardColors[COLOR_DATA];

case 2:
return m_standardColors[COLOR_CONTROL];

default:
return m_standardColors[COLOR_ERROR];
}
}

//error
return m_standardColors[COLOR_ERROR];
}

string Ethernet64b66bDecoder::GetText(int i)
{
auto capture = dynamic_cast<Ethernet64b66bWaveform*>(GetData());
if(capture != NULL)
{
const Ethernet64b66bSymbol& s = capture->m_samples[i];

char tmp[32];
snprintf(tmp, sizeof(tmp), "%016lx", s.m_data);
return string(tmp);
}

return "";
}

84 changes: 84 additions & 0 deletions scopeprotocols/Ethernet64b66bDecoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/***********************************************************************************************************************
* *
* 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 Ethernet64b66bDecoder
*/

#ifndef Ethernet64b66bDecoder_h
#define Ethernet64b66bDecoder_h

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

class Ethernet64b66bSymbol
{
public:
Ethernet64b66bSymbol()
{}

Ethernet64b66bSymbol(uint8_t h, uint64_t d)
: m_header(h)
, m_data(d)
{}

uint8_t m_header;
uint64_t m_data;

bool operator== (const Ethernet64b66bSymbol& s) const
{
return (m_header == s.m_header) && (m_data == s.m_data);
}
};

typedef Waveform<Ethernet64b66bSymbol> Ethernet64b66bWaveform;

class Ethernet64b66bDecoder : public ProtocolDecoder
{
public:
Ethernet64b66bDecoder(std::string color);

virtual std::string GetText(int i);
virtual Gdk::Color GetColor(int i);

virtual void Refresh();
virtual bool NeedsConfig();

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

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

PROTOCOL_DECODER_INITPROC(Ethernet64b66bDecoder)

protected:
};

#endif
1 change: 1 addition & 0 deletions scopeprotocols/scopeprotocols.cpp
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ void ScopeProtocolStaticInit()
AddDecoderClass(Ethernet10BaseTDecoder);
AddDecoderClass(Ethernet100BaseTDecoder);
AddDecoderClass(Ethernet1000BaseXDecoder);
AddDecoderClass(Ethernet64b66bDecoder);
AddDecoderClass(EthernetGMIIDecoder);
AddDecoderClass(EthernetRGMIIDecoder);
AddDecoderClass(EthernetAutonegotiationDecoder);
1 change: 1 addition & 0 deletions scopeprotocols/scopeprotocols.h
Original file line number Diff line number Diff line change
@@ -64,6 +64,7 @@
#include "Ethernet10BaseTDecoder.h"
#include "Ethernet100BaseTDecoder.h"
#include "Ethernet1000BaseXDecoder.h"
#include "Ethernet64b66bDecoder.h"
#include "EyeBitRateMeasurementDecoder.h"
#include "EyeDecoder2.h"
#include "EyeHeightMeasurementDecoder.h"