diff --git a/DSView/pv/data/decode/annotation.cpp b/DSView/pv/data/decode/annotation.cpp index 0301af06..7fc88831 100755 --- a/DSView/pv/data/decode/annotation.cpp +++ b/DSView/pv/data/decode/annotation.cpp @@ -30,6 +30,8 @@ #include #include #include +#include + #include "../../config/appconfig.h" #include "decoderstatus.h" #include "../../dsvdef.h" @@ -124,7 +126,10 @@ Annotation::~Annotation() const std::vector& 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& 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)); } } diff --git a/DSView/pv/data/decode/decoder.h b/DSView/pv/data/decode/decoder.h index 2b9a3e39..268ff134 100755 --- a/DSView/pv/data/decode/decoder.h +++ b/DSView/pv/data/decode/decoder.h @@ -97,6 +97,10 @@ public: return ch->type; } + inline const srd_decoder* get_dec_handel(){ + return _decoder; + } + private: const srd_decoder *const _decoder; diff --git a/DSView/pv/data/decode/decoderstatus.h b/DSView/pv/data/decode/decoderstatus.h index abc9231f..cdc2252a 100644 --- a/DSView/pv/data/decode/decoderstatus.h +++ b/DSView/pv/data/decode/decoderstatus.h @@ -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; }; diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index 8d6db49e..0adff7bd 100755 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -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 diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index ff43e21a..28ca7540 100755 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -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(); diff --git a/DSView/pv/dialogs/search.cpp b/DSView/pv/dialogs/search.cpp index 406f1be8..ff630146 100755 --- a/DSView/pv/dialogs/search.cpp +++ b/DSView/pv/dialogs/search.cpp @@ -122,5 +122,5 @@ std::map Search::get_pattern() return pattern; } -} // namespace decoder +} // namespace dialogs } // namespace pv diff --git a/DSView/pv/dialogs/search.h b/DSView/pv/dialogs/search.h index 013c4723..d848dfc0 100755 --- a/DSView/pv/dialogs/search.h +++ b/DSView/pv/dialogs/search.h @@ -64,7 +64,7 @@ private: QDialogButtonBox search_buttonBox; }; -} // namespace decoder +} // namespace dialogs } // namespace pv #endif // DSVIEW_PV_SEARCH_H diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp index 4c0abdc3..cd004ac9 100755 --- a/DSView/pv/dock/protocoldock.cpp +++ b/DSView/pv/dock/protocoldock.cpp @@ -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(srd_decoder_list()); std::map 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 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 &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(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; + } //------------------------- diff --git a/DSView/pv/dock/protocoldock.h b/DSView/pv/dock/protocoldock.h index ff3efa15..4c332940 100755 --- a/DSView/pv/dock/protocoldock.h +++ b/DSView/pv/dock/protocoldock.h @@ -27,8 +27,7 @@ #include #include -#include -#include +#include #include #include #include @@ -40,17 +39,14 @@ #include #include +#include #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 &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 _protocol_lay_items; //protocol item layers + std::vector _protocol_lay_items; //protocol item layers QPushButton *_dn_set_button; QPushButton *_dn_save_button; diff --git a/DSView/pv/dock/protocolitemlayer.cpp b/DSView/pv/dock/protocolitemlayer.cpp index a4534f98..b7600d98 100644 --- a/DSView/pv/dock/protocolitemlayer.cpp +++ b/DSView/pv/dock/protocolitemlayer.cpp @@ -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); diff --git a/DSView/pv/dock/protocolitemlayer.h b/DSView/pv/dock/protocolitemlayer.h index 3ac129fb..cd0bff9c 100644 --- a/DSView/pv/dock/protocolitemlayer.h +++ b/DSView/pv/dock/protocolitemlayer.h @@ -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 diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 8351ea2c..adf1a5f4 100755 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -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 &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& SigSession::get_decode_signals() @@ -1389,6 +1393,20 @@ std::vector& 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() diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index f7c763d7..5623ed18 100755 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -30,6 +30,7 @@ #include #include #include +#include #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& get_signals(); std::vector& get_group_signals(); - bool add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus); - void remove_decoder(int index); - std::vector& get_decode_signals(); - + bool add_decoder(srd_decoder *const dec, bool silent, DecoderStatus *dstatus, + std::list &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& get_decode_signals(); void rst_decoder(int index); + void rst_decoder_by_key_handel(void *handel); + pv::data::DecoderModel* get_decoder_model(); std::vector& 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); diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index 0389ad78..8bc8b1e5 100755 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -50,6 +50,7 @@ #include #include #include +#include #ifdef _WIN32 #include @@ -993,10 +994,36 @@ bool StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_arra QJsonObject dec_obj = dec_value.toObject(); std::vector &pre_dsigs = _session->get_decode_signals(); - //set current protocol - bool ret = widget->add_protocol_by_id(dec_obj["id"].toString(), true); + std::list 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) { diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index e83d82d9..415eb081 100755 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -54,6 +54,7 @@ #include "../toolbars/titlebar.h" #include "../dsvdef.h" #include "../ui/dscombobox.h" +#include "../ui/msgbox.h" #include using namespace boost; @@ -419,6 +420,13 @@ void DecodeTrace::load_all_decoder_property(std::list 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 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 dels; std::list adds; @@ -1103,6 +1100,11 @@ void DecodeTrace::frame_ended() } } +void* DecodeTrace::get_key_handel() +{ + return _decoder_stack->get_key_handel(); +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index 833b515f..2f277164 100755 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -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); diff --git a/DSView/pv/widgets/decodergroupbox.cpp b/DSView/pv/widgets/decodergroupbox.cpp index 682211af..c262b534 100755 --- a/DSView/pv/widgets/decodergroupbox.cpp +++ b/DSView/pv/widgets/decodergroupbox.cpp @@ -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; diff --git a/libsigrokdecode4DSL/decoder.c b/libsigrokdecode4DSL/decoder.c index 809cb25b..1019c814 100755 --- a/libsigrokdecode4DSL/decoder.c +++ b/libsigrokdecode4DSL/decoder.c @@ -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); } diff --git a/libsigrokdecode4DSL/decoders/adns5020/pd.py b/libsigrokdecode4DSL/decoders/adns5020/pd.py index 9ac778e0..e25aa5a6 100644 --- a/libsigrokdecode4DSL/decoders/adns5020/pd.py +++ b/libsigrokdecode4DSL/decoders/adns5020/pd.py @@ -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 = [] diff --git a/libsigrokdecode4DSL/decoders/adxl345/pd.py b/libsigrokdecode4DSL/decoders/adxl345/pd.py index 2d53e4c0..8ccb6cad 100644 --- a/libsigrokdecode4DSL/decoders/adxl345/pd.py +++ b/libsigrokdecode4DSL/decoders/adxl345/pd.py @@ -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 diff --git a/libsigrokdecode4DSL/decoders/cc1101/pd.py b/libsigrokdecode4DSL/decoders/cc1101/pd.py index 8407b510..a2038907 100644 --- a/libsigrokdecode4DSL/decoders/cc1101/pd.py +++ b/libsigrokdecode4DSL/decoders/cc1101/pd.py @@ -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'.'''