add: auto build decoder stack

This commit is contained in:
dreamsourcelabTAI 2022-03-29 15:49:07 +08:00
parent 940a8c7ecc
commit e6a496755f
21 changed files with 398 additions and 181 deletions

View File

@ -30,6 +30,8 @@
#include <cstring>
#include <assert.h>
#include <string.h>
#include <QDebug>
#include "../../config/appconfig.h"
#include "decoderstatus.h"
#include "../../dsvdef.h"
@ -124,7 +126,10 @@ Annotation::~Annotation()
const std::vector<QString>& Annotation::annotations() const
{
AnnotationSourceItem &resItem = *(_status->m_resTable.GetItem(_resIndex));
AnnotationSourceItem *pobj = _status->m_resTable.GetItem(_resIndex);
assert(pobj);
AnnotationSourceItem &resItem = *pobj;
//get origin data, is not a numberic value
if (!resItem.is_numeric){
@ -142,13 +147,21 @@ const std::vector<QString>& Annotation::annotations() const
if (resItem.src_lines.size() > 0)
{
char sz_format_tmp_buf[200] = {0};
//have custom string
for (QString &rd_src : resItem.src_lines)
{
char sz_format_tmp_buf[50] = {0};
{
QString src = rd_src.replace("{$}", "%s");
const char *num_str = _status->m_resTable.format_numberic(resItem.str_number_hex, resItem.cur_display_format);
sprintf(sz_format_tmp_buf, src.toUtf8().data(), num_str);
const char *src_str = src.toUtf8().data();
if (strlen(src_str) + strlen(num_str) > sizeof(sz_format_tmp_buf)){
qDebug()<<"Annotation string length is too long!";
return resItem.src_lines;
}
sprintf(sz_format_tmp_buf, src_str, num_str);
resItem.cvt_lines.push_back(QString(sz_format_tmp_buf));
}
}

View File

@ -97,6 +97,10 @@ public:
return ch->type;
}
inline const srd_decoder* get_dec_handel(){
return _decoder;
}
private:
const srd_decoder *const _decoder;

View File

@ -34,5 +34,5 @@ public:
bool m_bNumeric; //when decoder get any numerical data,it will be set
int m_format; //protocol format code
void *sdr_decoder_handle;
AnnotationResTable m_resTable;
AnnotationResTable m_resTable;
};

View File

@ -56,7 +56,7 @@ DecoderStack::DecoderStack(pv::SigSession *session,
{
assert(session);
assert(dec);
assert(decoder_status);
assert(decoder_status);
_samples_decoded = 0;
_sample_count = 0;
@ -96,7 +96,7 @@ DecoderStack::~DecoderStack()
_class_rows.clear();
}
void DecoderStack::push(decode::Decoder *decoder)
void DecoderStack::add_sub_decoder(decode::Decoder *decoder)
{
assert(decoder);
_stack.push_back(decoder);
@ -104,7 +104,7 @@ void DecoderStack::push(decode::Decoder *decoder)
_options_changed = true;
}
void DecoderStack::remove(Decoder *decoder)
void DecoderStack::remove_sub_decoder(Decoder *decoder)
{
// Find the decoder in the stack
auto iter = _stack.begin();
@ -123,6 +123,22 @@ void DecoderStack::remove(Decoder *decoder)
_options_changed = true;
}
void DecoderStack::remove_decoder_by_handel(const srd_decoder *dec)
{
Decoder *decoder = NULL;
for (auto d : _stack){
if (d->get_dec_handel() == dec){
decoder = d;
break;
}
}
if (decoder){
remove_sub_decoder(decoder);
}
}
void DecoderStack::build_row()
{
//release source

View File

@ -94,8 +94,10 @@ public:
return _stack;
}
void push(decode::Decoder *decoder);
void remove(decode::Decoder *decoder);
void add_sub_decoder(decode::Decoder *decoder);
void remove_sub_decoder(decode::Decoder *decoder);
void remove_decoder_by_handel(const srd_decoder *dec);
void build_row();
int64_t samples_decoded();
@ -154,6 +156,10 @@ public:
return _error_message;
}
inline void *get_key_handel(){
return _decoder_status;
}
private:
void decode_data(const uint64_t decode_start, const uint64_t decode_end, srd_session *const session);
void execute_decode_stack();

View File

@ -122,5 +122,5 @@ std::map<uint16_t, QString> Search::get_pattern()
return pattern;
}
} // namespace decoder
} // namespace dialogs
} // namespace pv

View File

@ -64,7 +64,7 @@ private:
QDialogButtonBox search_buttonBox;
};
} // namespace decoder
} // namespace dialogs
} // namespace pv
#endif // DSVIEW_PV_SEARCH_H

View File

@ -51,6 +51,7 @@
#include "../dsvdef.h"
#include "../config/appconfig.h"
#include "../data/decode/decoderstatus.h"
#include "../data/decode/decoder.h"
#define PROTOCOL_FIND_TITLE "Protocol search..."
@ -113,7 +114,9 @@ ProtocolDock::ProtocolDock(QWidget *parent, view::View &view, SigSession *sessio
_protocol_combobox->setLineEdit(new KeywordLineEdit(_protocol_combobox));
_protocol_combobox->setCompleter(NULL);
GSList *l = g_slist_sort(g_slist_copy((GSList*)srd_decoder_list()), decoder_name_cmp);
//GSList *l = g_slist_sort(g_slist_copy((GSList*)srd_decoder_list()), decoder_name_cmp);
GSList *l = const_cast<GSList*>(srd_decoder_list());
std::map<std::string, int> pro_key_table;
QString repeatNammes;
@ -122,22 +125,19 @@ ProtocolDock::ProtocolDock(QWidget *parent, view::View &view, SigSession *sessio
{
const srd_decoder *const d = (srd_decoder*)l->data;
assert(d);
const bool have_probes = (d->channels || d->opt_channels) != 0;
if (true == have_probes) {
DecoderInfoItem *info = new DecoderInfoItem();
strncpy(info->Name, d->name, DECODER_NAME_LEN-1);
strncpy(info->Id, d->id, DECODER_NAME_LEN-1);
info->ObjectHandle = l->data;
// const bool have_probes = (d->channels || d->opt_channels) != 0;
if (true) {
DecoderInfoItem *info = new DecoderInfoItem();
srd_decoder *dec = (srd_decoder *)(l->data);
info->ObjectHandle = dec;
_decoderInfoList.push_back(info);
std::string prokey(info->Id);
std::string prokey(dec->id);
if (pro_key_table.find(prokey) != pro_key_table.end()){
if (repeatNammes != "")
repeatNammes += ",";
repeatNammes += info->Id;
repeatNammes += QString(dec->id);
}
else{
pro_key_table[prokey] = 1;
@ -154,7 +154,8 @@ ProtocolDock::ProtocolDock(QWidget *parent, view::View &view, SigSession *sessio
for (auto info : _decoderInfoList){
info->Index = protocol_index;
protocol_index++;
_protocol_combobox->addItem(QString::fromUtf8(info->Name), QVariant::fromValue(info->Index));
srd_decoder *dec = (srd_decoder *)(info->ObjectHandle);
_protocol_combobox->addItem(QString::fromUtf8(dec->name), QVariant::fromValue(info->Index));
}
_protocol_combobox->setCurrentIndex(-1);
@ -362,7 +363,8 @@ int ProtocolDock::get_protocol_index_by_id(QString id)
{
int dex = 0;
for (auto info : _decoderInfoList){
QString proid(info->Id);
srd_decoder *dec = (srd_decoder *)(info->ObjectHandle);
QString proid(dec->id);
if (id == proid){
return dex;
}
@ -383,12 +385,58 @@ void ProtocolDock::on_add_protocol()
}
int dex = _protocol_combobox->itemData(_protocol_combobox->currentIndex()).toInt();
QString pro_id(_decoderInfoList[dex]->Id);
add_protocol_by_id(pro_id, false);
//check the base protocol
srd_decoder *const dec = (srd_decoder *)(_decoderInfoList[dex]->ObjectHandle);
QString pro_id(dec->id);
std::list<data::decode::Decoder*> sub_decoders;
assert(dec->inputs);
QString input_id = parse_protocol_id((char *)dec->inputs->data);
if (input_id != "logic")
{
pro_id = ""; //reset base protocol
int base_dex = get_output_protocol_by_id(input_id);
sub_decoders.push_front(new data::decode::Decoder(dec));
while (base_dex != -1)
{
srd_decoder *base_dec = (srd_decoder *)(_decoderInfoList[base_dex]->ObjectHandle);
pro_id = QString(base_dec->id); //change base protocol
assert(base_dec->inputs);
input_id = parse_protocol_id((char *)base_dec->inputs->data);
if (input_id == "logic")
{
break;
}
sub_decoders.push_front(new data::decode::Decoder(base_dec));
pro_id = ""; //reset base protocol
base_dex = get_output_protocol_by_id(input_id);
}
}
if (pro_id == ""){
MsgBox::Show("error", "find the base protocol error!");
for(auto sub: sub_decoders){
delete sub;
}
sub_decoders.clear();
return;
}
add_protocol_by_id(pro_id, false, sub_decoders);
}
bool ProtocolDock::add_protocol_by_id(QString id, bool silent)
bool ProtocolDock::add_protocol_by_id(QString id, bool silent, std::list<pv::data::decode::Decoder*> &sub_decoders)
{
if (_session->get_device()->dev_inst()->mode != LOGIC) {
qDebug()<<"Protocol Analyzer\nProtocol Analyzer is only valid in Digital Mode!";
@ -404,34 +452,42 @@ bool ProtocolDock::add_protocol_by_id(QString id, bool silent)
srd_decoder *const decoder = (srd_decoder *)(_decoderInfoList[dex]->ObjectHandle);
DecoderStatus *dstatus = new DecoderStatus();
dstatus->m_format = (int)DecoderDataFormat::hex;
if (_session->add_decoder(decoder, silent, dstatus))
{
//create item layer
QString protocolName(_decoderInfoList[dex]->Name);
ProtocolItemLayer *layer = new ProtocolItemLayer(_up_widget, protocolName, this);
_protocol_lay_items.push_back(layer);
_up_layout->insertLayout(_protocol_lay_items.size(), layer);
layer->m_decoderStatus = dstatus;
//set current protocol format
string fmt = AppConfig::Instance().GetProtocolFormat(protocolName.toStdString());
if (fmt != ""){
layer->SetProtocolFormat(fmt.c_str());
dstatus->m_format = DecoderDataFormat::Parse(fmt.c_str());
}
QString protocolName(decoder->name);
QString protocolId(decoder->id);
//progress connection
const auto &decode_sigs = _session->get_decode_signals();
connect(decode_sigs.back(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progress(int)));
protocol_updated();
return true;
if (sub_decoders.size()){
auto it = sub_decoders.end();
it--;
protocolName = QString((*it)->decoder()->name);
protocolId = QString((*it)->decoder()->id);
}
return false;
if (_session->add_decoder(decoder, silent, dstatus, sub_decoders) == false){
return false;
}
// create item layer
ProtocolItemLayer *layer = new ProtocolItemLayer(_up_widget, protocolName, this);
_protocol_lay_items.push_back(layer);
_up_layout->insertLayout(_protocol_lay_items.size(), layer);
layer->m_decoderStatus = dstatus;
layer->m_protocolId = protocolId;
// set current protocol format
string fmt = AppConfig::Instance().GetProtocolFormat(protocolId.toStdString());
if (fmt != "")
{
layer->SetProtocolFormat(fmt.c_str());
dstatus->m_format = DecoderDataFormat::Parse(fmt.c_str());
}
// progress connection
const auto &decode_sigs = _session->get_decode_signals();
protocol_updated();
connect(decode_sigs.back(), SIGNAL(decoded_progress(int)), this, SLOT(decoded_progress(int)));
return true;
}
void ProtocolDock::on_del_all_protocol(){
@ -850,42 +906,51 @@ void ProtocolDock::search_update()
//-------------------IProtocolItemLayerCallback
void ProtocolDock::OnProtocolSetting(void *handle){
int dex = 0;
for (auto it = _protocol_lay_items.begin(); it != _protocol_lay_items.end(); it++){
if ((*it) == handle){
_session->rst_decoder(dex);
if ((*it) == handle){
void *key_handel = (*it)->get_protocol_key_handel();
_session->rst_decoder_by_key_handel(key_handel);
protocol_updated();
break;
}
dex++;
}
}
}
void ProtocolDock::OnProtocolDelete(void *handle){
if (!MsgBox::Confirm("Are you sure to remove this protocol analyzer?", this)){
return;
}
}
int dex = 0;
for (auto it = _protocol_lay_items.begin(); it != _protocol_lay_items.end(); it++){
if ((*it) == handle){
DESTROY_QT_LATER(*it);
_protocol_lay_items.remove(dex);
_session->remove_decoder(dex);
protocol_updated();
break;
}
dex++;
}
for (auto it = _protocol_lay_items.begin(); it != _protocol_lay_items.end(); it++)
{
if ((*it) == handle)
{
auto lay = (*it);
void *key_handel = lay->get_protocol_key_handel();
_protocol_lay_items.erase(it);
DESTROY_QT_LATER(lay);
_session->remove_decoder_by_key_handel(key_handel);
protocol_updated();
break;
}
}
}
void ProtocolDock::OnProtocolFormatChanged(QString format, void *handle){
for (auto it = _protocol_lay_items.begin(); it != _protocol_lay_items.end(); it++){
if ((*it) == handle){
QString &name = (*it)->GetProtocolName();
AppConfig::Instance().SetProtocolFormat(name.toStdString(), format.toStdString());
(*it)->m_decoderStatus->m_format = DecoderDataFormat::Parse(format.toStdString().c_str());
protocol_updated();
auto lay = (*it);
AppConfig::Instance().SetProtocolFormat(lay->m_protocolId.toStdString(), format.toStdString());
if (lay->m_decoderStatus != NULL)
{
lay->m_decoderStatus->m_format = DecoderDataFormat::Parse(format.toStdString().c_str());
protocol_updated();
}
break;
}
}
@ -900,13 +965,15 @@ void ProtocolDock::on_decoder_name_edited(const QString &value)
_protocol_combobox->removeItem(0);
}
for (auto &info: _decoderInfoList){
QString name(info->Name);
QString id(info->Id);
for (auto info: _decoderInfoList){
srd_decoder *dec = (srd_decoder *)(info->ObjectHandle);
QString name(dec->name);
QString id(dec->id);
if (value == ""
|| name.indexOf(value, 0, Qt::CaseInsensitive) != -1
|| id.indexOf(value, 0, Qt::CaseInsensitive) != -1 ){
_protocol_combobox->addItem(QString::fromUtf8(info->Name), QVariant::fromValue(info->Index));
_protocol_combobox->addItem(QString::fromUtf8(dec->name), QVariant::fromValue(info->Index));
}
}
@ -934,8 +1001,10 @@ void ProtocolDock::on_decoder_name_edited(const QString &value)
bool ProtocolDock::protocol_sort_callback(const DecoderInfoItem *o1, const DecoderInfoItem *o2)
{
const char *s1 = o1->Name;
const char *s2 = o2->Name;
srd_decoder *dec1 = (srd_decoder *)(o1->ObjectHandle);
srd_decoder *dec2 = (srd_decoder *)(o2->ObjectHandle);
const char *s1 = dec1->name;
const char *s2 = dec2->name;
char c1 = 0;
char c2 = 0;
@ -981,6 +1050,61 @@ bool ProtocolDock::eventFilter(QObject *object, QEvent *event)
on_add_protocol();
}
}
QString ProtocolDock::parse_protocol_id(const char *id)
{
if (id == NULL || *id == 0){
assert(false);
}
char buf[25];
strncpy(buf, id, sizeof(buf));
char *rd = buf;
char *start = NULL;
int len = 0;
while (*rd && len - 1 < sizeof(buf))
{
if (*rd == '['){
start = rd++;
}
else if (*rd == ']'){
*rd = 0;
break;
}
++rd;
len++;
}
if (start == NULL){
start = const_cast<char*>(id);
}
return QString(start);
}
int ProtocolDock::get_output_protocol_by_id(QString id)
{
int dex = 0;
for (auto info : _decoderInfoList)
{
srd_decoder *dec = (srd_decoder *)(info->ObjectHandle);
if (dec->outputs)
{
QString output_id = parse_protocol_id((char*)dec->outputs->data);
if (output_id == id)
{
QString proid(dec->id);
if (!proid.startsWith("0:") || output_id == proid){
return dex;
}
}
}
++dex;
}
return -1;
}
//-------------------------

View File

@ -27,8 +27,7 @@
#include <QDockWidget>
#include <QPushButton>
#include <QLabel>
#include <QVector>
#include <QLabel>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QScrollArea>
@ -40,17 +39,14 @@
#include <vector>
#include <mutex>
#include <list>
#include "../data/decodermodel.h"
#include "protocolitemlayer.h"
#include "../ui/dscombobox.h"
#include "../dstimer.h"
#define DECODER_NAME_LEN 20
struct DecoderInfoItem{
char Name[DECODER_NAME_LEN];
char Id[DECODER_NAME_LEN];
int Index;
void *ObjectHandle; //srd_decoder* type
};
@ -75,7 +71,10 @@ namespace pv {
class SigSession;
namespace data {
class DecoderModel;
class DecoderModel;
namespace decode{
class Decoder;
}
}
namespace view {
@ -96,7 +95,7 @@ public:
~ProtocolDock();
void del_all_protocol();
bool add_protocol_by_id(QString id, bool silent);
bool add_protocol_by_id(QString id, bool silent, std::list<pv::data::decode::Decoder*> &sub_decoders);
private:
void changeEvent(QEvent *event);
@ -106,13 +105,16 @@ private:
protected:
void paintEvent(QPaintEvent *);
void resizeEvent(QResizeEvent *);
int get_protocol_index_by_id(QString id);
static QString parse_protocol_id(const char *id);
int get_output_protocol_by_id(QString id);
private:
//IProtocolItemLayerCallback
void OnProtocolSetting(void *handle);
void OnProtocolDelete(void *handle);
void OnProtocolFormatChanged(QString format, void *handle);
int get_protocol_index_by_id(QString id);
signals:
void protocol_updated();
@ -168,7 +170,7 @@ private:
QPushButton *_del_all_button;
DsComboBox *_protocol_combobox;
QVBoxLayout *_up_layout;
QVector <ProtocolItemLayer*> _protocol_lay_items; //protocol item layers
std::vector <ProtocolItemLayer*> _protocol_lay_items; //protocol item layers
QPushButton *_dn_set_button;
QPushButton *_dn_save_button;

View File

@ -34,6 +34,7 @@ ProtocolItemLayer::ProtocolItemLayer(QWidget *parent, QString protocolName, IPro
m_callback = callback;
_protocolName = protocolName;
m_bSetting = false;
m_decoderStatus = NULL;
_protocol_label = new QLabel(parent);
_progress_label = new QLabel(parent);
@ -48,8 +49,7 @@ ProtocolItemLayer::ProtocolItemLayer(QWidget *parent, QString protocolName, IPro
_set_button->setIcon(QIcon(iconPath + "/gear.svg"));
_protocol_label->setText(protocolName);
m_singleFlag = true;
m_decoderStatus = NULL;
m_singleFlag = true;
LoadFormatSelect(false);

View File

@ -53,6 +53,10 @@ public:
void LoadFormatSelect(bool bSingle);
inline QString &GetProtocolName(){return _protocolName;}
void SetProtocolFormat(const char *format);
inline void* get_protocol_key_handel(){
return m_decoderStatus;
}
private slots:
void on_set_protocol();
@ -61,6 +65,7 @@ private slots:
public:
DecoderStatus *m_decoderStatus; //DecoderStatus
QString m_protocolId;
private:
QLabel *_protocol_label;
@ -69,9 +74,9 @@ private:
QPushButton *_del_button;
DsComboBox *_format_combox;
IProtocolItemLayerCallback *m_callback;
QString _protocolName;
bool m_bSetting;
bool m_singleFlag;
QString _protocolName; //the lable text
bool m_bSetting;
bool m_singleFlag;
};
} //dock

View File

@ -1321,13 +1321,10 @@ uint16_t SigSession::get_ch_num(int type)
return num_channels;
}
bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus){
return do_add_decoder(dec, silent, dstatus);
}
bool SigSession::add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus,
std::list<pv::data::decode::Decoder*> &sub_decoders){
bool SigSession::do_add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus)
{
try {
try {
bool ret = false;
@ -1350,6 +1347,12 @@ bool SigSession::do_add_decoder(srd_decoder *const dec, bool silent, DecoderStat
view::DecodeTrace *trace = new view::DecodeTrace(this, decoder_stack, _decode_traces.size());
assert(trace);
//add sub decoder
for(auto sub : sub_decoders){
trace->decoder()->add_sub_decoder(sub);
}
sub_decoders.clear();
// set view early for decode start/end region setting
for(auto &s : _signals) {
if (s->get_view()) {
@ -1357,6 +1360,7 @@ bool SigSession::do_add_decoder(srd_decoder *const dec, bool silent, DecoderStat
break;
}
}
if (silent) {
ret = true;
} else if (trace->create_popup()) {
@ -1364,7 +1368,7 @@ bool SigSession::do_add_decoder(srd_decoder *const dec, bool silent, DecoderStat
}
if (ret)
{
{
_decode_traces.push_back(trace);
add_decode_task(trace);
signals_changed();
@ -1381,7 +1385,7 @@ bool SigSession::do_add_decoder(srd_decoder *const dec, bool silent, DecoderStat
ds_debug("Starting a hotplug thread...\n");
}
return false;
return false;
}
std::vector<view::DecodeTrace*>& SigSession::get_decode_signals()
@ -1389,6 +1393,20 @@ std::vector<view::DecodeTrace*>& SigSession::get_decode_signals()
return _decode_traces;
}
int SigSession::get_trace_index_by_key_handel(void *handel)
{
int dex = 0;
for(auto tr : _decode_traces){
if (tr->decoder()->get_key_handel() == handel){
return dex;
}
++dex;
}
return -1;
}
void SigSession::remove_decoder(int index)
{
int size = (int)_decode_traces.size();
@ -1412,9 +1430,15 @@ void SigSession::remove_decoder(int index)
}
}
void SigSession::remove_decoder_by_key_handel(void *handel)
{
int dex = get_trace_index_by_key_handel(handel);
remove_decoder(dex);
}
void SigSession::rst_decoder(int index)
{
auto trace = get_decoder_trace(index);
auto trace = get_decoder_trace(index);
if (trace && trace->create_popup() ){
remove_decode_task(trace); //remove old task
@ -1422,6 +1446,12 @@ void SigSession::rst_decoder(int index)
data_updated();
}
}
void SigSession::rst_decoder_by_key_handel(void *handel)
{
int dex = get_trace_index_by_key_handel(handel);
rst_decoder(dex);
}
pv::data::DecoderModel* SigSession::get_decoder_model()
{
@ -1866,9 +1896,10 @@ void SigSession::set_stop_scale(float scale)
view::DecodeTrace* SigSession::get_decoder_trace(int index)
{
int size = (int)_decode_traces.size();
assert(index < size);
return _decode_traces[index];
if (index >= 0 && index < (int)_decode_traces.size()){
return _decode_traces[index];
}
assert(false);
}
view::DecodeTrace* SigSession::get_top_decode_task()

View File

@ -30,6 +30,7 @@
#include <QString>
#include <thread>
#include <QDateTime>
#include <list>
#include "view/mathtrace.h"
#include "data/mathstack.h"
@ -63,6 +64,11 @@ class Group;
class GroupSnapshot;
class DecoderModel;
class MathStack;
namespace decode {
class Decoder;
}
}
namespace device {
@ -78,11 +84,6 @@ class LissajousTrace;
class MathTrace;
}
namespace decoder {
class Decoder;
class DecoderFactory;
}
using namespace pv::device;
//created by MainWindow
@ -162,11 +163,16 @@ public:
std::vector<view::Signal*>& get_signals();
std::vector<view::GroupSignal*>& get_group_signals();
bool add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus);
void remove_decoder(int index);
std::vector<view::DecodeTrace*>& get_decode_signals();
bool add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus,
std::list<pv::data::decode::Decoder*> &sub_decoders);
int get_trace_index_by_key_handel(void *handel);
void remove_decoder(int index);
void remove_decoder_by_key_handel(void *handel);
std::vector<view::DecodeTrace*>& get_decode_signals();
void rst_decoder(int index);
void rst_decoder_by_key_handel(void *handel);
pv::data::DecoderModel* get_decoder_model();
std::vector<view::SpectrumTrace*>& get_spectrum_traces();
view::LissajousTrace* get_lissajous_trace();
@ -277,8 +283,7 @@ private:
private:
void set_capture_state(capture_state state);
void register_hotplug_callback();
void deregister_hotplug_callback();
bool do_add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus);
void deregister_hotplug_callback();
void add_decode_task(view::DecodeTrace *trace);
void remove_decode_task(view::DecodeTrace *trace);

View File

@ -50,6 +50,7 @@
#include <math.h>
#include <QTextStream>
#include <QDebug>
#include <list>
#ifdef _WIN32
#include <QTextCodec>
@ -993,10 +994,36 @@ bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra
QJsonObject dec_obj = dec_value.toObject();
std::vector<view::DecodeTrace*> &pre_dsigs = _session->get_decode_signals();
//set current protocol
bool ret = widget->add_protocol_by_id(dec_obj["id"].toString(), true);
std::list<pv::data::decode::Decoder*> sub_decoders;
//get sub decoders
if (dec_obj.contains("stacked decoders")) {
for(const QJsonValue &value : dec_obj["stacked decoders"].toArray()) {
QJsonObject stacked_obj = value.toObject();
GSList *dl = g_slist_copy((GSList*)srd_decoder_list());
for(; dl; dl = dl->next) {
const srd_decoder *const d = (srd_decoder*)dl->data;
assert(d);
if (QString::fromUtf8(d->id) == stacked_obj["id"].toString()) {
sub_decoders.push_back(new data::decode::Decoder(d));
break;
}
}
g_slist_free(dl);
}
}
//create protocol
bool ret = widget->add_protocol_by_id(dec_obj["id"].toString(), true, sub_decoders);
if (!ret)
{
for(auto sub : sub_decoders){
delete sub;
}
sub_decoders.clear();
continue; //protocol is not exists;
}
@ -1007,25 +1034,7 @@ bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra
auto new_dsig = aft_dsigs.back();
auto stack = new_dsig->decoder();
if (dec_obj.contains("stacked decoders")) {
for(const QJsonValue &value : dec_obj["stacked decoders"].toArray()) {
QJsonObject stacked_obj = value.toObject();
GSList *dl = g_slist_copy((GSList*)srd_decoder_list());
for(; dl; dl = dl->next) {
const srd_decoder *const d = (srd_decoder*)dl->data;
assert(d);
if (QString::fromUtf8(d->id) == stacked_obj["id"].toString()) {
stack->push(new data::decode::Decoder(d));
break;
}
}
g_slist_free(dl);
}
}
auto &decoder = stack->stack();
for(auto &dec : decoder) {

View File

@ -54,6 +54,7 @@
#include "../toolbars/titlebar.h"
#include "../dsvdef.h"
#include "../ui/dscombobox.h"
#include "../ui/msgbox.h"
#include <QDebug>
using namespace boost;
@ -419,6 +420,13 @@ void DecodeTrace::load_all_decoder_property(std::list<pv::data::decode::Decoder*
create_decoder_form(_decoder_stack, dec, panel, form);
//spacing
if (ls.size() > 1){
QWidget *spc = new QWidget();
spc->setMinimumHeight(15);
lay->addWidget(spc);
}
decoder_panel_item inf;
inf.decoder_handle = dec;
inf.panel = panel;
@ -479,19 +487,7 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
form->addRow(_end_comboBox, new QLabel(
tr("Decode End to")));
// Add stacking button
pv::widgets::DecoderMenu *const decoder_menu =
new pv::widgets::DecoderMenu(parent);
QPushButton *const stack_button =
new QPushButton(tr("Stack Decoder"), parent);
stack_button->setMenu(decoder_menu);
QHBoxLayout *stack_button_box = new QHBoxLayout;
stack_button_box->addWidget(stack_button, 0, Qt::AlignLeft);
form->addRow(stack_button_box);
// Add ButtonBox (OK/Cancel)
QDialogButtonBox *button_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
Qt::Horizontal, parent);
@ -502,8 +498,7 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
form->addRow(confirm_button_box);
connect(_start_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_region_set(int)));
connect(_end_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_region_set(int)));
connect(decoder_menu, SIGNAL(decoder_selected(srd_decoder *)), this, SLOT(on_add_stack(srd_decoder *)));
connect(_end_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(on_region_set(int)));
connect(button_box, SIGNAL(accepted()), parent, SLOT(accept()));
connect(button_box, SIGNAL(rejected()), parent, SLOT(reject()));
}
@ -785,14 +780,12 @@ void DecodeTrace::create_decoder_form(
_bindings.push_back(binding);
//
pv::widgets::DecoderGroupBox *const group =
new pv::widgets::DecoderGroupBox(decoder_stack, dec, decoder_form, parent);
form->addRow(group);
_decoder_forms.push_back(group);
connect(group, SIGNAL(del_stack(data::decode::Decoder*)), this, SLOT(on_del_stack(data::decode::Decoder*)));
}
DsComboBox* DecodeTrace::create_probe_selector(
@ -907,7 +900,7 @@ void DecodeTrace::on_add_stack(srd_decoder *decoder)
auto dec = new data::decode::Decoder(decoder);
_decoder_stack->push(dec);
_decoder_stack->add_sub_decoder(dec);
std::list<pv::data::decode::Decoder*> items;
items.push_back(dec);
@ -935,7 +928,11 @@ void DecodeTrace::on_del_stack(data::decode::Decoder *dec)
assert(dec);
assert(_decoder_stack);
_decoder_stack->remove(dec);
if (MsgBox::Confirm("Are you sure to remove the sub protocol?") == false){
return;
}
_decoder_stack->remove_sub_decoder(dec);
std::list<decoder_panel_item> dels;
std::list<pv::data::decode::Decoder*> adds;
@ -1103,6 +1100,11 @@ void DecodeTrace::frame_ended()
}
}
void* DecodeTrace::get_key_handel()
{
return _decoder_stack->get_key_handel();
}
} // namespace view
} // namespace pv

View File

@ -153,6 +153,8 @@ public:
int get_progress();
void* get_key_handel();
protected:
void paint_type_options(QPainter &p, int right, const QPoint pt, QColor fore);

View File

@ -66,9 +66,9 @@ DecoderGroupBox::DecoderGroupBox(data::DecoderStack *decoder_stack,
assert(d);
const bool have_probes = (d->channels || d->opt_channels) != 0;
if (!have_probes) {
_del_button = new QPushButton(QIcon(iconPath+"/del.svg"), QString(), _widget);
_layout->addWidget(_del_button, 0, 1);
connect(_del_button, SIGNAL(clicked()), this, SLOT(on_del_stack()));
// _del_button = new QPushButton(QIcon(iconPath+"/del.svg"), QString(), _widget);
// _layout->addWidget(_del_button, 0, 1);
//connect(_del_button, SIGNAL(clicked()), this, SLOT(on_del_stack()));
}
_index = 0;

View File

@ -704,7 +704,7 @@ SRD_API int srd_decoder_load(const char *module_name)
int is_subclass;
const char *fail_txt;
PyGILState_STATE gstate;
if (!srd_check_init())
return SRD_ERR;
@ -798,7 +798,7 @@ SRD_API int srd_decoder_load(const char *module_name)
fail_txt = "no 'id' attribute";
goto err_out;
}
if (py_attr_as_str(d->py_dec, "name", &(d->name)) != SRD_OK) {
fail_txt = "no 'name' attribute";
goto err_out;
@ -1066,6 +1066,7 @@ static void srd_decoder_load_all_path(char *path)
{
GDir *dir;
const gchar *direntry;
int ldst = 0;
if (!(dir = g_dir_open(path, 0, NULL))) {
/* Not really fatal. Try zipimport method too. */
@ -1080,7 +1081,7 @@ static void srd_decoder_load_all_path(char *path)
*/
while ((direntry = g_dir_read_name(dir)) != NULL) {
/* The directory name is the module name (e.g. "i2c"). */
srd_decoder_load(direntry);
ldst = srd_decoder_load(direntry);
}
g_dir_close(dir);
}

View File

@ -108,9 +108,10 @@ class Decoder(srd.Decoder):
reg_desc = regs.get(reg, 'Reserved %#x' % reg)
if reg > 0x63:
reg_desc = 'Unknown'
if write:
self.putx([1, ['%s: %#x' % (reg_desc, arg)]])
self.putx([1, ['%s: {$}' % reg_desc, '@%02X' % arg]])
else:
self.putx([0, ['%s: %d' % (reg_desc, arg)]])
self.putx([0, ['%s: {$}' % reg_desc, '@%02X' % arg]])
self.mosi_bytes = []

View File

@ -410,8 +410,7 @@ class Decoder(srd.Decoder):
self.address <<= 1
self.address >>= 1
self.put(start_sample, addr_bit[2], self.out_ann,
[Ann.REG_ADDRESS, ['ADDRESS: 0x%02X' % self.address, 'ADDR: 0x%02X'
% self.address, '0x%02X' % self.address]])
[Ann.REG_ADDRESS, ['ADDRESS: {$}', 'ADDR: {$}', '{$}', '@%02X' % self.address]])
self.ss = -1
self.state = St.DATA

View File

@ -46,6 +46,7 @@ class Decoder(srd.Decoder):
('single_write', 'Single register write'),
('burst_read', 'Burst register read'),
('burst_write', 'Burst register write'),
('status_read', 'Status read'),
('status', 'Status register'),
('warning', 'Warning'),
)
@ -72,13 +73,8 @@ class Decoder(srd.Decoder):
'''Put a warning message 'msg' at 'pos'.'''
self.put(pos.ss, pos.es, self.out_ann, [ANN_WARN, [msg]])
def putp(self, pos, ann, msg):
'''Put an annotation message 'msg' at 'pos'.'''
self.put(pos.ss, pos.es, self.out_ann, [ann, [msg]])
def putp2(self, pos, ann, msg1, msg2):
'''Put an annotation message 'msg' at 'pos'.'''
self.put(pos.ss, pos.es, self.out_ann, [ann, [msg1, msg2]])
def put_ann(self, pos, ann, data):
self.put(pos.ss, pos.es, self.out_ann, [ann, data])
def next(self):
'''Resets the decoder after a complete command was decoded.'''
@ -116,7 +112,7 @@ class Decoder(srd.Decoder):
self.cmd, self.dat, self.min, self.max = c
if self.cmd == 'Strobe':
self.putp(pos, ANN_STROBE, self.format_command())
self.put_ann(pos, ANN_STROBE, [self.format_command()])
else:
# Don't output anything now, the command is merged with
# the data bytes following it.
@ -210,9 +206,10 @@ class Decoder(srd.Decoder):
else:
longtext_fifo = '{} bytes free in TX FIFO'.format(fifo_bytes)
text = '{} = {:02X}'.format(label, status)
text = '{} = '.format(label) + '{$}'
longtext = ''.join([text, '; ', longtext_chiprdy, longtext_state, longtext_fifo])
self.putp2(pos, ann, longtext, text)
#self.printlog(longtext + ' ,' + text + '\n')
self.put_ann(pos, ann, [longtext, text, '@%02X' % status])
def decode_mb_data(self, pos, ann, data, label):
'''Decodes the data bytes 'data' of a multibyte command at position
@ -222,8 +219,8 @@ class Decoder(srd.Decoder):
return '{:02X}'.format(b)
data = ' '.join([escape(b) for b in data])
text = '{} = {}'.format(label, data)
self.putp(pos, ann, text)
text = '{} = '.format(label) + '{$}'
self.put_ann(pos, ann, [text, '@' + data])
def finish_command(self, pos):
'''Decodes the remaining data bytes at position 'pos'.'''