Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions scopeprotocols/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ set(SCOPEPROTOCOLS_SOURCES
CSVImportFilter.cpp
CTLEFilter.cpp
CurrentShuntFilter.cpp
DAC8552Decoder.cpp
DCDMeasurement.cpp
DDJMeasurement.cpp
DDR1Decoder.cpp
Expand Down
145 changes: 145 additions & 0 deletions scopeprotocols/DAC8552Decoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@

/***********************************************************************************************************************
* *
* libscopeprotocols *
* *
* Copyright (c) 2012-2026 Andrew D. Zonenberg and contributors *
* 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 "../scopehal/scopehal.h"
#include "DAC8552Decoder.h"
#include "SPIDecoder.h"

using namespace std;

DAC8552Decoder::DAC8552Decoder(const string& color)
: Filter(color, CAT_MISC)
{
AddProtocolStream("data");
CreateInput<InputConstraintWaveformType<SPIWaveform>>("spi");
}

string DAC8552Waveform::GetColor(size_t)
{
return m_color;
}

string DAC8552Waveform::GetText(size_t i)
{
const DAC8552Symbol& s = m_samples[i];

char tmp[128];
snprintf(tmp, sizeof(tmp), "Load %s %s, Bfr=%c, Value=%d",
s.loadA() ? "A" : "", s.loadB() ? "B" : "", s.bfrSelect() ? 'A' : 'B', s.m_value);
return string(tmp);
}

string DAC8552Decoder::GetProtocolName()
{
return "DAC8552";
}

void DAC8552Decoder::Refresh(
[[maybe_unused]] vk::raii::CommandBuffer& cmdBuf,
[[maybe_unused]] shared_ptr<QueueHandle> queue)
{
ClearMessages();

if(!VerifyAllInputsOK())
{
if(!GetInput(0))
AddErrorMessage("Missing inputs", "No signal input connected");
else if(!GetInputWaveform(0))
AddErrorMessage("Missing inputs", "No waveform available at input");
SetData(nullptr, 0);
return;
}

auto din = dynamic_cast<SPIWaveform*>(GetInputWaveform(0));
if(!din)
{
AddErrorMessage("Missing inputs", "Invalid input connected");
SetData(nullptr, 0);
return;
}
size_t len = din->m_samples.size();

auto cap = new DAC8552Waveform(m_displaycolor);
cap->m_timescale = din->m_timescale;
cap->m_startTimestamp = din->m_startTimestamp;
cap->m_startFemtoseconds = din->m_startFemtoseconds;
cap->PrepareForCpuAccess();
din->PrepareForCpuAccess();
DAC8552Symbol samp;
int state = 0;
int64_t offset = 0;

for(size_t i=0; i<len; i++) {
auto s = din->m_samples[i];

switch(state)
{
case 0:
if(s.m_stype == SPISymbol::TYPE_SELECT)
state = 1;
break;
case 1:
if(s.m_stype == SPISymbol::TYPE_DATA)
{
offset = din->m_offsets[i];
samp.m_flags = s.m_data & (DAC8552Symbol::MASK_LOAD_A | DAC8552Symbol::MASK_LOAD_B | DAC8552Symbol::MASK_BFR_SEL);
state = 2;
} else
state = 0;
break;
case 2:
if(s.m_stype == SPISymbol::TYPE_DATA)
{
samp.m_value = static_cast<uint16_t>(s.m_data) << 8;
state = 3;
} else
state = 0;
break;
case 3:
if(s.m_stype == SPISymbol::TYPE_DATA)
{
samp.m_value |= s.m_data;
cap->m_offsets.push_back(offset);
cap->m_durations.push_back(din->m_offsets[i] + din->m_durations[i] - offset);
cap->m_samples.push_back(samp);
state = 4;
} else
state = 0;
break;
case 4:
if(s.m_stype == SPISymbol::TYPE_DESELECT)
state = 0;
break;
}
}
cap->MarkSamplesModifiedFromCpu();
cap->MarkTimestampsModifiedFromCpu();
SetData(cap, 0);
}
85 changes: 85 additions & 0 deletions scopeprotocols/DAC8552Decoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@

/***********************************************************************************************************************
* *
* libscopeprotocols *
* *
* Copyright (c) 2012-2026 Andrew D. Zonenberg and contributors *
* 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 Daniel Bauer
@brief Declaration of DAC8552Decoder
*/
#ifndef DAC8522Decoder_h
#define DAC8522Decoder_h

class DAC8552Symbol
{
public:
DAC8552Symbol(uint8_t flags = 0, uint16_t value=0xDEAD)
: m_flags(flags)
, m_value(value)
{}
// Rather store all the flags in 1 byte instead of making the struct 5 bytes large and then get funky padding
// This will most likely get padded to a nice handy integer
static constexpr uint8_t MASK_LOAD_A = 0x10;
static constexpr uint8_t MASK_LOAD_B = 0x20;
static constexpr uint8_t MASK_BFR_SEL = 0x04;
uint8_t m_flags;
uint16_t m_value;

bool operator==(const DAC8552Symbol& s) const
{
return (m_flags == s.m_flags) && (m_value == s.m_value);
}
bool loadA() const { return m_flags & MASK_LOAD_A ? true : false; }
bool loadB() const { return m_flags & MASK_LOAD_B ? true : false; }
bool bfrSelect() const { return m_flags & MASK_BFR_SEL ? true : false; }
};

class DAC8552Waveform : public SparseWaveform<DAC8552Symbol>
{
public:
DAC8552Waveform (const std::string& color) : SparseWaveform<DAC8552Symbol>(), m_color(color) {};
virtual std::string GetText(size_t override);
virtual std::string GetColor(size_t override);

private:
const std::string& m_color;
};

class DAC8552Decoder : public Filter
{
public:
DAC8552Decoder(const std::string& color);

virtual void Refresh(vk::raii::CommandBuffer& cmdBuf, std::shared_ptr<QueueHandle> queue) override;
static std::string GetProtocolName();

PROTOCOL_DECODER_INITPROC(DAC8552Decoder)
};

#endif
1 change: 1 addition & 0 deletions scopeprotocols/scopeprotocols.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void ScopeProtocolStaticInit()
AddDecoderClass(CSVImportFilter);
AddDecoderClass(CTLEFilter);
AddDecoderClass(CurrentShuntFilter);
AddDecoderClass(DAC8552Decoder);
AddDecoderClass(DCDMeasurement);
AddDecoderClass(DDJMeasurement);
AddDecoderClass(DDR1Decoder);
Expand Down
1 change: 1 addition & 0 deletions scopeprotocols/scopeprotocols.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
#include "CSVImportFilter.h"
#include "CTLEFilter.h"
#include "CurrentShuntFilter.h"
#include "DAC8552Decoder.h"
#include "DCDMeasurement.h"
#include "DDJMeasurement.h"
#include "DDR1Decoder.h"
Expand Down