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

Commits on May 7, 2020

  1. Copy the full SHA
    87e0779 View commit details
  2. Copy the full SHA
    ed0d009 View commit details
30 changes: 19 additions & 11 deletions scopehal/AntikernelLabsOscilloscope.cpp
Original file line number Diff line number Diff line change
@@ -186,13 +186,13 @@ bool AntikernelLabsOscilloscope::IsChannelEnabled(size_t i)
void AntikernelLabsOscilloscope::EnableChannel(size_t i)
{
lock_guard<recursive_mutex> lock(m_mutex);
//m_transport->SendCommand(m_channels[i]->GetHwname() + ":STAT ON");
m_transport->SendCommand(m_channels[i]->GetHwname() + ":EN");
}

void AntikernelLabsOscilloscope::DisableChannel(size_t i)
{
lock_guard<recursive_mutex> lock(m_mutex);
//m_transport->SendCommand(m_channels[i]->GetHwname() + ":STAT OFF");
m_transport->SendCommand(m_channels[i]->GetHwname() + ":DIS");
}

OscilloscopeChannel::CouplingType AntikernelLabsOscilloscope::GetChannelCoupling(size_t /*i*/)
@@ -287,18 +287,27 @@ void AntikernelLabsOscilloscope::SetChannelVoltageRange(size_t i, double range)
{
//Convert requested range to gain
float frac_gain = 2.0 / range;
float db = 20*log10(frac_gain);
int rdb = round(db) + 4;
//LogDebug("Setting channel gain to %.2f dB (rounding to %d)\n", db, rdb);
float db = 20*log10(frac_gain) + 4;
//LogDebug("Setting channel gain to %.2f dB (rounding to %.0f)\n", db, round(db));

//Clip gain to the supported range
if(db < -9)
{
db = -9;
range = 2.0 / pow(10, (db-4)/20.0f);
}
else if(db > 26)
{
db = 26;
range = 2.0 / pow(10, (db-4)/20.0f);
}

char tmp[128];
snprintf(tmp, sizeof(tmp), "%s:GAIN %d", m_channels[i]->GetHwname().c_str(), rdb);
snprintf(tmp, sizeof(tmp), "%s:GAIN %d", m_channels[i]->GetHwname().c_str(), (int)round(db));

lock_guard<recursive_mutex> lock2(m_mutex);
m_transport->SendCommand(tmp);

//TODO: cap to limits and report actual gain if we zoom too far?

lock_guard<recursive_mutex> lock(m_cacheMutex);
m_channelVoltageRanges[i] = range;
}
@@ -326,7 +335,6 @@ double AntikernelLabsOscilloscope::GetChannelOffset(size_t i)
string reply = m_transport->ReadReply();
double offset;
sscanf(reply.c_str(), "%lf", &offset);
offset = -offset;
lock_guard<recursive_mutex> lock(m_cacheMutex);
m_channelOffsets[i] = offset;
return offset;
@@ -337,7 +345,7 @@ void AntikernelLabsOscilloscope::SetChannelOffset(size_t i, double offset)
lock_guard<recursive_mutex> lock(m_mutex);

char tmp[128];
snprintf(tmp, sizeof(tmp), "%s:OFFS %f", m_channels[i]->GetHwname().c_str(), -offset);
snprintf(tmp, sizeof(tmp), "%s:OFFS %f", m_channels[i]->GetHwname().c_str(), offset);
m_transport->SendCommand(tmp);

lock_guard<recursive_mutex> lock2(m_cacheMutex);
@@ -382,7 +390,7 @@ bool AntikernelLabsOscilloscope::AcquireData(bool toQueue)
for(size_t i=0; i<depth; i++)
{
//Scale it
float v = ((waveform[i] - 128.0f) * scale) - offset;
float v = ((waveform[i] - 128.0f) * scale) + offset;
cap->m_samples.push_back(AnalogSample(i, 1, v));
}

2 changes: 2 additions & 0 deletions scopeprotocols/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -7,6 +7,8 @@ set(SCOPEPROTOCOLS_SOURCES
ClockRecoveryDecoder.cpp
ClockRecoveryDebugDecoder.cpp
DCOffsetDecoder.cpp
DDR3Decoder.cpp
DDR3Renderer.cpp
DifferenceDecoder.cpp
DVIDecoder.cpp
DVIRenderer.cpp
217 changes: 217 additions & 0 deletions scopeprotocols/DDR3Decoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
/***********************************************************************************************************************
* *
* 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 DDR3Decoder
*/

#include "../scopehal/scopehal.h"
#include "../scopehal/ChannelRenderer.h"
#include "../scopehal/TextRenderer.h"
#include "DDR3Renderer.h"
#include "DDR3Decoder.h"

using namespace std;

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

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

m_signalNames.push_back("WE#");
m_channels.push_back(NULL);

m_signalNames.push_back("RAS#");
m_channels.push_back(NULL);

m_signalNames.push_back("CAS#");
m_channels.push_back(NULL);

m_signalNames.push_back("CS#");
m_channels.push_back(NULL);

m_signalNames.push_back("A12");
m_channels.push_back(NULL);

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

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

bool DDR3Decoder::NeedsConfig()
{
return true;
}

ChannelRenderer* DDR3Decoder::CreateRenderer()
{
return new DDR3Renderer(this);
}

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

string DDR3Decoder::GetProtocolName()
{
return "DDR3 Command Bus";
}

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

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

void DDR3Decoder::Refresh()
{
//Get the input data
DigitalCapture* caps[7] = {0};
for(int i=0; i<7; i++)
{
if(m_channels[i] == NULL)
{
SetData(NULL);
return;
}
DigitalCapture* cap = dynamic_cast<DigitalCapture*>(m_channels[i]->GetData());
if(cap == NULL)
{
SetData(NULL);
return;
}
caps[i] = cap;
}

//Sample all of the inputs
DigitalCapture* cclk = caps[0];
vector<DigitalSample> we;
vector<DigitalSample> ras;
vector<DigitalSample> cas;
vector<DigitalSample> cs;
vector<DigitalSample> a12;
vector<DigitalSample> a10;
SampleOnRisingEdges(caps[1], cclk, we);
SampleOnRisingEdges(caps[2], cclk, ras);
SampleOnRisingEdges(caps[3], cclk, cas);
SampleOnRisingEdges(caps[4], cclk, cs);
SampleOnRisingEdges(caps[5], cclk, a12);
SampleOnRisingEdges(caps[6], cclk, a10);

//Create the capture
DDR3Capture* cap = new DDR3Capture;
cap->m_timescale = 1;
cap->m_startTimestamp = cclk->m_startTimestamp;
cap->m_startPicoseconds = 0;

//Loop over the data and look for events on clock edges
for(size_t i=0; i<we.size(); i++)
{
//Abort if one of the other waveforms ends earlier
if( (i >= ras.size()) ||
(i >= cas.size()) ||
(i >= cs.size()) ||
(i >= a12.size()) ||
(i >= a10.size()) )
{
break;
}

bool swe = we[i];
bool sras = ras[i];
bool scas = cas[i];
bool scs = cs[i];
bool sa12 = a12[i];
bool sa10 = a10[i];

if(!scs)
{
//NOP
if(sras && scas && swe)
continue;

DDR3Symbol sym(DDR3Symbol::TYPE_ERROR);

if(!sras && !scas && !swe)
sym.m_stype = DDR3Symbol::TYPE_MRS;
else if(!sras && !scas && swe)
sym.m_stype = DDR3Symbol::TYPE_REF;
else if(!sras && scas && !swe && !sa10)
sym.m_stype = DDR3Symbol::TYPE_PRE;
else if(!sras && scas && !swe && sa10)
sym.m_stype = DDR3Symbol::TYPE_PREA;
else if(!sras && scas && swe)
sym.m_stype = DDR3Symbol::TYPE_ACT;
else if(sras && !scas && !swe)
{
if(!sa10)
sym.m_stype = DDR3Symbol::TYPE_WR;
else
sym.m_stype = DDR3Symbol::TYPE_WRA;
}
else if(sras && !scas && swe)
{
if(!sa10)
sym.m_stype = DDR3Symbol::TYPE_RD;
else
sym.m_stype = DDR3Symbol::TYPE_RDA;
}

//Unknown
//TODO: self refresh entry/exit (we don't have CKE in the current test data source so can't use it)
else
LogDebug("[%zu] Unknown command (RAS=%d, CAS=%d, WE=%d, A12=%d, A10=%d)\n", i, sras, scas, swe, sa12, sa10);

//Create the symbol
cap->m_samples.push_back(DDR3Sample(
we[i].m_offset,
we[i].m_duration,
sym));
}
}

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

#ifndef DDR3Decoder_h
#define DDR3Decoder_h

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

class DDR3Symbol
{
public:
enum stype
{
TYPE_MRS,
TYPE_REF,
TYPE_PRE,
TYPE_PREA,
TYPE_ACT,
TYPE_WR,
TYPE_WRA,
TYPE_RD,
TYPE_RDA,

TYPE_ERROR
};

DDR3Symbol(stype t)
: m_stype(t)
{}

stype m_stype;

bool operator== (const DDR3Symbol& s) const
{
return (m_stype == s.m_stype);
}
};

typedef OscilloscopeSample<DDR3Symbol> DDR3Sample;
typedef CaptureChannel<DDR3Symbol> DDR3Capture;

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

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

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

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

PROTOCOL_DECODER_INITPROC(DDR3Decoder)

protected:
};

#endif
Loading