From 5626a9ba81d68c083d96a7578ac18ab4e19157d3 Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Sat, 6 Jun 2015 22:24:00 +0800 Subject: [PATCH] add session load/store funtion --- DSView/CMakeLists.txt | 4 + DSView/pv/dock/dsotriggerdock.cpp | 6 +- DSView/pv/dock/triggerdock.cpp | 75 +++++++++- DSView/pv/dock/triggerdock.h | 6 +- DSView/pv/mainwindow.cpp | 196 ++++++++++++++++++++++++++- DSView/pv/mainwindow.h | 3 + DSView/pv/sigsession.cpp | 22 ++- DSView/pv/sigsession.h | 1 + DSView/pv/toolbars/filebar.cpp | 47 ++++++- DSView/pv/toolbars/filebar.h | 6 + DSView/pv/view/analogsignal.cpp | 2 +- DSView/pv/view/decodetrace.cpp | 2 +- DSView/pv/view/dsosignal.cpp | 165 ++++++++++++++++++---- DSView/pv/view/dsosignal.h | 10 +- DSView/pv/view/groupsignal.cpp | 2 +- DSView/pv/view/header.cpp | 12 +- DSView/pv/view/logicsignal.cpp | 2 +- DSView/pv/view/trace.cpp | 36 ++--- DSView/pv/view/trace.h | 3 - libsigrok4DSL/hardware/DSL/dscope.c | 32 +++-- libsigrok4DSL/hardware/DSL/dsl.h | 1 + libsigrok4DSL/hardware/DSL/dslogic.c | 59 ++++++-- libsigrok4DSL/hardware/demo/demo.c | 11 ++ libsigrok4DSL/hwdriver.c | 12 +- libsigrok4DSL/libsigrok.h | 8 +- libsigrok4DSL/proto.h | 1 + libsigrok4DSL/trigger.c | 10 ++ 27 files changed, 636 insertions(+), 98 deletions(-) diff --git a/DSView/CMakeLists.txt b/DSView/CMakeLists.txt index 2f5eb787..95096455 100644 --- a/DSView/CMakeLists.txt +++ b/DSView/CMakeLists.txt @@ -357,6 +357,10 @@ install(FILES res/DSLogicPro.fw DESTINATION bin/res/) install(FILES res/DSLogicPro.bin DESTINATION bin/res/) install(FILES res/DSCope.fw DESTINATION bin/res/) install(FILES res/DSCope.bin DESTINATION bin/res/) +install(FILES res/DSLogic_ini.dsc DESTINATION bin/res/) +install(FILES res/DSLogic_ini.dsc.bak DESTINATION bin/res/) +install(FILES res/DSCope_ini.dsc DESTINATION bin/res/) +install(FILES res/DSCope_ini.dsc.bak DESTINATION bin/res/) #=============================================================================== #= Packaging (handled by CPack) diff --git a/DSView/pv/dock/dsotriggerdock.cpp b/DSView/pv/dock/dsotriggerdock.cpp index 357b9d02..965540f5 100644 --- a/DSView/pv/dock/dsotriggerdock.cpp +++ b/DSView/pv/dock/dsotriggerdock.cpp @@ -138,7 +138,7 @@ void DsoTriggerDock::pos_changed(int pos) int ret; ret = _session.get_device()->set_config(NULL, NULL, SR_CONF_HORIZ_TRIGGERPOS, - g_variant_new_uint16((uint16_t)pos)); + g_variant_new_byte((uint8_t)pos)); if (!ret) { QMessageBox msg(this); msg.setText(tr("Trigger Setting Issue")); @@ -206,7 +206,7 @@ void DsoTriggerDock::init() GVariant* gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_HORIZ_TRIGGERPOS); if (gvar != NULL) { - uint16_t pos = g_variant_get_uint16(gvar); + uint16_t pos = g_variant_get_byte(gvar); g_variant_unref(gvar); position_slider->setValue(pos); } @@ -222,7 +222,7 @@ void DsoTriggerDock::init() gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_TRIGGER_SLOPE); if (gvar != NULL) { - uint8_t slope = g_variant_get_uint16(gvar); + uint8_t slope = g_variant_get_byte(gvar); g_variant_unref(gvar); type_group->button(slope)->setChecked(true); } diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp index 07f6eddf..1bc4dee1 100644 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -300,7 +300,7 @@ void TriggerDock::adv_trigger() if (stream) { QMessageBox msg(this); msg.setText(tr("Trigger")); - msg.setInformativeText(tr("Stram Mode Don't Support Advanced Trigger!")); + msg.setInformativeText(tr("Stream Mode Don't Support Advanced Trigger!")); msg.setStandardButtons(QMessageBox::Ok); msg.setIcon(QMessageBox::Warning); msg.exec(); @@ -522,5 +522,78 @@ void TriggerDock::init() //position_slider->setValue(pos); } +QJsonObject TriggerDock::get_session() +{ + QJsonObject trigSes; + trigSes["triggerMode"] = adv_radioButton->isChecked() ? 1 : 0; + trigSes["triggerPos"] = position_slider->value(); + trigSes["triggerStages"] = stages_comboBox->currentIndex(); + trigSes["triggerSerial"] = _adv_tabWidget->currentIndex(); + + for (int i = 0; i < stages_comboBox->count(); i++) { + QString value0_str = "triggerValue0" + QString::number(i); + QString inv0_str = "triggerInv0" + QString::number(i); + QString count0_str = "triggerCount0" + QString::number(i); + QString value1_str = "triggerValue1" + QString::number(i); + QString inv1_str = "triggerInv1" + QString::number(i); + QString count1_str = "triggerCount1" + QString::number(i); + QString logic_str = "triggerLogic" + QString::number(i); + trigSes[value0_str] = _value0_lineEdit_list.at(i)->text(); + trigSes[value1_str] = _value1_lineEdit_list.at(i)->text(); + trigSes[inv0_str] = _inv0_comboBox_list.at(i)->currentIndex(); + trigSes[inv1_str] = _inv1_comboBox_list.at(i)->currentIndex(); + trigSes[count0_str] = _count0_spinBox_list.at(i)->value(); + trigSes[count1_str] = _count1_spinBox_list.at(i)->value(); + trigSes[logic_str] = _logic_comboBox_list.at(i)->currentIndex(); + } + + trigSes["triggerStart"] = _serial_start_lineEdit->text(); + trigSes["triggerStop"] = _serial_stop_lineEdit->text(); + trigSes["triggerClock"] = _serial_edge_lineEdit->text(); + trigSes["triggerChannel"] = _serial_data_comboBox->currentIndex(); + trigSes["triggerData"] = _serial_value_lineEdit->text(); + + return trigSes; +} + +void TriggerDock::set_session(QJsonObject ses) +{ + position_slider->setValue(ses["triggerPos"].toDouble()); + stages_comboBox->setCurrentIndex(ses["triggerStages"].toDouble()); + _adv_tabWidget->setCurrentIndex(ses["triggerSerial"].toDouble()); + if (ses["triggerMode"].toDouble() == 0) + simple_radioButton->click(); + else + adv_radioButton->click(); + + for (int i = 0; i < stages_comboBox->count(); i++) { + QString value0_str = "triggerValue0" + QString::number(i); + QString inv0_str = "triggerInv0" + QString::number(i); + QString count0_str = "triggerCount0" + QString::number(i); + QString value1_str = "triggerValue1" + QString::number(i); + QString inv1_str = "triggerInv1" + QString::number(i); + QString count1_str = "triggerCount1" + QString::number(i); + QString logic_str = "triggerLogic" + QString::number(i); + _value0_lineEdit_list.at(i)->setText(ses[value0_str].toString()); + _value1_lineEdit_list.at(i)->setText(ses[value1_str].toString()); + _inv0_comboBox_list.at(i)->setCurrentIndex(ses[inv0_str].toDouble()); + _inv1_comboBox_list.at(i)->setCurrentIndex(ses[inv1_str].toDouble()); + _count0_spinBox_list.at(i)->setValue(ses[count0_str].toDouble()); + _count1_spinBox_list.at(i)->setValue(ses[count1_str].toDouble()); + _logic_comboBox_list.at(i)->setCurrentIndex(ses[logic_str].toDouble()); + } + + _serial_start_lineEdit->setText(ses["triggerStart"].toString()); + _serial_stop_lineEdit->setText(ses["triggerStop"].toString()); + _serial_edge_lineEdit->setText(ses["triggerClock"].toString()); + _serial_data_comboBox->setCurrentIndex(ses["triggerChannel"].toDouble()); + _serial_value_lineEdit->setText(ses["triggerData"].toString()); + + value_changed(); + logic_changed(0); + inv_changed(0); + count_changed(); +} + } // namespace dock } // namespace pv diff --git a/DSView/pv/dock/triggerdock.h b/DSView/pv/dock/triggerdock.h index 5cdfa3b7..a3c717d5 100644 --- a/DSView/pv/dock/triggerdock.h +++ b/DSView/pv/dock/triggerdock.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -63,9 +64,12 @@ public: void init(); + QJsonObject get_session(); + void set_session(QJsonObject ses); + signals: -private slots: +public slots: void simple_trigger(); void adv_trigger(); void trigger_stages_changed(int index); diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 4a3ba30e..fce40b2a 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -146,6 +146,10 @@ void MainWindow::setup_ui() SLOT(on_save())); connect(_file_bar, SIGNAL(on_screenShot()), this, SLOT(on_screenShot())); + connect(_file_bar, SIGNAL(load_session(QString)), this, + SLOT(load_session(QString))); + connect(_file_bar, SIGNAL(store_session(QString)), this, + SLOT(store_session(QString))); #ifdef ENABLE_DECODE // protocol dock @@ -311,10 +315,13 @@ void MainWindow::update_device_list() errorMessage, infoMessage)); } - if (strcmp(selected_device->dev_inst()->driver->name, "demo") != 0) + if (strcmp(selected_device->dev_inst()->driver->name, "demo") != 0) { _logo_bar->dsl_connected(true); - else + QString ses_name = config_path + QString::fromLocal8Bit(selected_device->dev_inst()->driver->name) + "_ini.dsc"; + load_session(ses_name); + } else { _logo_bar->dsl_connected(false); + } } void MainWindow::reload() @@ -537,7 +544,7 @@ void MainWindow::on_save() // Show the dialog const QString file_name = QFileDialog::getSaveFileName( - this, tr("Save File"), "", tr("DSView Sessions (*.dsl)")); + this, tr("Save File"), "", tr("DSView Data (*.dsl)")); if (file_name.isEmpty()) return; @@ -546,6 +553,189 @@ void MainWindow::on_save() dlg->run(); } +bool MainWindow::load_session(QString name) +{ + QFile sessionFile(name.toStdString().c_str()); + if (!sessionFile.open(QIODevice::ReadOnly)) { + QMessageBox msg(this); + msg.setText(tr("File Error")); + msg.setInformativeText(tr("Couldn't open session file!")); + msg.setStandardButtons(QMessageBox::Ok); + msg.setIcon(QMessageBox::Warning); + msg.exec(); + return false; + } + + QByteArray sessionData = sessionFile.readAll(); + QJsonDocument sessionDoc = QJsonDocument::fromJson(sessionData); + QJsonObject sessionObj = sessionDoc.object(); + + // check device and mode + const sr_dev_inst *const sdi = _session.get_device()->dev_inst(); + if (strcmp(sdi->driver->name, sessionObj["Device"].toString().toLocal8Bit()) != 0 || + sdi->mode != sessionObj["DeviceMode"].toDouble()) { + QMessageBox msg(this); + msg.setText(tr("Session Error")); + msg.setInformativeText(tr("Session File is not compatible with current device or mode!")); + msg.setStandardButtons(QMessageBox::Ok); + msg.setIcon(QMessageBox::Warning); + msg.exec(); + return false; + } + + // load device settings + GVariant *gvar_opts; + gsize num_opts; + if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_DEVICE_SESSIONS, &gvar_opts) == SR_OK)) { + const int *const options = (const int32_t *)g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(int32_t)); + for (unsigned int i = 0; i < num_opts; i++) { + const struct sr_config_info *const info = + sr_config_info_get(options[i]); + if (info->datatype == SR_T_BOOL) + _session.get_device()->set_config(NULL, NULL, info->key, g_variant_new_boolean(sessionObj[info->name].toDouble())); + else if (info->datatype == SR_T_UINT64) + _session.get_device()->set_config(NULL, NULL, info->key, g_variant_new_uint64(sessionObj[info->name].toString().toULongLong())); + else if (info->datatype == SR_T_UINT8) + _session.get_device()->set_config(NULL, NULL, info->key, g_variant_new_byte(sessionObj[info->name].toString().toUInt())); + else if (info->datatype == SR_T_FLOAT) + _session.get_device()->set_config(NULL, NULL, info->key, g_variant_new_double(sessionObj[info->name].toDouble())); + else if (info->datatype == SR_T_CHAR) + _session.get_device()->set_config(NULL, NULL, info->key, g_variant_new_string(sessionObj[info->name].toString().toLocal8Bit())); + } + } + _sampling_bar->update_record_length(); + _sampling_bar->update_sample_rate(); + + // load channel settings + for (const GSList *l = _session.get_device()->dev_inst()->channels; l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + bool isEnabled = false; + foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { + QJsonObject obj = value.toObject(); + qDebug("obj.index = %d", obj["index"].toDouble()); + if ((probe->index == obj["index"].toDouble()) && + (probe->type == obj["type"].toDouble())) { + isEnabled = true; + probe->enabled = obj["enabled"].toBool(); + //probe->colour = obj["colour"].toString(); + probe->name = g_strdup(obj["name"].toString().toStdString().c_str()); + probe->vdiv = obj["vdiv"].toDouble(); + probe->coupling = obj["coupling"].toDouble(); + probe->vfactor = obj["vfactor"].toDouble(); + probe->trig_value = obj["trigValue"].toDouble(); + //probe->zeroPos = obj["zeroPos"].toDouble(); + break; + } + } + if (!isEnabled) + probe->enabled = false; + } + _session.init_signals(); + + // load signal setting + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + foreach (const QJsonValue &value, sessionObj["channel"].toArray()) { + QJsonObject obj = value.toObject(); + if ((s->get_index() == obj["index"].toDouble()) && + (s->get_type() == obj["type"].toDouble())) { + s->set_colour(QColor(obj["colour"].toString())); + s->set_trig(obj["strigger"].toDouble()); + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(s)) { + dsoSig->update_hDial(); + //dsoSig->update_vDial(); + dsoSig->set_zeroRate(obj["zeroPos"].toDouble()); + dsoSig->set_enable(obj["enabled"].toBool()); + dsoSig->set_trigRate(obj["trigValue"].toDouble()); + } + break; + } + } + } + + // load trigger settings + if (sessionObj.contains("trigger")) { + _trigger_widget->set_session(sessionObj["trigger"].toObject()); + } + on_trigger(false); +} + +bool MainWindow::store_session(QString name) +{ + QFile sessionFile(name.toStdString().c_str()); + if (!sessionFile.open(QIODevice::WriteOnly)) { + QMessageBox msg(this); + msg.setText(tr("File Error")); + msg.setInformativeText(tr("Couldn't open session file to write!")); + msg.setStandardButtons(QMessageBox::Ok); + msg.setIcon(QMessageBox::Warning); + msg.exec(); + return false; + } + + GVariant *gvar_opts; + GVariant *gvar; + gsize num_opts; + const sr_dev_inst *const sdi = _session.get_device()->dev_inst(); + QJsonObject sessionVar; + QJsonObject triggerVar; + QJsonArray channelVar; + sessionVar["Device"] = QJsonValue::fromVariant(sdi->driver->name); + sessionVar["DeviceMode"] = QJsonValue::fromVariant(sdi->mode); + + if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_DEVICE_SESSIONS, &gvar_opts) != SR_OK)) + return false; /* Driver supports no device instance sessions. */ + const int *const options = (const int32_t *)g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(int32_t)); + for (unsigned int i = 0; i < num_opts; i++) { + const struct sr_config_info *const info = + sr_config_info_get(options[i]); + gvar = _session.get_device()->get_config(NULL, NULL, info->key); + if (gvar != NULL) { + if (info->datatype == SR_T_BOOL) + sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_boolean(gvar)); + else if (info->datatype == SR_T_UINT64) + sessionVar[info->name] = QJsonValue::fromVariant(QString::number(g_variant_get_uint64(gvar))); + else if (info->datatype == SR_T_UINT8) + sessionVar[info->name] = QJsonValue::fromVariant(QString::number(g_variant_get_byte(gvar))); + else if (info->datatype == SR_T_FLOAT) + sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_double(gvar)); + else if (info->datatype == SR_T_CHAR) + sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_string(gvar, NULL)); + g_variant_unref(gvar); + } + } + + BOOST_FOREACH(const boost::shared_ptr s, _session.get_signals()) { + QJsonObject s_obj; + s_obj["index"] = s->get_index(); + s_obj["type"] = s->get_type(); + s_obj["enabled"] = s->enabled(); + s_obj["name"] = s->get_name(); + s_obj["colour"] = QJsonValue::fromVariant(s->get_colour()); + s_obj["strigger"] = s->get_trig(); + boost::shared_ptr dsoSig; + if (dsoSig = dynamic_pointer_cast(s)) { + s_obj["vdiv"] = QJsonValue::fromVariant(dsoSig->get_vDialValue()); + s_obj["vfactor"] = QJsonValue::fromVariant(dsoSig->get_factor()); + s_obj["coupling"] = dsoSig->get_acCoupling(); + s_obj["trigValue"] = dsoSig->get_trigRate(); + s_obj["zeroPos"] = dsoSig->get_zeroRate(); + } + channelVar.append(s_obj); + } + sessionVar["channel"] = channelVar; + + if (_session.get_device()->dev_inst()->mode == LOGIC) { + sessionVar["trigger"] = _trigger_widget->get_session(); + } + + QJsonDocument sessionDoc(sessionVar); + sessionFile.write(sessionDoc.toJson()); + return true; +} bool MainWindow::eventFilter(QObject *object, QEvent *event) { diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 34566805..f4c113bf 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -117,6 +117,9 @@ private slots: void on_save(); + bool load_session(QString name); + bool store_session(QString name); + /* * hotplug slot function */ diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 2a4f5006..bf36cf78 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -56,6 +56,8 @@ #include #include #include +#include +#include #include #include @@ -152,7 +154,6 @@ void SigSession::set_device(boost::shared_ptr dev_inst) throw(Q } } - void SigSession::set_file(const string &name) throw(QString) { // Deslect the old device, because file type detection in File::create @@ -600,7 +601,7 @@ void SigSession::add_group() std::vector< boost::shared_ptr >::iterator i = _signals.begin(); while (i != _signals.end()) { - if ((*i)->get_type() == view::Trace::DS_LOGIC && (*i)->selected()) + if ((*i)->get_type() == SR_CHANNEL_LOGIC && (*i)->selected()) probe_index_list.push_back((*i)->get_index()); i++; } @@ -851,7 +852,22 @@ void SigSession::feed_in_meta(const sr_dev_inst *sdi, void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos) { - receive_trigger(trigger_pos.real_pos); + if (_dev_inst->dev_inst()->mode != DSO) { + receive_trigger(trigger_pos.real_pos); + } else { + int probe_count = 0; + int probe_en_count = 0; + for (const GSList *l = _dev_inst->dev_inst()->channels; + l; l = l->next) { + const sr_channel *const probe = (const sr_channel *)l->data; + if (probe->type == SR_CHANNEL_DSO) { + probe_count++; + if (probe->enabled) + probe_en_count++; + } + } + receive_trigger(trigger_pos.real_pos * probe_count / probe_en_count); + } } void SigSession::feed_in_logic(const sr_datafeed_logic &logic) diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index fd406950..97703b73 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -45,6 +45,7 @@ #include #include #include +#include #include #include diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index 12816b12..48a35fec 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -46,6 +46,24 @@ FileBar::FileBar(SigSession &session, QWidget *parent) : { setMovable(false); + _action_load = new QAction(this); + _action_load->setText(QApplication::translate( + "File", "&Load Session...", 0)); + _action_load->setIcon(QIcon::fromTheme("file", + QIcon(":/icons/open.png"))); + _action_load->setObjectName(QString::fromUtf8("actionLoad")); + _file_button.addAction(_action_load); + connect(_action_load, SIGNAL(triggered()), this, SLOT(on_actionLoad_triggered())); + + _action_store = new QAction(this); + _action_store->setText(QApplication::translate( + "File", "S&tore Session...", 0)); + _action_store->setIcon(QIcon::fromTheme("file", + QIcon(":/icons/open.png"))); + _action_store->setObjectName(QString::fromUtf8("actionStore")); + _file_button.addAction(_action_store); + connect(_action_store, SIGNAL(triggered()), this, SLOT(on_actionStore_triggered())); + _action_open = new QAction(this); _action_open->setText(QApplication::translate( "File", "&Open...", 0)); @@ -96,7 +114,7 @@ void FileBar::on_actionOpen_triggered() // Show the dialog const QString file_name = QFileDialog::getOpenFileName( this, tr("Open File"), "", tr( - "DSView Sessions (*.dsl);;All Files (*.*)")); + "DSView Data (*.dsl);;All Files (*.*)")); if (!file_name.isEmpty()) load_file(file_name); } @@ -175,7 +193,7 @@ void FileBar::on_actionSave_triggered() }else { QString file_name = QFileDialog::getSaveFileName( this, tr("Save File"), "", - tr("DSView Session (*.dsl)")); + tr("DSView Data (*.dsl)")); if (!file_name.isEmpty()) { QFileInfo f(file_name); if(f.suffix().compare("dsl")) @@ -185,6 +203,31 @@ void FileBar::on_actionSave_triggered() } } + +void FileBar::on_actionLoad_triggered() +{ + // Show the dialog + const QString file_name = QFileDialog::getOpenFileName( + this, tr("Open Session"), "", tr( + "DSView Session (*.dsc)")); + if (!file_name.isEmpty()) + load_session(file_name); +} + +void FileBar::on_actionStore_triggered() +{ + QString default_name = _session.get_device()->dev_inst()->driver->name; + QString file_name = QFileDialog::getSaveFileName( + this, tr("Save Session"), default_name, + tr("DSView Session (*.dsc)")); + if (!file_name.isEmpty()) { + QFileInfo f(file_name); + if(f.suffix().compare("dsc")) + file_name.append(tr(".dsc")); + store_session(file_name); + } +} + void FileBar::on_actionCapture_triggered() { on_screenShot(); diff --git a/DSView/pv/toolbars/filebar.h b/DSView/pv/toolbars/filebar.h index a10a405c..93f82b33 100644 --- a/DSView/pv/toolbars/filebar.h +++ b/DSView/pv/toolbars/filebar.h @@ -53,8 +53,12 @@ signals: void load_file(QString); void save(); void on_screenShot(); + void load_session(QString); + void store_session(QString); private slots: + void on_actionLoad_triggered(); + void on_actionStore_triggered(); void on_actionOpen_triggered(); void on_actionSave_triggered(); void on_actionCapture_triggered(); @@ -66,6 +70,8 @@ private: QToolButton _file_button; + QAction *_action_load; + QAction *_action_store; QAction *_action_open; QAction *_action_save; QAction *_action_export; diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index 6bf8ad33..ceeca037 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -54,7 +54,7 @@ const float AnalogSignal::EnvelopeThreshold = 256.0f; AnalogSignal::AnalogSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, const sr_channel * const probe) : - Signal(dev_inst, probe, DS_ANALOG), + Signal(dev_inst, probe, SR_CHANNEL_ANALOG), _data(data) { _colour = SignalColours[probe->index % countof(SignalColours)]; diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index ecac15c1..e4c8e2c5 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -117,7 +117,7 @@ const QColor DecodeTrace::OutlineColours[16] = { DecodeTrace::DecodeTrace(pv::SigSession &session, boost::shared_ptr decoder_stack, int index) : Trace(QString::fromUtf8( - decoder_stack->stack().front()->decoder()->name), index, Trace::DS_DECODER), + decoder_stack->stack().front()->decoder()->name), index, SR_CHANNEL_DECODER), _session(session), _decoder_stack(decoder_stack), _show_hide_mapper(this), diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index c099af80..b8d7b244 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -112,7 +112,7 @@ const int DsoSignal::RightMargin = 30; DsoSignal::DsoSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, const sr_channel * const probe): - Signal(dev_inst, probe, DS_DSO), + Signal(dev_inst, probe, SR_CHANNEL_DSO), _data(data), _scale(0), _vDialActive(false), @@ -148,31 +148,34 @@ DsoSignal::DsoSignal(boost::shared_ptr dev_inst, _colour = SignalColours[probe->index % countof(SignalColours)]; - GVariant* gvar; +// GVariant* gvar; - gvar = dev_inst->get_config(probe, NULL, SR_CONF_VDIV); - if (gvar != NULL) { - _vDial->set_value(g_variant_get_uint64(gvar)); - g_variant_unref(gvar); - } else { - qDebug() << "ERROR: config_get SR_CONF_VDIV failed."; - } +// gvar = dev_inst->get_config(probe, NULL, SR_CONF_VDIV); +// if (gvar != NULL) { +// _vDial->set_value(g_variant_get_uint64(gvar)); +// g_variant_unref(gvar); +// } else { +// qDebug() << "ERROR: config_get SR_CONF_VDIV failed."; +// } - gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TIMEBASE); - if (gvar != NULL) { - _hDial->set_value(g_variant_get_uint64(gvar)); - g_variant_unref(gvar); - } else { - qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; - } +// gvar = dev_inst->get_config(NULL, NULL, SR_CONF_TIMEBASE); +// if (gvar != NULL) { +// _hDial->set_value(g_variant_get_uint64(gvar)); +// g_variant_unref(gvar); +// } else { +// qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; +// } - gvar = dev_inst->get_config(probe, NULL, SR_CONF_COUPLING); - if (gvar != NULL) { - _acCoupling = g_variant_get_byte(gvar); - g_variant_unref(gvar); - } else { - qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; - } +// gvar = dev_inst->get_config(probe, NULL, SR_CONF_COUPLING); +// if (gvar != NULL) { +// _acCoupling = g_variant_get_byte(gvar); +// g_variant_unref(gvar); +// } else { +// qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; +// } + update_vDial(); + update_hDial(); + update_acCoupling(); } DsoSignal::~DsoSignal() @@ -420,6 +423,54 @@ bool DsoSignal::go_hDialNext(bool setted) } } +bool DsoSignal::update_vDial() +{ + uint64_t vdiv; + //uint64_t pre_vdiv = _vDial->get_value(); + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VDIV); + if (gvar != NULL) { + vdiv = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; + return false; + } + + _vDial->set_value(vdiv); + _dev_inst->set_config(_probe, NULL, SR_CONF_VDIV, + g_variant_new_uint64(_vDial->get_value())); + if (_view) { + update_zeroPos(); + _view->set_need_update(true); + _view->update(); + } + return true; +} + +bool DsoSignal::update_hDial() +{ + uint64_t hdiv; + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_TIMEBASE); + if (gvar != NULL) { + hdiv = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_TIMEBASE failed."; + return false; + } + + _hDial->set_value(hdiv); + _dev_inst->set_config(_probe, NULL, SR_CONF_TIMEBASE, + g_variant_new_uint64(_hDial->get_value())); + if (_view) { + const double scale = _hDial->get_value() * std::pow(10.0, -9.0) * DS_CONF_DSO_HDIVS / get_view_rect().width(); + _view->set_scale_offset(scale, _view->offset()); + _view->set_need_update(true); + _view->update(); + } + return true; +} + uint64_t DsoSignal::get_vDialValue() const { return _vDial->get_value(); @@ -454,11 +505,32 @@ void DsoSignal::set_acCoupling(uint8_t coupling) } } +bool DsoSignal::update_acCoupling() +{ + GVariant* gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_COUPLING); + if (gvar != NULL) { + _acCoupling = g_variant_get_byte(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; + return false; + } + + _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, + g_variant_new_byte(_acCoupling)); + return true; +} + int DsoSignal::get_trig_vpos() const { return _trig_vpos * get_view_rect().height() + UpMargin; } +double DsoSignal::get_trigRate() const +{ + return _trig_vpos; +} + void DsoSignal::set_trig_vpos(int pos) { assert(_view); @@ -477,15 +549,39 @@ void DsoSignal::set_trig_vpos(int pos) trig_value = (delta * 255.0f + 0x80); } _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, - g_variant_new_uint16(trig_value)); + g_variant_new_byte(trig_value)); } } +void DsoSignal::set_trigRate(double rate) +{ + int trig_value; + double delta = rate; + bool isDSCope = (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0); + if (isDSCope) { + _trig_vpos = min(max(delta, 0+TrigMargin), 1-TrigMargin); + trig_value = delta * 255; + } else { + delta = delta - _zeroPos; + delta = min(delta, 0.5); + delta = max(delta, -0.5); + _trig_vpos = min(max(_zeroPos + delta, 0+TrigMargin), 1-TrigMargin); + trig_value = (delta * 255.0f + 0x80); + } + _dev_inst->set_config(_probe, NULL, SR_CONF_TRIGGER_VALUE, + g_variant_new_byte(trig_value)); +} + int DsoSignal::get_zeroPos() { return _zeroPos * get_view_rect().height() + UpMargin; } +double DsoSignal::get_zeroRate() +{ + return _zeroPos; +} + void DsoSignal::set_zeroPos(int pos) { if (enabled()) { @@ -498,6 +594,12 @@ void DsoSignal::set_zeroPos(int pos) } } +void DsoSignal::set_zeroRate(double rate) +{ + _zeroPos = rate; + update_zeroPos(); +} + void DsoSignal::set_factor(uint64_t factor) { if (enabled()) { @@ -521,6 +623,21 @@ void DsoSignal::set_factor(uint64_t factor) } } +uint64_t DsoSignal::get_factor() +{ + GVariant* gvar; + uint64_t factor; + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_FACTOR); + if (gvar != NULL) { + factor = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + return factor; + } else { + qDebug() << "ERROR: config_get SR_CONF_FACTOR failed."; + return 1; + } +} + void DsoSignal::update_zeroPos() { if (strcmp(_dev_inst->dev_inst()->driver->name, "DSCope") == 0) { diff --git a/DSView/pv/view/dsosignal.h b/DSView/pv/view/dsosignal.h index af474c91..734ef757 100644 --- a/DSView/pv/view/dsosignal.h +++ b/DSView/pv/view/dsosignal.h @@ -95,7 +95,14 @@ public: void set_acCoupling(uint8_t coupling); void set_trig_vpos(int pos); int get_trig_vpos() const; + void set_trigRate(double rate); + double get_trigRate() const; void set_factor(uint64_t factor); + uint64_t get_factor(); + + bool update_vDial(); + bool update_hDial(); + bool update_acCoupling(); /** * @@ -112,11 +119,12 @@ public: * Gets the mid-Y position of this signal. */ int get_zeroPos(); - + double get_zeroRate(); /** * Sets the mid-Y position of this signal. */ void set_zeroPos(int pos); + void set_zeroRate(double rate); void update_zeroPos(); /** diff --git a/DSView/pv/view/groupsignal.cpp b/DSView/pv/view/groupsignal.cpp index 1d339875..1c6ac1d8 100644 --- a/DSView/pv/view/groupsignal.cpp +++ b/DSView/pv/view/groupsignal.cpp @@ -47,7 +47,7 @@ const float GroupSignal::EnvelopeThreshold = 256.0f; GroupSignal::GroupSignal(QString name, boost::shared_ptr data, std::list probe_index_list, int group_index) : - Trace(name, probe_index_list, DS_GROUP, group_index), + Trace(name, probe_index_list, SR_CHANNEL_GROUP, group_index), _data(data) { _colour = SignalColours[probe_index_list.front() % countof(SignalColours)]; diff --git a/DSView/pv/view/header.cpp b/DSView/pv/view/header.cpp index 5bcc9ae0..3930d012 100644 --- a/DSView/pv/view/header.cpp +++ b/DSView/pv/view/header.cpp @@ -200,7 +200,7 @@ void Header::mousePressEvent(QMouseEvent *event) if (mTrace->selected()) mTrace->select(false); else { - if (mTrace->get_type() != Trace::DS_DSO) + if (mTrace->get_type() != SR_CHANNEL_DSO) mTrace->select(true); if (~QApplication::keyboardModifiers() & @@ -410,7 +410,7 @@ void Header::mouseMoveEvent(QMouseEvent *event) const boost::shared_ptr sig((*i).first); if (sig) { int y = (*i).second + delta; - if (sig->get_type() != Trace::DS_DSO) { + if (sig->get_type() != SR_CHANNEL_DSO) { const int y_snap = ((y + View::SignalSnapGridSize / 2) / View::SignalSnapGridSize) * @@ -452,9 +452,9 @@ void Header::contextMenuEvent(QContextMenuEvent *event) return; QMenu menu(this); - if (t->get_type() == Trace::DS_LOGIC) + if (t->get_type() == SR_CHANNEL_LOGIC) menu.addAction(_action_add_group); - else if (t->get_type() == Trace::DS_GROUP) + else if (t->get_type() == SR_CHANNEL_GROUP) menu.addAction(_action_del_group); _context_trace = t; @@ -470,8 +470,8 @@ void Header::on_action_set_name_triggered() if (nameEdit->isModified()) { context_Trace->set_name(nameEdit->text()); - if (context_Trace->get_type() == Trace::DS_LOGIC || - context_Trace->get_type() == Trace::DS_ANALOG) + if (context_Trace->get_type() == SR_CHANNEL_LOGIC || + context_Trace->get_type() == SR_CHANNEL_ANALOG) sr_dev_probe_name_set(_view.session().get_device()->dev_inst(), context_Trace->get_index(), nameEdit->text().toUtf8().constData()); } diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index bd95cc0a..6faede11 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -69,7 +69,7 @@ const int LogicSignal::StateRound = 5; LogicSignal::LogicSignal(boost::shared_ptr dev_inst, boost::shared_ptr data, const sr_channel * const probe) : - Signal(dev_inst, probe, DS_LOGIC), + Signal(dev_inst, probe, SR_CHANNEL_LOGIC), _data(data) { assert(probe->index >= 0); diff --git a/DSView/pv/view/trace.cpp b/DSView/pv/view/trace.cpp index e234a723..9794bae1 100644 --- a/DSView/pv/view/trace.cpp +++ b/DSView/pv/view/trace.cpp @@ -54,6 +54,7 @@ const QPen Trace::AxisPen(QColor(128, 128, 128, 64)); const int Trace::LabelHitPadding = 2; Trace::Trace(QString name, int index, int type) : + _view(NULL), _name(name), _v_offset(INT_MAX), _type(type), @@ -65,6 +66,7 @@ Trace::Trace(QString name, int index, int type) : } Trace::Trace(QString name, std::list index_list, int type, int sec_index) : + _view(NULL), _name(name), _v_offset(INT_MAX), _type(type), @@ -262,7 +264,7 @@ void Trace::paint_label(QPainter &p, int right, bool hover, int action) }; p.setPen(Qt::transparent); - if (_type == DS_DSO) + if (_type == SR_CHANNEL_DSO) p.setBrush(((hover && action == LABEL) || selected()) ? _colour.darker() : _colour); else p.setBrush(((hover && action == LABEL) || selected()) ? dsYellow : dsBlue); @@ -275,11 +277,11 @@ void Trace::paint_label(QPainter &p, int right, bool hover, int action) // Paint the text p.setPen(Qt::white); - if (_type == DS_GROUP) + if (_type == SR_CHANNEL_GROUP) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "G"); - else if (_type == DS_ANALOG) + else if (_type == SR_CHANNEL_ANALOG) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "A"); - else if (_type == DS_DECODER) + else if (_type == SR_CHANNEL_DECODER) p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, "D"); else p.drawText(label_rect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(_index_list.front())); @@ -317,33 +319,33 @@ int Trace::pt_in_rect(int y, int right, const QPoint &point) return COLOR; else if (name.contains(point) && enabled()) return NAME; - else if (posTrig.contains(point) && _type == DS_LOGIC) + else if (posTrig.contains(point) && _type == SR_CHANNEL_LOGIC) return POSTRIG; - else if (higTrig.contains(point) && _type == DS_LOGIC) + else if (higTrig.contains(point) && _type == SR_CHANNEL_LOGIC) return HIGTRIG; - else if (negTrig.contains(point) && _type == DS_LOGIC) + else if (negTrig.contains(point) && _type == SR_CHANNEL_LOGIC) return NEGTRIG; - else if (lowTrig.contains(point) && _type == DS_LOGIC) + else if (lowTrig.contains(point) && _type == SR_CHANNEL_LOGIC) return LOWTRIG; - else if (edgeTrig.contains(point) && _type == DS_LOGIC) + else if (edgeTrig.contains(point) && _type == SR_CHANNEL_LOGIC) return EDGETRIG; else if (label.contains(point) && enabled()) return LABEL; - else if (vDial.contains(point) && _type == DS_DSO && enabled()) + else if (vDial.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return VDIAL; - else if (x1.contains(point) && _type == DS_DSO && enabled()) + else if (x1.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return X1; - else if (x10.contains(point) && _type == DS_DSO && enabled()) + else if (x10.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return X10; - else if (x100.contains(point) && _type == DS_DSO && enabled()) + else if (x100.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return X100; - else if (hDial.contains(point) && _type == DS_DSO && enabled()) + else if (hDial.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return HDIAL; - else if (chEn.contains(point) && _type == DS_DSO) + else if (chEn.contains(point) && _type == SR_CHANNEL_DSO) return CHEN; - else if (acdc.contains(point) && _type == DS_DSO && enabled()) + else if (acdc.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return ACDC; - else if (dsoTrig.contains(point) && _type == DS_DSO && enabled()) + else if (dsoTrig.contains(point) && _type == SR_CHANNEL_DSO && enabled()) return DSOTRIG; else return 0; diff --git a/DSView/pv/view/trace.h b/DSView/pv/view/trace.h index 031f94a7..8cc73307 100644 --- a/DSView/pv/view/trace.h +++ b/DSView/pv/view/trace.h @@ -92,9 +92,6 @@ protected: */ Trace(const Trace &t); -public: - enum {DS_LOGIC = 0, DS_ANALOG, DS_DSO, DS_GROUP, DS_DECODER}; - public: /** * Gets the name of this signal. diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index c3a22d3a..3c16d18c 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -80,6 +80,16 @@ static const int32_t hwoptions[] = { SR_CONF_OPERATION_MODE, }; +static const int32_t sessions[] = { + SR_CONF_SAMPLERATE, + SR_CONF_LIMIT_SAMPLES, + SR_CONF_OPERATION_MODE, + SR_CONF_TIMEBASE, + SR_CONF_TRIGGER_SLOPE, + SR_CONF_TRIGGER_SOURCE, + SR_CONF_HORIZ_TRIGGERPOS, +}; + static const char *probe_names[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", @@ -575,6 +585,7 @@ static struct DSL_context *DSCope_dev_new(void) devc->trigger_slope = DSO_TRIGGER_RISING; devc->trigger_source = DSO_TRIGGER_AUTO; devc->trigger_hpos = 0x0; + devc->trigger_hrate = 0; devc->zero = FALSE; return devc; @@ -1215,20 +1226,13 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_TRIGGER_VALUE: if (!ch) return SR_ERR; - *data = g_variant_new_uint16(ch->trig_value); + *data = g_variant_new_byte(ch->trig_value); break; case SR_CONF_HORIZ_TRIGGERPOS: if (!sdi) return SR_ERR; devc = sdi->priv; - uint16_t channel_cnt = 0; - GSList *l; - for (l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - channel_cnt += probe->enabled; - } - uint16_t pos = devc->trigger_hpos * channel_cnt * 100 / devc->limit_samples; - *data = g_variant_new_uint16(pos); + *data = g_variant_new_byte(devc->trigger_hrate); break; case SR_CONF_ZERO: if (!sdi) @@ -1409,6 +1413,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (sdi->mode == DSO) { ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_EN_CH)); + ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); } if (ret == SR_OK) sr_dbg("%s: setting ENABLE of channel %d to %d", @@ -1476,7 +1481,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting DSO Trigger Source to %d failed", __func__, devc->trigger_source); } else if (id == SR_CONF_TRIGGER_VALUE) { - ch->trig_value = g_variant_get_uint16(data); + ch->trig_value = g_variant_get_byte(data); if (sdi->mode == DSO) { ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_TRIGGER_VALUE)); } @@ -1493,7 +1498,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct sr_channel *probe = (struct sr_channel *)l->data; channel_cnt += probe->enabled; } - devc->trigger_hpos = g_variant_get_uint16(data) * channel_cnt * devc->limit_samples / 200.0; + devc->trigger_hrate = g_variant_get_byte(data); + devc->trigger_hpos = devc->trigger_hrate * channel_cnt * devc->limit_samples / 200.0; if (sdi->mode == DSO) { ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 1, SR_CONF_HORIZ_TRIGGERPOS)); } @@ -1567,6 +1573,10 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), hwoptions, ARRAY_SIZE(hwoptions)*sizeof(int32_t), TRUE, NULL, NULL); break; + case SR_CONF_DEVICE_SESSIONS: + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + sessions, ARRAY_SIZE(sessions)*sizeof(int32_t), TRUE, NULL, NULL); + break; case SR_CONF_SAMPLERATE: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); // gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index 8b6203f0..f5d6ca16 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -167,6 +167,7 @@ struct DSL_context { uint64_t timebase; uint8_t trigger_slope; uint8_t trigger_source; + uint8_t trigger_hrate; uint32_t trigger_hpos; gboolean zero; gboolean stream; diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index 020769bb..7a45f358 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -94,6 +94,36 @@ static const int32_t hwoptions_pro[] = { SR_CONF_CLOCK_EDGE, }; +static const int32_t sessions[] = { + SR_CONF_SAMPLERATE, + SR_CONF_LIMIT_SAMPLES, + SR_CONF_CLOCK_TYPE, + SR_CONF_CLOCK_EDGE, + SR_CONF_OPERATION_MODE, + SR_CONF_THRESHOLD, + SR_CONF_FILTER, + SR_CONF_TRIGGER_SLOPE, + SR_CONF_TRIGGER_SOURCE, + SR_CONF_HORIZ_TRIGGERPOS, +}; + +static const int32_t sessions_pro[] = { + SR_CONF_SAMPLERATE, + SR_CONF_LIMIT_SAMPLES, + SR_CONF_CLOCK_TYPE, + SR_CONF_CLOCK_EDGE, + SR_CONF_OPERATION_MODE, + SR_CONF_VTH, + SR_CONF_FILTER, + SR_CONF_TRIGGER_SLOPE, + SR_CONF_TRIGGER_SOURCE, + SR_CONF_HORIZ_TRIGGERPOS, +}; + +static const int32_t ch_sessions[] = { + SR_CONF_VDIV +}; + static const char *probe_names[] = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", @@ -618,6 +648,7 @@ static struct DSL_context *DSLogic_dev_new(void) devc->trigger_slope = DSO_TRIGGER_RISING; devc->trigger_source = DSO_TRIGGER_AUTO; devc->trigger_hpos = 0x0; + devc->trigger_hrate = 0; devc->zero = FALSE; devc->stream = FALSE; devc->mstatus_valid = FALSE; @@ -1197,23 +1228,16 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_TRIGGER_VALUE: if (!ch) return SR_ERR; - *data = g_variant_new_uint16(ch->trig_value); + *data = g_variant_new_byte(ch->trig_value); break; case SR_CONF_HORIZ_TRIGGERPOS: if (!sdi) return SR_ERR; devc = sdi->priv; if (sdi->mode == DSO) { - uint16_t channel_cnt = 0; - GSList *l; - for (l = sdi->channels; l; l = l->next) { - struct sr_channel *probe = (struct sr_channel *)l->data; - channel_cnt += probe->enabled; - } - uint16_t pos = devc->trigger_hpos * channel_cnt * 100 / devc->limit_samples; - *data = g_variant_new_uint16(pos); + *data = g_variant_new_byte(devc->trigger_hrate); } else { - *data = g_variant_new_uint16(devc->trigger_hpos); + *data = g_variant_new_byte(devc->trigger_hpos); } break; case SR_CONF_ZERO: @@ -1568,7 +1592,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting DSO Trigger Source to %d failed", __func__, devc->trigger_source); } else if (id == SR_CONF_TRIGGER_VALUE) { - ch->trig_value = g_variant_get_uint16(data); + ch->trig_value = g_variant_get_byte(data); if (sdi->mode == DSO) { ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_TRIGGER_VALUE)); } @@ -1586,9 +1610,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, struct sr_channel *probe = (struct sr_channel *)l->data; channel_cnt += probe->enabled; } - devc->trigger_hpos = g_variant_get_uint16(data) * channel_cnt * devc->limit_samples / 200.0; + devc->trigger_hrate = g_variant_get_byte(data); + devc->trigger_hpos = devc->trigger_hrate * channel_cnt * devc->limit_samples / 200.0; } else { - devc->trigger_hpos = g_variant_get_uint16(data) * devc->limit_samples / 100.0; + devc->trigger_hpos = g_variant_get_byte(data) * devc->limit_samples / 100.0; } if (sdi->mode == DSO) { ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 1, SR_CONF_HORIZ_TRIGGERPOS)); @@ -1663,6 +1688,14 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), hwoptions, ARRAY_SIZE(hwoptions)*sizeof(int32_t), TRUE, NULL, NULL); break; + case SR_CONF_DEVICE_SESSIONS: + if (strcmp(sdi->model, "DSLogic Pro") == 0) + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + sessions_pro, ARRAY_SIZE(sessions_pro)*sizeof(int32_t), TRUE, NULL, NULL); + else + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + sessions, ARRAY_SIZE(sessions)*sizeof(int32_t), TRUE, NULL, NULL); + break; case SR_CONF_SAMPLERATE: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); // gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index 861b38a0..29d34902 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -119,6 +119,13 @@ static const int hwoptions[] = { SR_CONF_PATTERN_MODE, }; +static const int32_t sessions[] = { + SR_CONF_SAMPLERATE, + SR_CONF_LIMIT_SAMPLES, + SR_CONF_PATTERN_MODE, +}; + + static const uint64_t samplerates[] = { SR_KHZ(10), SR_KHZ(20), @@ -520,6 +527,10 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), hwoptions, ARRAY_SIZE(hwoptions)*sizeof(int32_t), TRUE, NULL, NULL); break; + case SR_CONF_DEVICE_SESSIONS: + *data = g_variant_new_from_data(G_VARIANT_TYPE("ai"), + sessions, ARRAY_SIZE(sessions)*sizeof(int32_t), TRUE, NULL, NULL); + break; case SR_CONF_SAMPLERATE: g_variant_builder_init(&gvb, G_VARIANT_TYPE("a{sv}")); // gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 3b2af0ae..7300d8af 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -51,12 +51,14 @@ */ static struct sr_config_info sr_config_info_data[] = { - {SR_CONF_CONN, SR_T_CHAR, "conn", + {SR_CONF_CONN, SR_T_CHAR, "conn", "Connection", NULL}, {SR_CONF_SERIALCOMM, SR_T_CHAR, "serialcomm", "Serial communication", NULL}, {SR_CONF_SAMPLERATE, SR_T_UINT64, "samplerate", "Sample rate", NULL}, + {SR_CONF_LIMIT_SAMPLES, SR_T_UINT64, "samplecount", + "Sample count", NULL}, {SR_CONF_CLOCK_TYPE, SR_T_BOOL, "clocktype", "Using External Clock", NULL}, {SR_CONF_CLOCK_EDGE, SR_T_BOOL, "clockedge", @@ -69,15 +71,15 @@ static struct sr_config_info sr_config_info_data[] = { "Trigger types", NULL}, {SR_CONF_RLE, SR_T_BOOL, "rle", "Run Length Encoding", NULL}, - {SR_CONF_TRIGGER_SLOPE, SR_T_UINT64, "triggerslope", + {SR_CONF_TRIGGER_SLOPE, SR_T_UINT8, "triggerslope", "Trigger slope", NULL}, - {SR_CONF_TRIGGER_SOURCE, SR_T_CHAR, "triggersource", + {SR_CONF_TRIGGER_SOURCE, SR_T_UINT8, "triggersource", "Trigger source", NULL}, - {SR_CONF_HORIZ_TRIGGERPOS, SR_T_FLOAT, "horiz_triggerpos", + {SR_CONF_HORIZ_TRIGGERPOS, SR_T_UINT8, "horiz_triggerpos", "Horizontal trigger position", NULL}, {SR_CONF_BUFFERSIZE, SR_T_UINT64, "buffersize", "Buffer size", NULL}, - {SR_CONF_TIMEBASE, SR_T_RATIONAL_PERIOD, "timebase", + {SR_CONF_TIMEBASE, SR_T_UINT64, "timebase", "Time base", NULL}, {SR_CONF_FILTER, SR_T_CHAR, "filter", "Filter Targets", NULL}, diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index c4827412..527414ca 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -156,7 +156,8 @@ typedef int (*sr_receive_data_callback_t)(int fd, int revents, const struct sr_d /** Data types used by sr_config_info(). */ enum { SR_T_UINT64 = 10000, - SR_T_CHAR, + SR_T_UINT8, + SR_T_CHAR, SR_T_BOOL, SR_T_FLOAT, SR_T_RATIONAL_PERIOD, @@ -543,6 +544,8 @@ enum { SR_CHANNEL_LOGIC = 10000, SR_CHANNEL_DSO, SR_CHANNEL_ANALOG, + SR_CHANNEL_GROUP, + SR_CHANNEL_DECODER, }; enum { @@ -810,6 +813,9 @@ enum { SR_CONF_DEVICE_OPTIONS, SR_CONF_DEVICE_CONFIGS, + /** Sessions */ + SR_CONF_DEVICE_SESSIONS, + /** Session filename. */ SR_CONF_SESSIONFILE, diff --git a/libsigrok4DSL/proto.h b/libsigrok4DSL/proto.h index df2d1b3f..bbdcc12f 100644 --- a/libsigrok4DSL/proto.h +++ b/libsigrok4DSL/proto.h @@ -171,6 +171,7 @@ SR_API const char *sr_strerror_name(int error_code); /*--- trigger.c ------------------------------------------------------------*/ SR_API int ds_trigger_init(void); SR_API int ds_trigger_destroy(void); +SR_API struct ds_trigger *ds_trigger_get(void); SR_API int ds_trigger_stage_set_value(uint16_t stage, uint16_t probes, char *trigger0, char *trigger1); SR_API int ds_trigger_stage_set_logic(uint16_t stage, uint16_t probes, unsigned char trigger_logic); SR_API int ds_trigger_stage_set_inv(uint16_t stage, uint16_t probes, unsigned char trigger0_inv, unsigned char trigger1_inv); diff --git a/libsigrok4DSL/trigger.c b/libsigrok4DSL/trigger.c index 393b0e66..17e0740d 100644 --- a/libsigrok4DSL/trigger.c +++ b/libsigrok4DSL/trigger.c @@ -79,6 +79,16 @@ SR_API int ds_trigger_destroy(void) return SR_OK; } +/** + * + * + */ + +SR_API struct ds_trigger *ds_trigger_get(void) +{ + return trigger; +} + /** * set trigger based on stage *