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

Commits on May 17, 2020

  1. Copy the full SHA
    74e0efe View commit details
  2. Copy the full SHA
    80a0de9 View commit details
10 changes: 5 additions & 5 deletions scopeprotocols/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -11,8 +11,8 @@ set(SCOPEPROTOCOLS_SOURCES
DCOffsetDecoder.cpp
DDR3Decoder.cpp
DifferenceDecoder.cpp
#DramRefreshActivateMeasurementDecoder.cpp
#DramRowColumnLatencyMeasurementDecoder.cpp
DramRefreshActivateMeasurementDecoder.cpp
DramRowColumnLatencyMeasurementDecoder.cpp
DVIDecoder.cpp
#Ethernet10BaseTDecoder.cpp
Ethernet100BaseTDecoder.cpp
@@ -24,11 +24,11 @@ set(SCOPEPROTOCOLS_SOURCES
FFTDecoder.cpp
#FrequencyMeasurementDecoder.cpp
HorizontalBathtubDecoder.cpp
#I2CDecoder.cpp
#IBM8b10bDecoder.cpp
I2CDecoder.cpp
IBM8b10bDecoder.cpp
#JtagDecoder.cpp
#MDIODecoder.cpp
#MovingAverageDecoder.cpp
MovingAverageDecoder.cpp
#ParallelBusDecoder.cpp
#PeriodMeasurementDecoder.cpp
#RiseMeasurementDecoder.cpp
31 changes: 17 additions & 14 deletions scopeprotocols/DramRefreshActivateMeasurementDecoder.cpp
Original file line number Diff line number Diff line change
@@ -106,15 +106,15 @@ void DramRefreshActivateMeasurementDecoder::Refresh()
SetData(NULL);
return;
}
DDR3Capture* din = dynamic_cast<DDR3Capture*>(m_channels[0]->GetData());
if(din == NULL || (din->GetDepth() == 0))
auto din = dynamic_cast<DDR3Waveform*>(m_channels[0]->GetData());
if(din == NULL || (din->m_samples.size() == 0))
{
SetData(NULL);
return;
}

//Create the output
AnalogCapture* cap = new AnalogCapture;
auto cap = new AnalogWaveform;

//Measure delay from refreshing a bank until an activation to the same bank
int64_t lastRef[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -123,26 +123,27 @@ void DramRefreshActivateMeasurementDecoder::Refresh()
float fmin = 1e20;

int64_t tlast = 0;
for(size_t i=0; i<din->GetDepth(); i++)
size_t len = din->m_samples.size();
for(size_t i=0; i<len; i++)
{
auto sample = din->m_samples[i];
int64_t tnow = sample.m_offset * din->m_timescale;
int64_t tnow = din->m_offsets[i] * din->m_timescale;

//Discard invalid bank IDs
if( (sample.m_sample.m_bank < 0) || (sample.m_sample.m_bank > 8) )
auto sample = din->m_samples[i];
if( (sample.m_bank < 0) || (sample.m_bank > 8) )
continue;

//If it's a refresh, update the last refresh time
if(sample.m_sample.m_stype == DDR3Symbol::TYPE_REF)
lastRef[sample.m_sample.m_bank] = sample.m_offset * din->m_timescale;
if(sample.m_stype == DDR3Symbol::TYPE_REF)
lastRef[sample.m_bank] = din->m_offsets[i] * din->m_timescale;

//If it's an activate, measure the latency
else if(sample.m_sample.m_stype == DDR3Symbol::TYPE_ACT)
else if(sample.m_stype == DDR3Symbol::TYPE_ACT)
{
int64_t tact = sample.m_offset * din->m_timescale;
int64_t tact = din->m_offsets[i] * din->m_timescale;

//If the refresh command is before the start of the capture, ignore this event
int64_t tref= lastRef[sample.m_sample.m_bank];
int64_t tref= lastRef[sample.m_bank];
if(tref == 0)
continue;

@@ -153,11 +154,13 @@ void DramRefreshActivateMeasurementDecoder::Refresh()
if(fmax < latency)
fmax = latency;

cap->m_samples.push_back(AnalogSample(tlast, tnow-tlast, latency));
cap->m_offsets.push_back(tlast);
cap->m_durations.push_back(tnow - tlast);
cap->m_samples.push_back(latency);
tlast = tnow;

//Purge the last-refresh timestamp so we don't report false times for the next activate
lastRef[sample.m_sample.m_bank] = 0;
lastRef[sample.m_bank] = 0;
}
}

35 changes: 19 additions & 16 deletions scopeprotocols/DramRowColumnLatencyMeasurementDecoder.cpp
Original file line number Diff line number Diff line change
@@ -106,15 +106,15 @@ void DramRowColumnLatencyMeasurementDecoder::Refresh()
SetData(NULL);
return;
}
DDR3Capture* din = dynamic_cast<DDR3Capture*>(m_channels[0]->GetData());
if(din == NULL || (din->GetDepth() == 0))
auto din = dynamic_cast<DDR3Waveform*>(m_channels[0]->GetData());
if(din == NULL || (din->m_samples.size() == 0))
{
SetData(NULL);
return;
}

//Create the output
AnalogCapture* cap = new AnalogCapture;
auto cap = new AnalogWaveform;

//Measure delay from activating a row in a bank until a read or write to the same bank
int64_t lastAct[8] = {0, 0, 0, 0, 0, 0, 0, 0};
@@ -123,29 +123,30 @@ void DramRowColumnLatencyMeasurementDecoder::Refresh()
float fmin = 1e20;

int64_t tlast = 0;
for(size_t i=0; i<din->GetDepth(); i++)
size_t len = din->m_samples.size();
for(size_t i=0; i<len; i++)
{
auto sample = din->m_samples[i];
int64_t tnow = sample.m_offset * din->m_timescale;
int64_t tnow = din->m_offsets[i] * din->m_timescale;

//Discard invalid bank IDs
if( (sample.m_sample.m_bank < 0) || (sample.m_sample.m_bank > 8) )
auto sample = din->m_samples[i];
if( (sample.m_bank < 0) || (sample.m_bank > 8) )
continue;

//If it's an activate, update the last activation time
if(sample.m_sample.m_stype == DDR3Symbol::TYPE_ACT)
lastAct[sample.m_sample.m_bank] = tnow;
if(sample.m_stype == DDR3Symbol::TYPE_ACT)
lastAct[sample.m_bank] = tnow;

//If it's a read or write, measure the latency
else if( (sample.m_sample.m_stype == DDR3Symbol::TYPE_WR) |
(sample.m_sample.m_stype == DDR3Symbol::TYPE_WRA) |
(sample.m_sample.m_stype == DDR3Symbol::TYPE_RD) |
(sample.m_sample.m_stype == DDR3Symbol::TYPE_RDA) )
else if( (sample.m_stype == DDR3Symbol::TYPE_WR) |
(sample.m_stype == DDR3Symbol::TYPE_WRA) |
(sample.m_stype == DDR3Symbol::TYPE_RD) |
(sample.m_stype == DDR3Symbol::TYPE_RDA) )
{
int64_t tcol = tnow;

//If the activate command is before the start of the capture, ignore this event
int64_t tact = lastAct[sample.m_sample.m_bank];
int64_t tact = lastAct[sample.m_bank];
if(tact == 0)
continue;

@@ -156,11 +157,13 @@ void DramRowColumnLatencyMeasurementDecoder::Refresh()
if(fmax < latency)
fmax = latency;

cap->m_samples.push_back(AnalogSample(tlast, tnow-tlast, latency));
cap->m_offsets.push_back(tlast);
cap->m_durations.push_back(tnow - tlast);
cap->m_samples.push_back(latency);
tlast = tnow;

//Purge the last-refresh activate so we don't report false times for the next read or write
lastAct[sample.m_sample.m_bank] = 0;
lastAct[sample.m_bank] = 0;
}
}

71 changes: 35 additions & 36 deletions scopeprotocols/I2CDecoder.cpp
Original file line number Diff line number Diff line change
@@ -35,6 +35,7 @@

#include "../scopehal/scopehal.h"
#include "I2CDecoder.h"
#include <algorithm>

using namespace std;

@@ -93,16 +94,16 @@ void I2CDecoder::Refresh()
SetData(NULL);
return;
}
DigitalCapture* sda = dynamic_cast<DigitalCapture*>(m_channels[0]->GetData());
DigitalCapture* scl = dynamic_cast<DigitalCapture*>(m_channels[1]->GetData());
auto sda = dynamic_cast<DigitalWaveform*>(m_channels[0]->GetData());
auto scl = dynamic_cast<DigitalWaveform*>(m_channels[1]->GetData());
if( (sda == NULL) || (scl == NULL) )
{
SetData(NULL);
return;
}

//Create the capture
I2CCapture* cap = new I2CCapture;
auto cap = new I2CWaveform;
cap->m_timescale = sda->m_timescale;
cap->m_startTimestamp = sda->m_startTimestamp;
cap->m_startPicoseconds = sda->m_startPicoseconds;
@@ -116,15 +117,17 @@ void I2CDecoder::Refresh()
uint8_t current_byte = 0;
uint8_t bitcount = 0;
bool last_was_start = 0;
for(size_t i=0; i<sda->m_samples.size(); i++)
size_t len = sda->m_samples.size();
len = min(len, scl->m_samples.size());
for(size_t i=0; i<len; i++)
{
bool cur_sda = sda->m_samples[i].m_sample;
bool cur_scl = scl->m_samples[i].m_sample;
bool cur_sda = sda->m_samples[i];
bool cur_scl = scl->m_samples[i];

//SDA falling with SCL high is beginning of a start condition
if(!cur_sda && last_sda && cur_scl)
{
LogDebug("found i2c start at time %zu\n", sda->m_samples[i].m_offset);
LogTrace("found i2c start at time %zu\n", (size_t)sda->m_offsets[i]);

//If we're following an ACK, this is a restart
if(current_type == I2CSymbol::TYPE_DATA)
@@ -141,10 +144,10 @@ void I2CDecoder::Refresh()
else if( ((current_type == I2CSymbol::TYPE_START) || (current_type == I2CSymbol::TYPE_RESTART)) &&
(cur_sda || !cur_scl) )
{
cap->m_samples.push_back(I2CSample(
sda->m_samples[symbol_start].m_offset,
sda->m_samples[i].m_offset - symbol_start,
I2CSymbol(current_type, 0)));
auto tstart = sda->m_offsets[symbol_start];
cap->m_offsets.push_back(tstart);
cap->m_durations.push_back(sda->m_offsets[i] - tstart);
cap->m_samples.push_back(I2CSymbol(current_type, 0));

last_was_start = true;
current_type = I2CSymbol::TYPE_DATA;
@@ -157,12 +160,13 @@ void I2CDecoder::Refresh()
//SDA rising with SCL high is a stop condition
else if(cur_sda && !last_sda && cur_scl)
{
LogDebug("found i2c stop at time %zu\n", sda->m_samples[i].m_offset);
LogTrace("found i2c stop at time %zu\n", (size_t)sda->m_offsets[i]);

auto tstart = sda->m_offsets[symbol_start];
cap->m_offsets.push_back(tstart);
cap->m_durations.push_back(sda->m_offsets[i] - tstart);
cap->m_samples.push_back(I2CSymbol(I2CSymbol::TYPE_STOP, 0));

cap->m_samples.push_back(I2CSample(
sda->m_samples[symbol_start].m_offset,
sda->m_samples[i].m_offset - symbol_start,
I2CSymbol(I2CSymbol::TYPE_STOP, 0)));
last_was_start = false;

symbol_start = i;
@@ -182,20 +186,14 @@ void I2CDecoder::Refresh()
//Add a sample if the byte is over
if(bitcount == 8)
{
auto tstart = sda->m_offsets[symbol_start];
cap->m_offsets.push_back(tstart);
cap->m_durations.push_back(sda->m_offsets[i] - tstart);
if(last_was_start)
{
cap->m_samples.push_back(I2CSample(
sda->m_samples[symbol_start].m_offset,
sda->m_samples[i].m_offset - symbol_start,
I2CSymbol(I2CSymbol::TYPE_ADDRESS, current_byte)));
}
cap->m_samples.push_back(I2CSymbol(I2CSymbol::TYPE_ADDRESS, current_byte));
else
{
cap->m_samples.push_back(I2CSample(
sda->m_samples[symbol_start].m_offset,
sda->m_samples[i].m_offset - symbol_start,
I2CSymbol(I2CSymbol::TYPE_DATA, current_byte)));
}
cap->m_samples.push_back(I2CSymbol(I2CSymbol::TYPE_DATA, current_byte));

last_was_start = false;

bitcount = 0;
@@ -209,10 +207,11 @@ void I2CDecoder::Refresh()
//ACK/NAK
else if(current_type == I2CSymbol::TYPE_ACK)
{
cap->m_samples.push_back(I2CSample(
sda->m_samples[symbol_start].m_offset,
sda->m_samples[i].m_offset - symbol_start,
I2CSymbol(I2CSymbol::TYPE_ACK, cur_sda)));
auto tstart = sda->m_offsets[symbol_start];
cap->m_offsets.push_back(tstart);
cap->m_durations.push_back(sda->m_offsets[i] - tstart);
cap->m_samples.push_back(I2CSymbol(I2CSymbol::TYPE_ACK, cur_sda));

last_was_start = false;

symbol_start = i;
@@ -230,10 +229,10 @@ void I2CDecoder::Refresh()

Gdk::Color I2CDecoder::GetColor(int i)
{
I2CCapture* capture = dynamic_cast<I2CCapture*>(GetData());
auto capture = dynamic_cast<I2CWaveform*>(GetData());
if(capture != NULL)
{
const I2CSymbol& s = capture->m_samples[i].m_sample;
const I2CSymbol& s = capture->m_samples[i];

switch(s.m_stype)
{
@@ -254,10 +253,10 @@ Gdk::Color I2CDecoder::GetColor(int i)

string I2CDecoder::GetText(int i)
{
I2CCapture* capture = dynamic_cast<I2CCapture*>(GetData());
auto capture = dynamic_cast<I2CWaveform*>(GetData());
if(capture != NULL)
{
const I2CSymbol& s = capture->m_samples[i].m_sample;
const I2CSymbol& s = capture->m_samples[i];

char tmp[32];
switch(s.m_stype)
6 changes: 4 additions & 2 deletions scopeprotocols/I2CDecoder.h
Original file line number Diff line number Diff line change
@@ -53,6 +53,9 @@ class I2CSymbol
TYPE_NONE
};

I2CSymbol()
{}

I2CSymbol(stype t,uint8_t d)
: m_stype(t)
, m_data(d)
@@ -67,8 +70,7 @@ class I2CSymbol
}
};

typedef OscilloscopeSample<I2CSymbol> I2CSample;
typedef CaptureChannel<I2CSymbol> I2CCapture;
typedef Waveform<I2CSymbol> I2CWaveform;

class I2CDecoder : public ProtocolDecoder
{
Loading