diff --git a/DSView/main.cpp b/DSView/main.cpp index 07bf54a7..58b022b5 100644 --- a/DSView/main.cpp +++ b/DSView/main.cpp @@ -62,20 +62,9 @@ int main(int argc, char *argv[]) DSApplication a(argc, argv); - // Language -#ifdef LANGUAGE_ZH_CN - QTranslator qtTrans; - qtTrans.load(":/qt_zh_CN"); - a.installTranslator(&qtTrans); - - QTranslator DSViewTrans; - DSViewTrans.load(":/DSView_zh"); - a.installTranslator(&DSViewTrans); -#endif - // Set some application metadata QApplication::setApplicationVersion(DS_VERSION_STRING); - QApplication::setApplicationName("DSView(Beta)"); + QApplication::setApplicationName("DSView"); QApplication::setOrganizationDomain("http://www.DreamSourceLab.com"); // Parse arguments @@ -130,7 +119,6 @@ int main(int argc, char *argv[]) } do { - #ifdef ENABLE_DECODE // Initialise libsigrokdecode if (srd_init(NULL) != SRD_OK) { diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index e0b64ab9..58827a03 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -60,7 +60,7 @@ const int64_t DecoderStack::DecodeChunkLength = 4 * 1024; //const int64_t DecoderStack::DecodeChunkLength = 1024 * 1024; const unsigned int DecoderStack::DecodeNotifyPeriod = 1024; -//mutex DecoderStack::_global_decode_mutex; +mutex DecoderStack::_global_decode_mutex; DecoderStack::DecoderStack(pv::SigSession &session, const srd_decoder *const dec) : @@ -145,12 +145,11 @@ void DecoderStack::build_row() _rows[row] = decode::RowData(); std::map::const_iterator iter = _rows_gshow.find(row); if (iter == _rows_gshow.end()) { + _rows_gshow[row] = true; if (row.title().contains("bit", Qt::CaseInsensitive) || row.title().contains("warning", Qt::CaseInsensitive)) { - _rows_gshow[row] = false; _rows_lshow[row] = false; } else { - _rows_gshow[row] = true; _rows_lshow[row] = true; } } @@ -169,12 +168,11 @@ void DecoderStack::build_row() _rows[row] = decode::RowData(); std::map::const_iterator iter = _rows_gshow.find(row); if (iter == _rows_gshow.end()) { + _rows_gshow[row] = true; if (row.title().contains("bit", Qt::CaseInsensitive) || row.title().contains("warning", Qt::CaseInsensitive)) { - _rows_gshow[row] = false; _rows_lshow[row] = false; } else { - _rows_gshow[row] = true; _rows_lshow[row] = true; } } @@ -553,7 +551,7 @@ void DecoderStack::decode_data( void DecoderStack::decode_proc() { - //lock_guard decode_lock(_global_decode_mutex); + lock_guard decode_lock(_global_decode_mutex); optional sample_count; srd_session *session; diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index 8f38d361..8e0d882f 100644 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -169,7 +169,7 @@ private: * @todo A proper solution should be implemented to allow multiple * decode operations. */ - //static boost::mutex _global_decode_mutex; + static boost::mutex _global_decode_mutex; std::list< boost::shared_ptr > _stack; diff --git a/DSView/pv/device/devinst.cpp b/DSView/pv/device/devinst.cpp index 731df1fc..347ce869 100644 --- a/DSView/pv/device/devinst.cpp +++ b/DSView/pv/device/devinst.cpp @@ -183,6 +183,13 @@ GSList* DevInst::get_dev_mode_list() return sr_dev_mode_list(sdi); } +QString DevInst::name() +{ + sr_dev_inst *const sdi = dev_inst(); + assert(sdi); + return QString::fromLocal8Bit(sdi->driver->name); +} + bool DevInst::is_trigger_enabled() const { return false; diff --git a/DSView/pv/device/devinst.h b/DSView/pv/device/devinst.h index da441a7f..c5e58d62 100644 --- a/DSView/pv/device/devinst.h +++ b/DSView/pv/device/devinst.h @@ -109,6 +109,13 @@ public: */ GSList* get_dev_mode_list(); + /** + * @brief Get the device name from the driver + * + * @return device name + */ + QString name(); + virtual bool is_trigger_enabled() const; public: diff --git a/DSView/pv/devicemanager.cpp b/DSView/pv/devicemanager.cpp index 474db42b..45ebbd4c 100644 --- a/DSView/pv/devicemanager.cpp +++ b/DSView/pv/devicemanager.cpp @@ -47,7 +47,7 @@ using std::ostringstream; using std::runtime_error; using std::string; -char config_path[256]; +extern char AppDataPath[256]; namespace pv { @@ -103,12 +103,9 @@ std::list > DeviceManager::driver_scan( // Check If DSL hardware driver if (strncmp(driver->name, "virtual", 7)) { - QDir dir(QCoreApplication::applicationDirPath()); - if (!dir.cd("res")) + QDir dir(DS_RES_PATH); + if (!dir.exists()) return driver_devices; - QString str = dir.absolutePath() + "/"; - QString str_utf8 = QString::fromLocal8Bit(str.toLocal8Bit()); - strcpy(config_path, str_utf8.toUtf8().data()); } // Do the scan diff --git a/DSView/pv/dock/dsotriggerdock.cpp b/DSView/pv/dock/dsotriggerdock.cpp index 346b7ea4..f7746d63 100644 --- a/DSView/pv/dock/dsotriggerdock.cpp +++ b/DSView/pv/dock/dsotriggerdock.cpp @@ -243,7 +243,7 @@ void DsoTriggerDock::type_changed() void DsoTriggerDock::device_change() { - if (strcmp(_session.get_device()->dev_inst()->driver->name, "DSLogic") != 0) { + if (_session.get_device()->name() != "DSLogic") { position_spinBox->setDisabled(true); position_slider->setDisabled(true); } else { diff --git a/DSView/pv/dock/protocoldock.cpp b/DSView/pv/dock/protocoldock.cpp index b93a13a6..27f83a83 100644 --- a/DSView/pv/dock/protocoldock.cpp +++ b/DSView/pv/dock/protocoldock.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -544,16 +545,54 @@ void ProtocolDock::search_pre() { // now the proxy only contains rows that match the name // let's take the pre one and map it to the original model - if (_model_proxy.rowCount() == 0) + if (_model_proxy.rowCount() == 0) { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; return; - _cur_search_index -= 1; - if (_cur_search_index <= -1 || _cur_search_index >= _model_proxy.rowCount()) - _cur_search_index = _model_proxy.rowCount() - 1; - QModelIndex matchingIndex = _model_proxy.mapToSource(_model_proxy.index(ceil(_cur_search_index),_model_proxy.filterKeyColumn())); - if(matchingIndex.isValid()){ + } + int i; + uint64_t rowCount = _model_proxy.rowCount(); + QModelIndex matchingIndex; + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + do { + _cur_search_index--; + if (_cur_search_index <= -1 || _cur_search_index >= _model_proxy.rowCount()) + _cur_search_index = _model_proxy.rowCount() - 1; + + matchingIndex = _model_proxy.mapToSource(_model_proxy.index(ceil(_cur_search_index),_model_proxy.filterKeyColumn())); + if (!decoder_stack || !matchingIndex.isValid()) + break; + i = 1; + uint64_t row = matchingIndex.row() + 1; + uint64_t col = matchingIndex.column(); + pv::data::decode::Annotation ann; + bool ann_valid; + while(i < _str_list.size()) { + QString nxt = _str_list.at(i); + do { + ann_valid = decoder_stack->list_annotation(ann, col, row); + row++; + }while(ann_valid && (ann.type() < 100 || ann.type() > 999)); + QString source = ann.annotations().at(0); + if (ann_valid && source.contains(nxt)) + i++; + else + break; + } + }while(i < _str_list.size() && --rowCount); + + if(i >= _str_list.size() && matchingIndex.isValid()){ _table_view->scrollTo(matchingIndex); _table_view->setCurrentIndex(matchingIndex); _table_view->clicked(matchingIndex); + } else { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; } } @@ -561,24 +600,67 @@ void ProtocolDock::search_nxt() { // now the proxy only contains rows that match the name // let's take the pre one and map it to the original model - if (_model_proxy.rowCount() == 0) + if (_model_proxy.rowCount() == 0) { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; return; - _cur_search_index += 1; - if (_cur_search_index < 0 || _cur_search_index >= _model_proxy.rowCount()) - _cur_search_index = 0; - QModelIndex matchingIndex = _model_proxy.mapToSource(_model_proxy.index(floor(_cur_search_index),_model_proxy.filterKeyColumn())); - if(matchingIndex.isValid()){ + } + int i; + uint64_t rowCount = _model_proxy.rowCount(); + QModelIndex matchingIndex; + pv::data::DecoderModel *decoder_model = _session.get_decoder_model(); + boost::shared_ptr decoder_stack = decoder_model->getDecoderStack(); + do { + _cur_search_index++; + if (_cur_search_index < 0 || _cur_search_index >= _model_proxy.rowCount()) + _cur_search_index = 0; + + matchingIndex = _model_proxy.mapToSource(_model_proxy.index(floor(_cur_search_index),_model_proxy.filterKeyColumn())); + if (!decoder_stack || !matchingIndex.isValid()) + break; + i = 1; + uint64_t row = matchingIndex.row() + 1; + uint64_t col = matchingIndex.column(); + pv::data::decode::Annotation ann; + bool ann_valid; + while(i < _str_list.size()) { + QString nxt = _str_list.at(i); + do { + ann_valid = decoder_stack->list_annotation(ann, col, row); + row++; + }while(ann_valid && (ann.type() < 100 || ann.type() > 999)); + QString source = ann.annotations().at(0); + if (ann_valid && source.contains(nxt)) + i++; + else + break; + } + }while(i < _str_list.size() && --rowCount); + + if(i >= _str_list.size() && matchingIndex.isValid()){ _table_view->scrollTo(matchingIndex); _table_view->setCurrentIndex(matchingIndex); _table_view->clicked(matchingIndex); + } else { + _table_view->scrollToTop(); + _table_view->clearSelection(); + _matchs_label->setText(QString::number(0)); + _cur_search_index = -1; } } void ProtocolDock::search_done() { QString str = _search_edit->text().trimmed(); - _model_proxy.setFilterFixedString(str); - _matchs_label->setText(QString::number(_model_proxy.rowCount())); + QRegExp rx("(-)"); + _str_list = str.split(rx); + _model_proxy.setFilterFixedString(_str_list.first()); + if (_str_list.size() > 1) + _matchs_label->setText("..."); + else + _matchs_label->setText(QString::number(_model_proxy.rowCount())); } diff --git a/DSView/pv/dock/protocoldock.h b/DSView/pv/dock/protocoldock.h index 71f68db6..bcf4bffd 100644 --- a/DSView/pv/dock/protocoldock.h +++ b/DSView/pv/dock/protocoldock.h @@ -89,6 +89,7 @@ private: SigSession &_session; QSortFilterProxyModel _model_proxy; double _cur_search_index; + QStringList _str_list; QSplitter *_split_widget; QWidget *_up_widget; diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp index 26fbdfa9..5dcb218a 100644 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -285,7 +285,7 @@ void TriggerDock::simple_trigger() void TriggerDock::adv_trigger() { - if (strcmp(_session.get_device()->dev_inst()->driver->name, "DSLogic") == 0) { + if (_session.get_device()->name() == "DSLogic") { bool stream = false; GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM); if (gvar != NULL) { @@ -368,7 +368,7 @@ void TriggerDock::device_change() g_variant_unref(gvar); } - if (!strncmp(_session.get_device()->dev_inst()->driver->name, "virtual", 7) || + if (_session.get_device()->name().contains("virtual") || stream) { simple_radioButton->setChecked(true); simple_trigger(); diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 7dd2e349..5dc78610 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -87,6 +87,8 @@ using boost::dynamic_pointer_cast; using std::list; using std::vector; +extern char AppDataPath[256]; + namespace pv { MainWindow::MainWindow(DeviceManager &device_manager, @@ -316,16 +318,17 @@ void MainWindow::update_device_list() errorMessage, infoMessage)); } - if (strncmp(selected_device->dev_inst()->driver->name, "virtual", 7)) { + if (!selected_device->name().contains("virtual")) { _logo_bar->dsl_connected(true); - QString ses_name = config_path + - QString::fromUtf8(selected_device->dev_inst()->driver->name) + + QString ses_name = DS_RES_PATH + + selected_device->name() + QString::number(selected_device->dev_inst()->mode) + ".dsc"; load_session(ses_name); } else { _logo_bar->dsl_connected(false); } + _view->status_clear(); } void MainWindow::reload() @@ -386,6 +389,8 @@ void MainWindow::device_detach() if (_session.get_capture_state() == SigSession::Running) _session.stop_capture(); + session_save(); + struct sr_dev_driver **const drivers = sr_driver_list(); struct sr_dev_driver **driver; for (driver = drivers; *driver; driver++) @@ -488,40 +493,25 @@ void MainWindow::capture_state_changed(int state) _sampling_bar->enable_toggle(state != SigSession::Running); _trig_bar->enable_toggle(state != SigSession::Running); _measure_dock->widget()->setEnabled(state != SigSession::Running); - if (_session.get_device()->dev_inst()->mode == LOGIC && - state == SigSession::Stopped) { - GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_RLE); - if (gvar != NULL) { - bool rle = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - if (rle) { - gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_ACTUAL_SAMPLES); - if (gvar != NULL) { - uint64_t actual_samples = g_variant_get_uint64(gvar); - g_variant_unref(gvar); - if (actual_samples != _session.cur_samplelimits()) { - show_session_error(tr("RLE Mode Warning"), - tr("Hardware buffer is full!\nActually received samples is less than setted sample depth!")); - } - } - } - } - } - } } -void MainWindow::closeEvent(QCloseEvent *event) +void MainWindow::session_save() { - QDir dir(QCoreApplication::applicationDirPath()); - if (dir.cd("res")) { - QString driver_name = _session.get_device()->dev_inst()->driver->name; + QDir dir(DS_RES_PATH); + if (dir.exists()) { + QString driver_name = _session.get_device()->name(); QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".dsc"; if (strncmp(driver_name.toLocal8Bit(), "virtual", 7) && !file_name.isEmpty()) store_session(file_name); } +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + session_save(); event->accept(); } diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 1b96a375..5159d077 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -86,6 +86,8 @@ private: bool eventFilter(QObject *object, QEvent *event); + void session_save(); + private slots: void load_file(QString file_name); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 53eca6cd..3abb5eac 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -232,7 +232,7 @@ void SigSession::save_file(const QString name, int type){ } sr_session_save(name.toLocal8Bit().data(), _dev_inst->dev_inst(), - data, unit_size, sample_count); + data, unit_size, sample_count, _trigger_time.toMSecsSinceEpoch(), _trigger_pos); } QList SigSession::getSuportedExportFormats(){ @@ -408,8 +408,7 @@ void SigSession::set_default_device(boost::function error_ // Try and find the DreamSourceLab device and select that by default BOOST_FOREACH (boost::shared_ptr dev, devices) if (dev->dev_inst() && - strncmp(dev->dev_inst()->driver->name, - "virtual", 7) != 0) { + !dev->name().contains("virtual")) { default_device = dev; break; } @@ -530,7 +529,7 @@ void SigSession::start_capture(bool instant, } // update setting - if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session")) + if (_dev_inst->name() != "virtual-session") _instant = instant; else _instant = true; @@ -674,10 +673,6 @@ void SigSession::check_update() } } -void SigSession::feed_in_header(const sr_dev_inst *sdi) -{ -} - void SigSession::add_group() { std::list probe_index_list; @@ -909,7 +904,7 @@ void SigSession::refresh(int holdtime) { boost::lock_guard lock(_data_mutex); - if (strncmp(_dev_inst->dev_inst()->driver->name, "virtual", 7)) { + if (!_dev_inst->name().contains("virtual")) { _data_lock = true; _refresh_timer.start(holdtime); } @@ -951,6 +946,26 @@ bool SigSession::get_data_lock() return _data_lock; } +void SigSession::feed_in_header(const sr_dev_inst *sdi) +{ + _trigger_pos = 0; + _trigger_time = QDateTime::currentDateTime(); + const int64_t secs = -cur_sampletime(); + _trigger_time = _trigger_time.addSecs(secs); + + if (_dev_inst->name() == "virtual-session") { + int64_t time; + GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_TRIGGER_TIME); + if (gvar != NULL) { + time = g_variant_get_int64(gvar); + g_variant_unref(gvar); + if (time != 0) + _trigger_time = QDateTime::fromMSecsSinceEpoch(time); + } + } + receive_header(); +} + void SigSession::feed_in_meta(const sr_dev_inst *sdi, const sr_datafeed_meta &meta) { @@ -973,7 +988,14 @@ void SigSession::feed_in_meta(const sr_dev_inst *sdi, void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) { if (_dev_inst->dev_inst()->mode != DSO) { - receive_trigger(trigger_pos.real_pos); + _trigger_pos = trigger_pos.real_pos; + receive_trigger(_trigger_pos); + if (_dev_inst->name() != "virtual-session") { + const double time = trigger_pos.real_pos * 1.0 / _cur_samplerate; + _trigger_time = QDateTime::currentDateTime(); + const int64_t secs = time - cur_sampletime(); + _trigger_time = _trigger_time.addSecs(secs); + } } else { int probe_count = 0; int probe_en_count = 0; @@ -986,7 +1008,8 @@ void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) probe_en_count++; } } - receive_trigger(trigger_pos.real_pos * probe_count / probe_en_count); + _trigger_pos = trigger_pos.real_pos * probe_count / probe_en_count; + receive_trigger(_trigger_pos); } } @@ -1218,9 +1241,6 @@ void SigSession::hotplug_proc(boost::function error_handle if (_hot_detach) { qDebug("DreamSourceLab hardware detached!"); device_detach(); - _logic_data.reset(); - _dso_data.reset(); - _analog_data.reset(); _hot_detach = false; } boost::this_thread::sleep(boost::posix_time::millisec(100)); @@ -1487,4 +1507,14 @@ vector< boost::shared_ptr > SigSession::get_math_signals() return _math_traces; } +QDateTime SigSession::get_trigger_time() const +{ + return _trigger_time; +} + +uint64_t SigSession::get_trigger_pos() const +{ + return _trigger_pos; +} + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 8ff3e0d9..5a9d8fa8 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -131,6 +131,8 @@ public: uint64_t cur_samplerate() const; uint64_t cur_samplelimits() const; double cur_sampletime() const; + QDateTime get_trigger_time() const; + uint64_t get_trigger_pos() const; void start_capture(bool instant, boost::function error_handler); @@ -274,6 +276,9 @@ private: bool _data_lock; bool _data_updated; + QDateTime _trigger_time; + uint64_t _trigger_pos; + signals: void capture_state_changed(int state); @@ -292,6 +297,8 @@ signals: void receive_trigger(quint64 trigger_pos); + void receive_header(); + void dso_ch_changed(uint16_t num); void frame_began(); diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index ecf93a5a..6007ad66 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -34,6 +34,8 @@ #include +extern char AppDataPath[256]; + namespace pv { namespace toolbars { @@ -109,11 +111,7 @@ FileBar::FileBar(SigSession &session, QWidget *parent) : connect(_action_capture, SIGNAL(triggered()), this, SLOT(on_actionCapture_triggered())); _file_button.setPopupMode(QToolButton::InstantPopup); -#ifdef LANGUAGE_ZH_CN - _file_button.setIcon(QIcon(":/icons/file_cn.png")); -#else _file_button.setIcon(QIcon(":/icons/file.png")); -#endif _menu = new QMenu(this); _menu->addMenu(_menu_session); @@ -226,8 +224,8 @@ void FileBar::on_actionLoad_triggered() void FileBar::on_actionDefault_triggered() { - QDir dir(QCoreApplication::applicationDirPath()); - if (!dir.cd("res")) { + QDir dir(DS_RES_PATH); + if (!dir.exists()) { QMessageBox msg(this); msg.setText(tr("Session Load")); msg.setInformativeText(tr("Cannot find default session file for this device!")); @@ -237,7 +235,7 @@ void FileBar::on_actionDefault_triggered() return; } - QString driver_name = _session.get_device()->dev_inst()->driver->name; + QString driver_name = _session.get_device()->name(); QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".def.dsc"; if (!file_name.isEmpty()) @@ -246,7 +244,7 @@ void FileBar::on_actionDefault_triggered() void FileBar::on_actionStore_triggered() { - QString default_name = _session.get_device()->dev_inst()->driver->name; + QString default_name = _session.get_device()->name(); QString file_name = QFileDialog::getSaveFileName( this, tr("Save Session"), default_name, tr("DSView Session (*.dsc)")); @@ -266,13 +264,8 @@ void FileBar::on_actionCapture_triggered() void FileBar::enable_toggle(bool enable) { _file_button.setDisabled(!enable); -#ifdef LANGUAGE_ZH_CN - _file_button.setIcon(enable ? QIcon(":/icons/file_cn.png") : - QIcon(":/icons/file_dis_cn.png")); -#else _file_button.setIcon(enable ? QIcon(":/icons/file.png") : QIcon(":/icons/file_dis.png")); -#endif } } // namespace toolbars diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index c3bfd339..15cf2c81 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -87,19 +87,11 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : _sample_rate(this), _updating_sample_rate(false), _updating_sample_count(false), - #ifdef LANGUAGE_ZH_CN - _icon_stop(":/icons/stop_cn.png"), - _icon_start(":/icons/start_cn.png"), - _icon_instant(":/icons/instant_cn.png"), - _icon_start_dis(":/icons/start_dis_cn.png"), - _icon_instant_dis(":/icons/instant_dis_cn.png"), - #else _icon_stop(":/icons/stop.png"), _icon_start(":/icons/start.png"), _icon_instant(":/icons/instant.png"), _icon_start_dis(":/icons/start_dis.png"), _icon_instant_dis(":/icons/instant_dis.png"), - #endif _run_stop_button(this), _instant_button(this), _instant(false) @@ -115,13 +107,9 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) : connect(&_instant_button, SIGNAL(clicked()), this, SLOT(on_instant_stop())); -#ifdef LANGUAGE_ZH_CN - _configure_button.setIcon(QIcon::fromTheme("configure", - QIcon(":/icons/params_cn.png"))); -#else _configure_button.setIcon(QIcon::fromTheme("configure", QIcon(":/icons/params.png"))); -#endif + _run_stop_button.setIcon(_icon_start); _instant_button.setIcon(_icon_instant); @@ -337,13 +325,8 @@ void SamplingBar::set_sampling(bool sampling) } _configure_button.setEnabled(!sampling); -#ifdef LANGUAGE_ZH_CN - _configure_button.setIcon(sampling ? QIcon(":/icons/params_dis_cn.png") : - QIcon(":/icons/params_cn.png")); -#else _configure_button.setIcon(sampling ? QIcon(":/icons/params_dis.png") : QIcon(":/icons/params.png")); -#endif } void SamplingBar::set_sample_rate(uint64_t sample_rate) @@ -492,7 +475,7 @@ void SamplingBar::on_samplecount_sel(int index) boost::shared_ptr _devInst = get_selected_device(); assert(_devInst); - if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) { + if (_devInst->name() == "DSLogic" && _devInst->dev_inst()->mode != DSO) { // Set the sample count _devInst->set_config(NULL, NULL, @@ -517,7 +500,7 @@ void SamplingBar::on_samplerate_sel(int index) // Get last samplerate //last_sample_rate = get_selected_device()->get_sample_rate(); - if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) { + if (_devInst->name() == "DSLogic" && _devInst->dev_inst()->mode != DSO) { // Set the samplerate get_selected_device()->set_config(NULL, NULL, SR_CONF_SAMPLERATE, diff --git a/DSView/pv/toolbars/trigbar.cpp b/DSView/pv/toolbars/trigbar.cpp index 509b28fc..5a938e29 100644 --- a/DSView/pv/toolbars/trigbar.cpp +++ b/DSView/pv/toolbars/trigbar.cpp @@ -52,24 +52,6 @@ TrigBar::TrigBar(SigSession &session, QWidget *parent) : connect(&_search_button, SIGNAL(clicked()), this, SLOT(search_clicked())); -#ifdef LANGUAGE_ZH_CN - _trig_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/trigger_cn.png"))); - _trig_button.setCheckable(true); - _protocol_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/protocol_cn.png"))); -#ifdef ENABLE_DECODE - _protocol_button.setCheckable(true); -#endif - _measure_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/measure_cn.png"))); - _measure_button.setCheckable(true); - _search_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/search-bar_cn.png"))); - _search_button.setCheckable(true); - _math_button.setIcon(QIcon::fromTheme("trig", - QIcon(":/icons/math_cn.png"))); -#else _trig_button.setIcon(QIcon::fromTheme("trig", QIcon(":/icons/trigger.png"))); _trig_button.setCheckable(true); @@ -86,7 +68,6 @@ TrigBar::TrigBar(SigSession &session, QWidget *parent) : _search_button.setCheckable(true); _math_button.setIcon(QIcon::fromTheme("trig", QIcon(":/icons/math.png"))); -#endif _action_fft = new QAction(this); _action_fft->setText(QApplication::translate( @@ -142,18 +123,6 @@ void TrigBar::enable_toggle(bool enable) _search_button.setDisabled(!enable); _math_button.setDisabled(!enable); -#ifdef LANGUAGE_ZH_CN - _trig_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/trigger_cn.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/trigger_dis_cn.png"))); - _protocol_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/protocol_cn.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/protocol_dis_cn.png"))); - _measure_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/measure_cn.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/measure_dis_cn.png"))); - _search_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/search-bar_cn.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/search-bar_dis_cn.png"))); - _math_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/math_cn.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/math_dis_cn.png"))); -#else _trig_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/trigger.png")) : QIcon::fromTheme("trig", QIcon(":/icons/trigger_dis.png"))); _protocol_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/protocol.png")) : @@ -164,20 +133,13 @@ void TrigBar::enable_toggle(bool enable) QIcon::fromTheme("trig", QIcon(":/icons/search-bar_dis.png"))); _math_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/math.png")) : QIcon::fromTheme("trig", QIcon(":/icons/math_dis.png"))); - -#endif } void TrigBar::enable_protocol(bool enable) { _protocol_button.setDisabled(!enable); -#ifdef LANGUAGE_ZH_CN - _protocol_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/protocol_cn.png")) : - QIcon::fromTheme("trig", QIcon(":/icons/protocol_dis_cn.png"))); -#else _protocol_button.setIcon(enable ? QIcon::fromTheme("trig", QIcon(":/icons/protocol.png")) : QIcon::fromTheme("trig", QIcon(":/icons/protocol_dis.png"))); -#endif } void TrigBar::close_all() diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index 24916a87..7f4b37ac 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -199,7 +199,7 @@ float DsoSignal::get_scale() void DsoSignal::set_enable(bool enable) { - if ((strcmp(_dev_inst->dev_inst()->driver->name, "DSLogic") == 0) && + if (_dev_inst->name() == "DSLogic" && get_index() == 0) return; _view->session().refresh(INT_MAX); @@ -524,7 +524,7 @@ bool DsoSignal::load_settings() qDebug() << "ERROR: config_get SR_CONF_TRIGGER_VALUE failed."; return false; } - bool isDSCope = (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0); + bool isDSCope = (_dev_inst->name() == "DSCope"); if (isDSCope) { _trig_vpos = min(max(trigger_value/255.0, 0+TrigMargin), 1-TrigMargin); } else { @@ -617,7 +617,7 @@ void DsoSignal::set_trig_vpos(int pos) int trig_value; if (enabled()) { double delta = min((double)max(pos - UpMargin, 0), get_view_rect().height()) * 1.0 / get_view_rect().height(); - bool isDSCope = (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0); + bool isDSCope = (_dev_inst->name() == "DSCope"); if (isDSCope) { trig_value = delta * 255.0 + 0.5; _trig_vpos = min(max(trig_value/255.0, 0+TrigMargin), 1-TrigMargin); @@ -637,7 +637,7 @@ void DsoSignal::set_trigRate(double rate) { int trig_value; double delta = rate; - bool isDSCope = (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0); + bool isDSCope = (_dev_inst->name() == "DSCope"); if (isDSCope) { trig_value = delta * 255.0 + 0.5; _trig_vpos = min(max(trig_value/255.0, 0+TrigMargin), 1-TrigMargin); @@ -781,7 +781,7 @@ QString DsoSignal::get_ms_string(int index) const void DsoSignal::update_zeroPos() { - if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0) { + if (_dev_inst->name() == "DSCope") { //double vpos_off = (0.5 - _zeroPos) * _vDial->get_value() * DS_CONF_DSO_VDIVS; double vpos_off = (0.5 - (get_zeroPos() - UpMargin) * 1.0/get_view_rect().height()) * _vDial->get_value() * DS_CONF_DSO_VDIVS; _dev_inst->set_config(_probe, NULL, SR_CONF_VPOS, @@ -888,7 +888,7 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right) return; const uint16_t number_channels = snapshot->get_channel_num(); - if ((strcmp(_dev_inst->dev_inst()->driver->name, "DSLogic") == 0) && + if (_dev_inst->name() == "DSLogic" && (unsigned int)get_index() >= number_channels) return; @@ -999,7 +999,7 @@ void DsoSignal::paint_trace(QPainter &p, float top = get_view_rect().top(); float bottom = get_view_rect().bottom(); float zeroP = _zeroPos * get_view_rect().height() + top;; - if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0 && + if (_dev_inst->name() == "DSCope" && _view->session().get_capture_state() == SigSession::Running) _zero_off = _zeroPos * 255; float x = (start / samples_per_pixel - pixels_offset) + left; @@ -1055,7 +1055,7 @@ void DsoSignal::paint_envelope(QPainter &p, float top = get_view_rect().top(); float bottom = get_view_rect().bottom(); float zeroP = _zeroPos * get_view_rect().height() + top; - if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0 && + if (_dev_inst->name() == "DSCope" && _view->session().get_capture_state() == SigSession::Running) _zero_off = _zeroPos * 255; for(uint64_t sample = 0; sample < e.length-1; sample++) { @@ -1172,7 +1172,7 @@ bool DsoSignal::mouse_press(int right, const QPoint pt) const QRectF x100_rect = get_rect(DSO_X100, y, right); if (chEn_rect.contains(pt)) { - if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session") && + if (_dev_inst->name() != "virtual-session" && !_view->session().get_data_lock()) set_enable(!enabled()); return true; @@ -1197,9 +1197,9 @@ bool DsoSignal::mouse_press(int right, const QPoint pt) setted = true; } } - } else if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session") && + } else if (_dev_inst->name() != "virtual-session" && acdc_rect.contains(pt)) { - if (strcmp(_view->session().get_device()->dev_inst()->driver->name, "DSLogic") == 0) + if (_dev_inst->name() == "DSLogic") set_acCoupling((get_acCoupling()+1)%2); else set_acCoupling((get_acCoupling()+1)%2); diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index a85eb321..f35d7a2e 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -73,7 +73,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget QScrollArea(parent), _session(session), _sampling_bar(sampling_bar), - _scale(1e-8), + _scale(1e-5), _preScale(1e-6), _maxscale(1e9), _minscale(1e-15), @@ -81,7 +81,6 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget _preOffset(0), _updating_scroll(false), _show_cursors(false), - _trig_pos(0), _hover_point(-1, -1) { setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); @@ -136,12 +135,13 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget _viewcenter = new QWidget(this); _viewcenter->setContentsMargins(0,0,0,0); QGridLayout* layout = new QGridLayout(_viewcenter); + layout->setSpacing(0); layout->setContentsMargins(0,0,0,0); _viewcenter->setLayout(layout); layout->addWidget(_vsplitter, 0, 0); - QWidget* bottom = new QWidget(this); - bottom->setFixedHeight(10); - layout->addWidget(bottom, 1, 0); + _viewbottom = new widgets::ViewStatus(this); + _viewbottom->setFixedHeight(StatusHeight); + layout->addWidget(_viewbottom, 1, 0); setViewport(_viewcenter); connect(_vsplitter, SIGNAL(splitterMoved(int,int)), this, SLOT(splitterMoved(int, int))); @@ -152,8 +152,14 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget this, SLOT(signals_changed()), Qt::DirectConnection); connect(&_session, SIGNAL(data_updated()), this, SLOT(data_updated())); + connect(&_session, SIGNAL(receive_header()), + this, SLOT(receive_header())); connect(&_session, SIGNAL(receive_trigger(quint64)), this, SLOT(set_trig_pos(quint64))); + connect(&_session, SIGNAL(frame_ended()), + this, SLOT(receive_end())); + connect(&_session, SIGNAL(frame_began()), + this, SLOT(frame_began())); connect(&_session, SIGNAL(show_region(uint64_t,uint64_t)), this, SLOT(show_region(uint64_t, uint64_t))); @@ -321,27 +327,6 @@ void View::set_preScale_preOffset() vector< boost::shared_ptr > View::get_traces(int type) { -// const vector< boost::shared_ptr > sigs(_session.get_signals()); -// const vector< boost::shared_ptr > groups(_session.get_group_signals()); -//#ifdef ENABLE_DECODE -// const vector< boost::shared_ptr > decode_sigs( -// _session.get_decode_signals()); -// vector< boost::shared_ptr > traces( -// sigs.size() + groups.size() + decode_sigs.size()); -//#else -// vector< boost::shared_ptr > traces(sigs.size() + groups.size()); -//#endif - -// vector< boost::shared_ptr >::iterator i = traces.begin(); -// i = copy(sigs.begin(), sigs.end(), i); -//#ifdef ENABLE_DECODE -// i = copy(decode_sigs.begin(), decode_sigs.end(), i); -//#endif -// i = copy(groups.begin(), groups.end(), i); - -// stable_sort(traces.begin(), traces.end(), compare_trace_v_offsets); -// return traces; - const vector< boost::shared_ptr > sigs(_session.get_signals()); const vector< boost::shared_ptr > groups(_session.get_group_signals()); #ifdef ENABLE_DECODE @@ -422,20 +407,52 @@ void View::show_search_cursor(bool show) viewport_update(); } +void View::status_clear() +{ + _viewbottom->clear(); +} + +void View::receive_header() +{ + status_clear(); +} + +void View::frame_began() +{ + if (_session.get_device()->dev_inst()->mode == LOGIC) + _viewbottom->set_trig_time(_session.get_trigger_time()); +} + +void View::receive_end() +{ + if (_session.get_device()->dev_inst()->mode == LOGIC) { + GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_RLE); + if (gvar != NULL) { + bool rle = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + if (rle) { + gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_ACTUAL_SAMPLES); + if (gvar != NULL) { + uint64_t actual_samples = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + if (actual_samples != _session.cur_samplelimits()) { + _viewbottom->set_rle_depth(actual_samples); + } + } + } + } + } +} + void View::set_trig_pos(quint64 trig_pos) { const double time = trig_pos * 1.0 / _session.cur_samplerate(); - _trig_pos = trig_pos; _trig_cursor->set_index(trig_pos); - if (ds_trigger_get_en()) { + if (ds_trigger_get_en() || _session.get_device()->name() == "virtual-session") { _show_trig_cursor = true; set_scale_offset(_scale, time - _scale * get_view_width() / 2); } - _trigger_time = QDateTime::currentDateTime(); - const int64_t secs = time - _session.get_device()->get_sample_time(); - _trigger_time = _trigger_time.addSecs(secs); - _ruler->update(); viewport_update(); } @@ -452,11 +469,6 @@ void View::set_search_pos(uint64_t search_pos) viewport_update(); } -uint64_t View::get_trig_pos() -{ - return _trig_pos; -} - uint64_t View::get_search_pos() { return _search_pos; @@ -555,7 +567,7 @@ void View::update_scale_offset() _preScale = _scale; _preOffset = _offset; - _trig_cursor->set_index(_trig_pos); + _trig_cursor->set_index(_session.get_trigger_pos()); _ruler->update(); viewport_update(); @@ -611,7 +623,6 @@ void View::signals_changed() } const double height = (_time_viewport->height() - - horizontalScrollBar()->height() - 2 * SignalMargin * time_traces.size()) * 1.0 / total_rows; if (_session.get_device()->dev_inst()->mode == LOGIC) { @@ -998,11 +1009,6 @@ void View::update_calibration() } } -QString View::trigger_time() -{ - return _trigger_time.toString("yyyy-MM-dd hh:mm:ss ddd"); -} - void View::show_region(uint64_t start, uint64_t end) { assert(start <= end); diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index 55f8ae91..af6f9337 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -43,6 +43,7 @@ #include "../view/viewport.h" #include "cursor.h" #include "signal.h" +#include "../widgets/viewstatus.h" namespace pv { @@ -83,6 +84,8 @@ public: static constexpr double MaxViewRate = 1.0; static const int MaxPixelsPerSample = 100; + static const int StatusHeight = 25; + public: explicit View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent = 0); @@ -158,7 +161,6 @@ public: //void set_trig_pos(uint64_t trig_pos); void set_search_pos(uint64_t search_pos); - uint64_t get_trig_pos(); uint64_t get_search_pos(); /* @@ -187,8 +189,6 @@ public: void set_sample_limit(uint64_t sample_limit, bool force = false); - QString trigger_time(); - QString get_measure(QString option); void viewport_update(); @@ -233,6 +233,7 @@ public slots: void show_region(uint64_t start, uint64_t end); // -- calibration void update_calibration(); + void status_clear(); private slots: @@ -245,8 +246,14 @@ private slots: void header_updated(); + void receive_header(); + void set_trig_pos(quint64 trig_pos); + void receive_end(); + + void frame_began(); + // calibration for oscilloscope void show_calibration(); void hide_calibration(); @@ -260,6 +267,7 @@ private: pv::toolbars::SamplingBar *_sampling_bar; QWidget *_viewcenter; + widgets::ViewStatus *_viewbottom; QSplitter *_vsplitter; Viewport * _time_viewport; Viewport * _fft_viewport; @@ -291,14 +299,12 @@ private: Cursor *_trig_cursor; bool _show_trig_cursor; - uint64_t _trig_pos; Cursor *_search_cursor; bool _show_search_cursor; uint64_t _search_pos; QPointF _hover_point; dialogs::Calibration *_cali; - QDateTime _trigger_time; }; } // namespace view diff --git a/DSView/pv/view/viewport.cpp b/DSView/pv/view/viewport.cpp index 199d35cb..38f0c117 100644 --- a/DSView/pv/view/viewport.cpp +++ b/DSView/pv/view/viewport.cpp @@ -172,8 +172,6 @@ void Viewport::paintEvent(QPaintEvent *event) if (_view.get_signalHeight() != _curSignalHeight) _curSignalHeight = _view.get_signalHeight(); - paintTrigTime(p); - p.end(); } @@ -379,7 +377,7 @@ void Viewport::mousePressEvent(QMouseEvent *event) _mouse_down_point = event->pos(); _mouse_down_offset = _view.offset(); _drag_strength = 0; - _time.start(); + _time.restart(); if (event->button() == Qt::LeftButton) { const vector< boost::shared_ptr > sigs(_view.session().get_signals()); @@ -456,13 +454,60 @@ void Viewport::mouseMoveEvent(QMouseEvent *event) uint64_t sample_rate = _view.session().cur_samplerate(); TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor(); if (_view.cursors_shown() && grabbed_marker) { - const double cur_time = _view.offset() + _view.hover_point().x() * _view.scale(); + double curX = _view.hover_point().x(); + uint64_t index0 = 0, index1 = 0, index2 = 0; + bool logic = false; + const vector< boost::shared_ptr > sigs(_view.session().get_signals()); + BOOST_FOREACH(const boost::shared_ptr s, sigs) { + assert(s); + boost::shared_ptr logicSig; + boost::shared_ptr dsoSig; + if ((_view.session().get_device()->dev_inst()->mode == LOGIC) && + (logicSig = dynamic_pointer_cast(s))) { + if (logicSig->measure(event->pos(), index0, index1, index2)) { + logic = true; + break; + } + } + if ((_view.session().get_device()->dev_inst()->mode == DSO) && + (dsoSig = dynamic_pointer_cast(s))) { + curX = min(dsoSig->get_view_rect().right(), curX); + break; + } + } + + const double cur_time = _view.offset() + curX * _view.scale(); const double pos = cur_time * sample_rate; const double pos_delta = pos - (uint64_t)pos; - if ( pos_delta < 0.5) + const double samples_per_pixel = sample_rate * _view.scale(); + const double index_offset = _view.offset() / _view.scale(); + const double curP = index0 / samples_per_pixel - index_offset; + const double curN = index1 / samples_per_pixel - index_offset; + if (logic && (curX - curP < SnapMinSpace || curN - curX < SnapMinSpace)) { + if (curX - curP < curN - curX) + grabbed_marker->set_index(index0); + else + grabbed_marker->set_index(index1); + } else if ( pos_delta < 0.5) { grabbed_marker->set_index((uint64_t)floor(pos)); - else + } else { grabbed_marker->set_index((uint64_t)ceil(pos)); + } + } + } + + if (_action_type == DSO_XM_STEP1 || _action_type == DSO_XM_STEP2) { + BOOST_FOREACH(const boost::shared_ptr s, _view.session().get_signals()) { + assert(s); + if (!s->get_view_rect().contains(event->pos())) { + _dso_xm_valid = false; + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + _action_type = NO_ACTION; + } + break; } } @@ -510,7 +555,6 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) if (_time.elapsed() < 200 && abs(_drag_strength) < MinorDragOffsetUp && abs(strength) > MinorDragRateUp) { - _drag_strength = _drag_strength; _drag_timer.start(DragTimerInterval); _action_type = LOGIC_MOVE; } else if (_time.elapsed() < 200 && @@ -609,10 +653,14 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) const double scale = _view.scale(); const double samples_per_pixel = sample_rate * scale; _dso_xm_index[2] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate; - const uint64_t max_index = max(_dso_xm_index[1], _dso_xm_index[2]); + uint64_t max_index = max(_dso_xm_index[1], _dso_xm_index[2]); _dso_xm_index[1] = min(_dso_xm_index[1], _dso_xm_index[2]); _dso_xm_index[2] = max_index; + max_index = max(_dso_xm_index[0], _dso_xm_index[1]); + _dso_xm_index[0] = min(_dso_xm_index[0], _dso_xm_index[1]); + _dso_xm_index[1] = max_index; + _action_type = NO_ACTION; } else if (event->button() == Qt::RightButton) { _action_type = NO_ACTION; @@ -639,9 +687,22 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event) _edge_rising = 0; _edge_falling = 0; } else if (_action_type == LOGIC_MOVE) { - _drag_strength = 0; - _drag_timer.stop(); - _action_type = NO_ACTION; + if (_mouse_down_point == event->pos()) { + _drag_strength = 0; + _drag_timer.stop(); + _action_type = NO_ACTION; + } else { + const double strength = _drag_strength*DragTimerInterval*1.0/_time.elapsed(); + if (_time.elapsed() < 200 && + abs(_drag_strength) < MinorDragOffsetUp && + abs(strength) > MinorDragRateUp) { + _drag_timer.start(DragTimerInterval); + } else if (_time.elapsed() < 200 && + abs(strength) > DragTimerInterval) { + _drag_strength = strength * 5; + _drag_timer.start(DragTimerInterval); + } + } } else if (_action_type == LOGIC_ZOOM) { if (event->pos().x() != _mouse_down_point.x()) { const double newOffset = _view.offset() + (min(event->pos().x(), _mouse_down_point.x()) + 0.5) * _view.scale(); @@ -686,13 +747,19 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event) _mm_duty = "#####"; measure_updated(); } else if (_action_type == NO_ACTION) { - uint64_t sample_rate = _view.session().cur_samplerate(); - double scale = _view.scale(); - const double samples_per_pixel = sample_rate * scale; - _dso_xm_index[0] = event->pos().x() * samples_per_pixel + - _view.offset() * sample_rate; - _dso_xm_y = event->pos().y(); - _action_type = DSO_XM_STEP0; + BOOST_FOREACH(const boost::shared_ptr s, _view.session().get_signals()) { + assert(s); + if (s->get_view_rect().contains(event->pos())) { + uint64_t sample_rate = _view.session().cur_samplerate(); + double scale = _view.scale(); + const double samples_per_pixel = sample_rate * scale; + _dso_xm_index[0] = event->pos().x() * samples_per_pixel + + _view.offset() * sample_rate; + _dso_xm_y = event->pos().y(); + _action_type = DSO_XM_STEP0; + } + break; + } } } } @@ -730,36 +797,25 @@ void Viewport::leaveEvent(QEvent *) _mouse_point = QPoint(-1, -1); //_view.show_cursors(false); - if (_action_type == CURS_MOVE) { - if (_view.cursors_shown()) { - list::iterator i = _view.get_cursorList().begin(); - while (i != _view.get_cursorList().end()) { - if ((*i)->grabbed()) { - _view.get_ruler()->rel_grabbed_cursor(); - } - i++; - } - } - } else if (_action_type == LOGIC_EDGE) { + if (_action_type == LOGIC_EDGE) { _edge_rising = 0; _edge_falling = 0; + _action_type = NO_ACTION; } else if (_action_type == LOGIC_MOVE) { _drag_strength = 0; _drag_timer.stop(); - } else if (_action_type == DSO_TRIG_MOVE) { - _drag_sig.reset(); + _action_type = NO_ACTION; } else if (_action_type == DSO_XM_STEP1 || _action_type == DSO_XM_STEP2) { _dso_xm_valid = false; - _mm_width = "#####"; - _mm_period = "#####"; - _mm_freq = "#####"; - _mm_duty = "#####"; + _mm_width = "#####"; + _mm_period = "#####"; + _mm_freq = "#####"; + _mm_duty = "#####"; + _action_type = NO_ACTION; } else if (_action_type == DSO_YM) { _dso_ym_valid = false; - } - - if (_action_type != NO_ACTION) _action_type = NO_ACTION; + } measure(); update(); @@ -1212,20 +1268,12 @@ void Viewport::on_drag_timer() _drag_strength /= DragDamping; if (_drag_strength != 0) _drag_timer.start(DragTimerInterval); - } else { + } else if (_action_type == NO_ACTION){ + _drag_strength = 0; _drag_timer.stop(); } } -void Viewport::paintTrigTime(QPainter &p) -{ - if (_view.session().get_device()->dev_inst()->mode == LOGIC) { - p.setPen(Trace::DARK_FORE); - p.drawText(this->rect(), Qt::AlignRight | Qt::AlignBottom, - "Last Trigger Time: "+_view.trigger_time()); - } -} - void Viewport::set_need_update(bool update) { _need_update = update; diff --git a/DSView/pv/view/viewport.h b/DSView/pv/view/viewport.h index cee1e9eb..9afef47b 100644 --- a/DSView/pv/view/viewport.h +++ b/DSView/pv/view/viewport.h @@ -58,6 +58,7 @@ public: static const int DsoMeasureStages = 3; static const double MinorDragRateUp; static const double DragDamping; + static const int SnapMinSpace = 10; enum ActionType { NO_ACTION, @@ -70,11 +71,8 @@ public: DSO_XM_STEP0, DSO_XM_STEP1, DSO_XM_STEP2, - DSO_XM_STEP3, DSO_YM, - DSO_TRIG_MOVE, - - DECODE_REGION + DSO_TRIG_MOVE }; enum MeasureType { @@ -116,7 +114,6 @@ private: void paintSignals(QPainter& p); void paintProgress(QPainter& p); void paintMeasure(QPainter &p); - void paintTrigTime(QPainter &p); void measure(); diff --git a/DSView/pv/widgets/viewstatus.cpp b/DSView/pv/widgets/viewstatus.cpp new file mode 100644 index 00000000..2b57a6c9 --- /dev/null +++ b/DSView/pv/widgets/viewstatus.cpp @@ -0,0 +1,66 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "viewstatus.h" + +#include +#include +#include + +#include "../view/trace.h" + +namespace pv { +namespace widgets { + +ViewStatus::ViewStatus(QWidget *parent) : QWidget(parent) +{ +} + +void ViewStatus::paintEvent(QPaintEvent *) +{ + QStyleOption opt; + opt.init(this); + QPainter p(this); + style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this); + + p.setPen(pv::view::Trace::DARK_FORE); + p.drawText(this->rect(), Qt::AlignLeft | Qt::AlignVCenter, _rle_depth); + p.drawText(this->rect(), Qt::AlignRight | Qt::AlignVCenter, _trig_time); +} + +void ViewStatus::clear() +{ + _trig_time.clear(); + _rle_depth.clear(); +} + +void ViewStatus::set_trig_time(QDateTime time) +{ + _trig_time = tr("Trigger Time: ") + time.toString("yyyy-MM-dd hh:mm:ss ddd"); +} + +void ViewStatus::set_rle_depth(uint64_t depth) +{ + _rle_depth = tr("RLE FULL: ") + QString::number(depth) + tr(" Samples Captured!"); +} + +} // namespace widgets +} // namespace pv diff --git a/DSView/pv/widgets/viewstatus.h b/DSView/pv/widgets/viewstatus.h new file mode 100644 index 00000000..58078d0d --- /dev/null +++ b/DSView/pv/widgets/viewstatus.h @@ -0,0 +1,58 @@ +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2016 DreamSourceLab + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DSVIEW_PV_WIDGETS_VIEWSTATUS_H +#define DSVIEW_PV_WIDGETS_VIEWSTATUS_H + +#include +#include +#include "QDateTime" + +namespace pv { + +class SigSession; + +namespace widgets { + +class ViewStatus : public QWidget +{ + Q_OBJECT +public: + explicit ViewStatus(QWidget *parent = 0); + + void paintEvent(QPaintEvent *); + +signals: + +public slots: + void clear(); + void set_trig_time(QDateTime time); + void set_rle_depth(uint64_t depth); + +private: + QString _trig_time; + QString _rle_depth; +}; + +} // namespace widgets +} // namespace pv + +#endif // DSVIEW_PV_WIDGETS_VIEWSTATUS_H diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 30c0549d..83928db4 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -850,10 +850,10 @@ static GSList *scan(GSList *options) sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { - char *firmware = malloc(strlen(config_path)+strlen(prof->firmware)+1); + char *firmware = malloc(strlen(DS_RES_PATH)+strlen(prof->firmware)+1); if (firmware == NULL) return NULL; - strcpy(firmware, config_path); + strcpy(firmware, DS_RES_PATH); strcat(firmware, prof->firmware); if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, firmware) == SR_OK) @@ -1452,12 +1452,12 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); //char filename[256]; - //sprintf(filename,"%s%s",config_path,devc->profile->fpga_bit33); + //sprintf(filename,"%s%s",DS_RES_PATH,devc->profile->fpga_bit33); //const char *fpga_bit = filename; - char *fpga_bit = malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1); + char *fpga_bit = malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1); if (fpga_bit == NULL) return SR_ERR_MALLOC; - strcpy(fpga_bit, config_path); + strcpy(fpga_bit, DS_RES_PATH); strcat(fpga_bit, devc->profile->fpga_bit33); ret = fpga_config(usb->devhdl, fpga_bit); if (ret != SR_OK) { @@ -2102,10 +2102,10 @@ static int dev_open(struct sr_dev_inst *sdi) } else { /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); - char *fpga_bit = malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1); + char *fpga_bit = malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1); if (fpga_bit == NULL) return SR_ERR_MALLOC; - strcpy(fpga_bit, config_path); + strcpy(fpga_bit, DS_RES_PATH); strcat(fpga_bit, devc->profile->fpga_bit33); ret = fpga_config(usb->devhdl, fpga_bit); if (ret != SR_OK) { @@ -2172,10 +2172,6 @@ static void abort_acquisition(struct DSL_context *devc) else sr_info("Stop DSCope acquisition!"); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen((struct sr_dev_inst *)devc->cb_data, NULL, SR_CONF_ZERO_OVER)); - if (ret != SR_OK) - sr_err("DSO zero over command failed!"); - /* Cancel exist transfers */ if (devc->num_transfers) for (i = devc->num_transfers - 1; i >= 0; i--) { @@ -2432,10 +2428,6 @@ static void receive_transfer(struct libusb_transfer *transfer) mstatus.vlen = instant_buffer_size; } - if (devc->zero) { - dso_zero(sdi, mstatus); - } - const uint32_t divider = devc->zero ? 0x1 : (uint32_t)ceil(DSCOPE_MAX_SAMPLERATE * 1.0 / devc->cur_samplerate / channel_en_cnt); if ((mstatus.sample_divider == divider && mstatus.vlen != 0 && @@ -2675,6 +2667,10 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) tv.tv_sec = tv.tv_usec = 0; libusb_handle_events_timeout_completed(drvc->sr_ctx->libusb_ctx, &tv, &completed); + if (devc->zero) { + dso_zero(sdi, mstatus); + } + return TRUE; } diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index e99f92ce..842ed953 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -700,7 +700,7 @@ static struct DSL_context *DSLogic_dev_new(void) devc->stream = FALSE; devc->mstatus_valid = FALSE; devc->data_lock = FALSE; - devc->max_height = 1; + devc->max_height = 0; return devc; } @@ -855,11 +855,11 @@ static GSList *scan(GSList *options) libusb_get_device_address(devlist[i]), NULL); } else { char *firmware; - if (!(firmware = g_try_malloc(strlen(config_path)+strlen(prof->firmware)+1))) { + if (!(firmware = g_try_malloc(strlen(DS_RES_PATH)+strlen(prof->firmware)+1))) { sr_err("Firmware path malloc error!"); return NULL; } - strcpy(firmware, config_path); + strcpy(firmware, DS_RES_PATH); strcat(firmware, prof->firmware); if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, firmware) == SR_OK) @@ -1326,25 +1326,6 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting mode to %d", __func__, sdi->mode); if (sdi->mode == DSO) { GList *l; - for(l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - zero_info.zero_addr = (zero_base_addr + probe->index * sizeof(struct cmd_zero_info)); - if ((ret = command_rd_nvm(usb->devhdl, (unsigned char *)&zero_info, zero_info.zero_addr, sizeof(struct cmd_zero_info))) != SR_OK) { - sr_err("Send Get Zero command failed!"); - } else { - if (zero_info.zero_addr == (zero_base_addr + probe->index * sizeof(struct cmd_zero_info))) { - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_ZERO_SET)); - if (ret != SR_OK) { - sr_err("Set Zero command failed!"); - return ret; - } - } else { - devc->zero = TRUE; - sr_info("Zero have not been setted!"); - } - } - } - for(l = sdi->channels; l; l = l->next) { struct sr_channel *probe = (struct sr_channel *)l->data; ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, probe, SR_CONF_COUPLING)); @@ -1488,11 +1469,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); char *fpga_bit; - if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) { + if (!(fpga_bit = g_try_malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1))) { sr_err("fpag_bit path malloc error!"); return SR_ERR_MALLOC; } - strcpy(fpga_bit, config_path); + strcpy(fpga_bit, DS_RES_PATH); switch(devc->th_level) { case SR_TH_3V3: strcat(fpga_bit, devc->profile->fpga_bit33);; @@ -1846,11 +1827,11 @@ static int dev_open(struct sr_dev_inst *sdi) /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); char *fpga_bit; - if (!(fpga_bit = g_try_malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1))) { + if (!(fpga_bit = g_try_malloc(strlen(DS_RES_PATH)+strlen(devc->profile->fpga_bit33)+1))) { sr_err("fpag_bit path malloc error!"); return SR_ERR_MALLOC; } - strcpy(fpga_bit, config_path); + strcpy(fpga_bit, DS_RES_PATH); switch(devc->th_level) { case SR_TH_3V3: strcat(fpga_bit, devc->profile->fpga_bit33);; @@ -1955,10 +1936,6 @@ static void abort_acquisition(struct DSL_context *devc) else sr_info("Stop DSLogic acquisition!"); - ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen((struct sr_dev_inst *)devc->cb_data, NULL, SR_CONF_ZERO_OVER)); - if (ret != SR_OK) - sr_err("DSO zero over command failed!"); - /* Cancel exist transfers */ if (devc->num_transfers) for (i = devc->num_transfers - 1; i >= 0; i--) { @@ -2439,9 +2416,12 @@ static void receive_trigger_pos(struct libusb_transfer *transfer) struct sr_datafeed_dso dso; struct sr_datafeed_analog analog; struct ds_trigger_pos *trigger_pos; + const struct sr_dev_inst *sdi; int ret; devc = transfer->user_data; + sdi = devc->cb_data; + sr_info("receive_trigger_pos(): status %d; timeout %d; received %d bytes.", transfer->status, transfer->timeout, transfer->actual_length); @@ -2454,13 +2434,13 @@ static void receive_trigger_pos(struct libusb_transfer *transfer) switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: if (transfer->actual_length == sizeof(struct ds_trigger_pos)) { - if (devc->stream || trigger_pos->remain_cnt < devc->limit_samples) { - if (!devc->stream) + if (sdi->mode != LOGIC || devc->stream || trigger_pos->remain_cnt < devc->limit_samples) { + if (sdi->mode == LOGIC && !devc->stream) devc->actual_samples = (devc->limit_samples - ceil(devc->cur_samplerate * 1.0 / DSLOGIC_MAX_LOGIC_SAMPLERATE) * (trigger_pos->remain_cnt)); packet.type = SR_DF_TRIGGER; packet.payload = trigger_pos; - sr_session_send(devc->cb_data, &packet); + sr_session_send(sdi, &packet); devc->status = DSL_TRIGGERED; free_transfer(transfer); @@ -2500,7 +2480,7 @@ static void receive_trigger_pos(struct libusb_transfer *transfer) } if (devc->status == DSL_TRIGGERED) { - if ((ret = dev_transfer_start(devc->cb_data)) != SR_OK) { + if ((ret = dev_transfer_start(sdi)) != SR_OK) { sr_err("%s: could not start data transfer" "(%d)%d", __func__, ret, errno); } diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index e26036c6..60e62a8c 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -119,6 +119,8 @@ struct dev_context { uint16_t trigger_mask; uint16_t trigger_value; uint16_t trigger_edge; + uint8_t trigger_slope; + uint8_t trigger_source; }; static const int hwcaps[] = { @@ -342,7 +344,7 @@ static GSList *hw_scan(GSList *options) devc->sample_generator = PATTERN_SINE; devc->timebase = 200; devc->data_lock = FALSE; - devc->max_height = 1; + devc->max_height = 0; sdi->priv = devc; @@ -690,7 +692,17 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting AC COUPLING of channel %d to %d", __func__, ch->index, ch->coupling); ret = SR_OK; - } else if (id == SR_CONF_TRIGGER_VALUE) { + } else if (id == SR_CONF_TRIGGER_SOURCE) { + devc->trigger_source = g_variant_get_byte(data); + sr_dbg("%s: setting Trigger Source to %d", + __func__, devc->trigger_source); + ret = SR_OK; + } else if (id == SR_CONF_TRIGGER_SLOPE) { + devc->trigger_slope = g_variant_get_byte(data); + sr_dbg("%s: setting Trigger Slope to %d", + __func__, devc->trigger_slope); + ret = SR_OK; + } else if (id == SR_CONF_TRIGGER_VALUE) { ch->trig_value = g_variant_get_byte(data); sr_dbg("%s: setting channel %d Trigger Value to %d", __func__, ch->index, ch->trig_value); @@ -798,7 +810,7 @@ static void samples_generator(uint16_t *buf, uint64_t size, } else if (sdi->mode != DSO) { start_rand = rand()%len; for (i = 0; i < size; i++) { - index = (i/g_slist_length(sdi->channels)+start_rand)%len; + index = (i/10/g_slist_length(sdi->channels)+start_rand)%len; *(buf + i) = (uint16_t)(((const_dc+pre_buf[index]) << 8) + (const_dc+pre_buf[index])); } } else { diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 319a35f5..72a022d9 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -111,6 +111,8 @@ enum { #define DS_CONF_DSO_HDIVS 10 #define DS_CONF_DSO_VDIVS 10 +#define DS_RES_PATH "/usr/local/share/DSView/res/" + /** libsigrok loglevels. */ enum { SR_LOG_NONE = 0, /**< Output no messages at all. */ @@ -863,6 +865,16 @@ enum { */ SR_CONF_LIMIT_SAMPLES, + /** + * Absolute time record for session driver + */ + SR_CONF_TRIGGER_TIME, + + /** + * Trigger position for session driver + */ + SR_CONF_TRIGGER_POS, + /** * The actual sample count received */ @@ -974,8 +986,6 @@ enum { SR_GND_COUPLING = 2, }; -extern char config_path[256]; - struct sr_dev_mode { char *name; int mode; diff --git a/libsigrok4DSL/proto.h b/libsigrok4DSL/proto.h index 854f445e..223f1ec0 100644 --- a/libsigrok4DSL/proto.h +++ b/libsigrok4DSL/proto.h @@ -111,7 +111,7 @@ SR_API int sr_session_start(void); SR_API int sr_session_run(void); SR_API int sr_session_stop(void); SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, - unsigned char *buf, int unitsize, int units); + unsigned char *buf, int unitsize, uint64_t samples, int64_t trig_time, uint64_t trig_pos); SR_API int sr_session_save_init(const char *filename, uint64_t samplerate, char **channels); SR_API int sr_session_append(const char *filename, unsigned char *buf, diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index fa1d0c0f..d61435ff 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -52,6 +52,8 @@ struct session_vdev { int bytes_read; uint64_t samplerate; uint64_t total_samples; + int64_t trig_time; + uint64_t trig_pos; int unitsize; int num_probes; uint64_t timebase; @@ -171,6 +173,8 @@ static int dev_open(struct sr_dev_inst *sdi) sr_err("%s: vdev->buf malloc failed", __func__); return SR_ERR_MALLOC; } + vdev->trig_pos = 0; + vdev->trig_time = 0; dev_insts = g_slist_append(dev_insts, sdi); @@ -211,6 +215,13 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, } else return SR_ERR; break; + case SR_CONF_TRIGGER_TIME: + if (sdi) { + vdev = sdi->priv; + *data = g_variant_new_int64(vdev->trig_time); + } else + return SR_ERR; + break; case SR_CONF_TIMEBASE: if (sdi) { vdev = sdi->priv; @@ -258,6 +269,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, return SR_ERR; *data = g_variant_new_uint64(vdev->total_samples); break; + case SR_CONF_RLE_SAMPLELIMITS: + *data = g_variant_new_uint64(UINT64_MAX); + break; default: return SR_ERR_ARG; } @@ -299,7 +313,15 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, samplecounts[0] = vdev->total_samples; sr_info("Setting limit samples to %" PRIu64 ".", vdev->total_samples); break; - case SR_CONF_CAPTURE_NUM_PROBES: + case SR_CONF_TRIGGER_TIME: + vdev->trig_time = g_variant_get_int64(data); + sr_info("Setting trigger time to %" PRId64 ".", vdev->trig_time); + break; + case SR_CONF_TRIGGER_POS: + vdev->trig_pos = g_variant_get_uint64(data); + sr_info("Setting trigger position to %" PRIu64 ".", vdev->trig_pos); + break; + case SR_CONF_CAPTURE_NUM_PROBES: vdev->num_probes = g_variant_get_uint64(data); break; case SR_CONF_EN_CH: @@ -407,6 +429,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, { struct zip_stat zs; struct session_vdev *vdev; + struct sr_datafeed_packet packet; int ret; vdev = sdi->priv; @@ -435,6 +458,15 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, /* Send header packet to the session bus. */ std_session_send_df_header(sdi, LOG_PREFIX); + /* Send trigger packet to the session bus */ + if (vdev->trig_pos != 0) { + struct ds_trigger_pos session_trigger; + session_trigger.real_pos = vdev->trig_pos; + packet.type = SR_DF_TRIGGER; + packet.payload = &session_trigger; + sr_session_send(sdi, &packet); + } + /* freewheeling source */ sr_session_source_add(-1, 0, 0, receive_data, sdi); diff --git a/libsigrok4DSL/session_file.c b/libsigrok4DSL/session_file.c index aa77128d..bf5b27c5 100644 --- a/libsigrok4DSL/session_file.c +++ b/libsigrok4DSL/session_file.c @@ -125,6 +125,7 @@ SR_API int sr_session_load(const char *filename) uint16_t probenum; uint64_t tmp_u64, total_probes, enabled_probes; uint16_t p; + int64_t tmp_64; char **sections, **keys, *metafile, *val, s[11]; char probename[SR_MAX_PROBENAME_LEN + 1]; int mode = LOGIC; @@ -205,10 +206,18 @@ SR_API int sr_session_load(const char *filename) tmp_u64 = strtoull(val, NULL, 10); sdi->driver->config_set(SR_CONF_LIMIT_SAMPLES, g_variant_new_uint64(tmp_u64), sdi, NULL, NULL); - } else if (!strcmp(keys[j], "hDiv")) { + } else if (!strcmp(keys[j], "hDiv")) { tmp_u64 = strtoull(val, NULL, 10); sdi->driver->config_set(SR_CONF_TIMEBASE, g_variant_new_uint64(tmp_u64), sdi, NULL, NULL); + } else if (!strcmp(keys[j], "trigger time")) { + tmp_64 = strtoll(val, NULL, 10); + sdi->driver->config_set(SR_CONF_TRIGGER_TIME, + g_variant_new_int64(tmp_64), sdi, NULL, NULL); + } else if (!strcmp(keys[j], "trigger pos")) { + tmp_u64 = strtoull(val, NULL, 10); + sdi->driver->config_set(SR_CONF_TRIGGER_POS, + g_variant_new_uint64(tmp_u64), sdi, NULL, NULL); } else if (!strcmp(keys[j], "total probes")) { total_probes = strtoull(val, NULL, 10); sdi->driver->config_set(SR_CONF_CAPTURE_NUM_PROBES, @@ -331,7 +340,7 @@ SR_API int sr_session_load(const char *filename) * upon other errors. */ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, - unsigned char *buf, int unitsize, int units) + unsigned char *buf, int unitsize, uint64_t samples, int64_t trig_time, uint64_t trig_pos) { GSList *l; GVariant *gvar; @@ -373,7 +382,7 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, /* metadata */ fprintf(meta, "capturefile = data\n"); fprintf(meta, "unitsize = %d\n", unitsize); - fprintf(meta, "total samples = %d\n", units); + fprintf(meta, "total samples = %llu\n", samples); fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels)); if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, &gvar) == SR_OK) { @@ -386,9 +395,13 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, if (sdi->mode == DSO && sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_TIMEBASE, &gvar) == SR_OK) { timeBase = g_variant_get_uint64(gvar); - fprintf(meta, "hDiv = %d\n", timeBase); + fprintf(meta, "hDiv = %llu\n", timeBase); g_variant_unref(gvar); + } else if (sdi->mode == LOGIC) { + fprintf(meta, "trigger time = %lld\n", trig_time); } + fprintf(meta, "trigger pos = %llu\n", trig_pos); + probecnt = 1; for (l = sdi->channels; l; l = l->next) { probe = l->data; @@ -405,13 +418,13 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, fprintf(meta, " vPos%d = %lf\n", probe->index, probe->vpos); if (sr_status_get(sdi, &status, 0, 0) == SR_OK) { if (probe->index == 0) { - fprintf(meta, " period%d = %d\n", probe->index, status.ch0_period); - fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch0_pcnt); + fprintf(meta, " period%d = %llu\n", probe->index, status.ch0_period); + fprintf(meta, " pcnt%d = %lu\n", probe->index, status.ch0_pcnt); fprintf(meta, " max%d = %d\n", probe->index, status.ch0_max); fprintf(meta, " min%d = %d\n", probe->index, status.ch0_min); } else { - fprintf(meta, " period%d = %d\n", probe->index, status.ch1_period); - fprintf(meta, " pcnt%d = %d\n", probe->index, status.ch1_pcnt); + fprintf(meta, " period%d = %llu\n", probe->index, status.ch1_period); + fprintf(meta, " pcnt%d = %lu\n", probe->index, status.ch1_pcnt); fprintf(meta, " max%d = %d\n", probe->index, status.ch1_max); fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min); } @@ -422,7 +435,7 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, } if (!(logicsrc = zip_source_buffer(zipfile, buf, - units * unitsize, FALSE))) + samples * unitsize, FALSE))) return SR_ERR; snprintf(rawname, 15, "data"); if (zip_add(zipfile, rawname, logicsrc) == -1) @@ -544,7 +557,7 @@ SR_API int sr_session_save_init(const char *filename, uint64_t samplerate, * @param filename The name of the filename to append to. Must not be NULL. * @param buf The data to be appended. * @param unitsize The number of bytes per sample. - * @param units The number of samples. + * @param samples The number of samples. * * @retval SR_OK Success * @retval SR_ERR_ARG Invalid arguments