From 800f4c615eb34f3ebe832b1fdbeeac2e8a5a967f Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Wed, 4 Nov 2015 00:27:42 +0800 Subject: [PATCH] Add file save support @ OSC & DAQ mode --- DSView/pv/data/analogsnapshot.cpp | 4 +- DSView/pv/device/file.cpp | 5 +- DSView/pv/devicemanager.cpp | 2 +- DSView/pv/mainwindow.cpp | 6 +- DSView/pv/sigsession.cpp | 82 +++-- DSView/pv/sigsession.h | 2 +- DSView/pv/toolbars/filebar.cpp | 16 +- DSView/pv/view/analogsignal.cpp | 4 +- DSView/pv/view/dsosignal.cpp | 37 ++- DSView/pv/view/logicsignal.cpp | 5 + DSView/pv/view/logicsignal.h | 3 +- DSView/pv/view/view.cpp | 7 +- libsigrok4DSL/hardware/DSL/dscope.c | 4 +- libsigrok4DSL/hardware/DSL/dslogic.c | 180 ++++++----- libsigrok4DSL/hardware/demo/demo.c | 450 ++++++++++++++++----------- libsigrok4DSL/libsigrok.h | 6 + libsigrok4DSL/session_driver.c | 156 +++++++++- libsigrok4DSL/session_file.c | 152 +++++++-- 18 files changed, 768 insertions(+), 353 deletions(-) diff --git a/DSView/pv/data/analogsnapshot.cpp b/DSView/pv/data/analogsnapshot.cpp index 981dc0f9..085cf20c 100644 --- a/DSView/pv/data/analogsnapshot.cpp +++ b/DSView/pv/data/analogsnapshot.cpp @@ -47,7 +47,7 @@ const float AnalogSnapshot::LogEnvelopeScaleFactor = const uint64_t AnalogSnapshot::EnvelopeDataUnit = 64*1024; // bytes AnalogSnapshot::AnalogSnapshot(const sr_datafeed_analog &analog, uint64_t _total_sample_len, unsigned int channel_num) : - Snapshot(sizeof(uint16_t), _total_sample_len, channel_num) + Snapshot(sizeof(uint16_t)*channel_num, _total_sample_len, channel_num) { boost::lock_guard lock(_mutex); memset(_envelope_levels, 0, sizeof(_envelope_levels)); @@ -66,7 +66,7 @@ void AnalogSnapshot::append_payload( const sr_datafeed_analog &analog) { boost::lock_guard lock(_mutex); - append_data(analog.data, analog.num_samples); + append_data(analog.data, analog.num_samples); // Generate the first mip-map from the data append_payload_to_envelope_levels(); diff --git a/DSView/pv/device/file.cpp b/DSView/pv/device/file.cpp index 18c9f6fb..fdc1bd15 100644 --- a/DSView/pv/device/file.cpp +++ b/DSView/pv/device/file.cpp @@ -23,6 +23,8 @@ #include "inputfile.h" #include "sessionfile.h" +#include + #include #include @@ -39,7 +41,8 @@ File::File(QString path) : QString File::format_device_title() const { - return _path; + QFileInfo fi(_path); + return fi.fileName(); } File* File::create(QString name) diff --git a/DSView/pv/devicemanager.cpp b/DSView/pv/devicemanager.cpp index a3d6d212..066af640 100644 --- a/DSView/pv/devicemanager.cpp +++ b/DSView/pv/devicemanager.cpp @@ -102,7 +102,7 @@ std::list > DeviceManager::driver_scan( //release_driver(driver); // Check If DSL hardware driver - if (strcmp(driver->name, "demo") != 0) { + if (strncmp(driver->name, "virtual", 7)) { QDir dir(QCoreApplication::applicationDirPath()); if (!dir.cd("res")) return driver_devices; diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 51472613..482f0361 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -319,8 +319,7 @@ void MainWindow::update_device_list() errorMessage, infoMessage)); } - if (strcmp(selected_device->dev_inst()->driver->name, "demo") != 0 && - strcmp(selected_device->dev_inst()->driver->name, "virtual-session") != 0) { + if (strncmp(selected_device->dev_inst()->driver->name, "virtual", 7)) { _logo_bar->dsl_connected(true); QString ses_name = config_path + QString::fromUtf8(selected_device->dev_inst()->driver->name) + @@ -521,7 +520,8 @@ void MainWindow::closeEvent(QCloseEvent *event) QString driver_name = _session.get_device()->dev_inst()->driver->name; QString mode_name = QString::number(_session.get_device()->dev_inst()->mode); QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".dsc"; - if (!file_name.isEmpty()) + if (strncmp(driver_name.toLocal8Bit(), "virtual", 7) && + !file_name.isEmpty()) store_session(file_name); } event->accept(); diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index e4b026b2..deff6746 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -177,19 +177,45 @@ void SigSession::set_file(QString name) throw(QString) } } -void SigSession::save_file(const QString name){ - const deque< boost::shared_ptr > &snapshots = - _logic_data->get_snapshots(); - if (snapshots.empty()) - return; - - const boost::shared_ptr &snapshot = - snapshots.front(); +void SigSession::save_file(const QString name, int type){ + unsigned char* data; + int unit_size; + uint64_t sample_count; + if (type == ANALOG) { + const deque< boost::shared_ptr > &snapshots = + _analog_data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + data = (unsigned char*)snapshot->get_data(); + unit_size = snapshot->unit_size(); + sample_count = snapshot->get_sample_count(); + } else if (type == DSO) { + const deque< boost::shared_ptr > &snapshots = + _dso_data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + data = (unsigned char*)snapshot->get_data(); + // snapshot->unit_size() is not valid for dso, replaced by enabled channel number + unit_size = get_ch_num(SR_CHANNEL_DSO); + sample_count = snapshot->get_sample_count(); + } else { + const deque< boost::shared_ptr > &snapshots = + _logic_data->get_snapshots(); + if (snapshots.empty()) + return; + const boost::shared_ptr &snapshot = + snapshots.front(); + data = (unsigned char*)snapshot->get_data(); + unit_size = snapshot->unit_size(); + sample_count = snapshot->get_sample_count(); + } sr_session_save(name.toLocal8Bit().data(), _dev_inst->dev_inst(), - (unsigned char*)snapshot->get_data(), - snapshot->unit_size(), - snapshot->get_sample_count()); + data, unit_size, sample_count); } QList SigSession::getSuportedExportFormats(){ @@ -365,8 +391,8 @@ 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() && - strcmp(dev->dev_inst()->driver->name, - "demo") != 0) { + strncmp(dev->dev_inst()->driver->name, + "virtual", 7) != 0) { default_device = dev; break; } @@ -423,7 +449,10 @@ void SigSession::start_capture(bool instant, } // update setting - _instant = instant; + if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session")) + _instant = instant; + else + _instant = true; if (~_instant) _view_timer.blockSignals(false); @@ -545,7 +574,7 @@ void SigSession::sample_thread_proc(boost::shared_ptr dev_inst, assert(s); boost::shared_ptr logicSig; if (logicSig = dynamic_pointer_cast(s)) { - if (logicSig->get_trig() != 0) { + if (logicSig->has_trig()) { ds_trigger_set_en(true); logicSig->set_trig(logicSig->get_trig()); } @@ -628,12 +657,14 @@ void SigSession::add_group() _group_traces.push_back(signal); _group_cnt++; - if (_capture_state == Stopped) { + const deque< boost::shared_ptr > &snapshots = + _logic_data->get_snapshots(); + if (!snapshots.empty()) { //if (!_cur_group_snapshot) //{ // Create a new data snapshot _cur_group_snapshot = boost::shared_ptr( - new data::GroupSnapshot(_logic_data->get_snapshots().front(), signal->get_index_list())); + new data::GroupSnapshot(snapshots.front(), signal->get_index_list())); //_cur_group_snapshot->append_payload(); _group_data->push_snapshot(_cur_group_snapshot); _cur_group_snapshot.reset(); @@ -724,10 +755,6 @@ void SigSession::init_signals() if (logic_probe_count != 0) { _logic_data.reset(new data::Logic()); assert(_logic_data); - - _group_data.reset(new data::Group()); - assert(_group_data); - _group_cnt = 0; } if (dso_probe_count != 0) { @@ -739,10 +766,17 @@ void SigSession::init_signals() _analog_data.reset(new data::Analog()); assert(_analog_data); } + + _group_data.reset(new data::Group()); + assert(_group_data); + _group_cnt = 0; } // Make the logic probe list { + _group_traces.clear(); + vector< boost::shared_ptr >().swap(_group_traces); + for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { const sr_channel *const probe = (const sr_channel *)l->data; @@ -853,8 +887,10 @@ void SigSession::refresh(int holdtime) _analog_data->clear(); _cur_analog_snapshot.reset(); } - _data_lock = true; - _refresh_timer.start(holdtime); + if (strncmp(_dev_inst->dev_inst()->driver->name, "virtual", 7)) { + _data_lock = true; + _refresh_timer.start(holdtime); + } data_updated(); } diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index fbee995c..ed64f491 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -117,7 +117,7 @@ public: void set_file(QString name) throw(QString); - void save_file(const QString name); + void save_file(const QString name, int type); void set_default_device(boost::function error_handler); void export_file(const QString name, QWidget* parent, const QString ext); diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index 4f557505..5562db7a 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -200,22 +200,16 @@ void FileBar::on_actionSave_triggered() msg.setStandardButtons(QMessageBox::Ok); msg.setIcon(QMessageBox::Warning); msg.exec(); - } else if (_session.get_device()->dev_inst()->mode != LOGIC) { - QMessageBox msg(this); - msg.setText(tr("File Save")); - msg.setInformativeText(tr("DSView currently only support saving logic data to file!")); - msg.setStandardButtons(QMessageBox::Ok); - msg.setIcon(QMessageBox::Warning); - msg.exec(); - }else { + } else { QString file_name = QFileDialog::getSaveFileName( - this, tr("Save File"), "", - tr("DSView Data (*.dsl)")); + this, tr("Save File"), "", + tr("DSView Data (*.dsl)")); + if (!file_name.isEmpty()) { QFileInfo f(file_name); if(f.suffix().compare("dsl")) file_name.append(tr(".dsl")); - _session.save_file(file_name); + _session.save_file(file_name, _session.get_device()->dev_inst()->mode); } } } diff --git a/DSView/pv/view/analogsignal.cpp b/DSView/pv/view/analogsignal.cpp index ceeca037..dbef9c00 100644 --- a/DSView/pv/view/analogsignal.cpp +++ b/DSView/pv/view/analogsignal.cpp @@ -137,8 +137,7 @@ void AnalogSignal::paint_trace(QPainter &p, //p.setPen(QPen(_colour, 2, Qt::SolidLine)); QPointF *points = new QPointF[sample_count]; - QPointF *point = points; - + QPointF *point = points; for (int64_t sample = start; sample != end; sample++) { const float x = (sample / samples_per_pixel - pixels_offset) + left; @@ -147,7 +146,6 @@ void AnalogSignal::paint_trace(QPainter &p, } p.drawPolyline(points, point - points); - //delete[] samples; delete[] points; } diff --git a/DSView/pv/view/dsosignal.cpp b/DSView/pv/view/dsosignal.cpp index 98386468..b6118c64 100644 --- a/DSView/pv/view/dsosignal.cpp +++ b/DSView/pv/view/dsosignal.cpp @@ -120,8 +120,6 @@ DsoSignal::DsoSignal(boost::shared_ptr dev_inst, //_trig_vpos(probe->index * 0.5 + 0.25), //_zeroPos(probe->index * 0.5 + 0.25) _trig_vpos(0.5), - _zeroPos(0.5), - _zero_off(255/2.0), _autoV(false), _autoH(false), _hover_en(false), @@ -495,6 +493,19 @@ bool DsoSignal::load_settings() _dev_inst->set_config(_probe, NULL, SR_CONF_COUPLING, g_variant_new_byte(_acCoupling)); + // -- vpos + double vpos; + gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_VPOS); + if (gvar != NULL) { + vpos = g_variant_get_double(gvar); + g_variant_unref(gvar); + } else { + qDebug() << "ERROR: config_get SR_CONF_COUPLING failed."; + return false; + } + _zeroPos = min(max((0.5 - vpos / (_vDial->get_value() * DS_CONF_DSO_VDIVS)), 0.0), 1.0); + _zero_off = _zeroPos * 255; + if (_view) { _view->set_need_update(true); _view->update(); @@ -657,6 +668,7 @@ uint64_t DsoSignal::get_factor() void DsoSignal::set_ms_show(bool show) { _ms_show = show; + _view->set_need_update(true); } bool DsoSignal::get_ms_show() const @@ -1093,7 +1105,12 @@ bool DsoSignal::mouse_press(int right, const QPoint pt) const QRectF x10_rect = get_rect(DSO_X10, y, right); const QRectF x100_rect = get_rect(DSO_X100, y, right); - if (enabled()) { + if (chEn_rect.contains(pt)) { + if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session") && + !_view->session().get_data_lock()) + set_enable(!enabled()); + return true; + } else if (enabled()) { if (vDec_rect.contains(pt)) { go_vDialPre(); } else if (vInc_rect.contains(pt)) { @@ -1114,10 +1131,8 @@ bool DsoSignal::mouse_press(int right, const QPoint pt) setted = true; } } - } else if (chEn_rect.contains(pt)) { - if (!_view->session().get_data_lock()) - set_enable(!enabled()); - } else if (acdc_rect.contains(pt)) { + } else if (strcmp(_dev_inst->dev_inst()->driver->name, "virtual-session") && + acdc_rect.contains(pt)) { if (strcmp(_view->session().get_device()->dev_inst()->driver->name, "DSLogic") == 0) set_acCoupling((get_acCoupling()+1)%2); else @@ -1284,6 +1299,14 @@ void DsoSignal::paint_measure(QPainter &p) _ms_string[DSO_MS_VMEA] = "Vmean: " + (abs(value_vmean) > 1000 ? QString::number(value_vmean/1000.0, 'f', 2) + "V" : QString::number(value_vmean, 'f', 2) + "mV"); } } + } else { + _ms_string[DSO_MS_VMAX] = "Vmax: #####"; + _ms_string[DSO_MS_VMIN] = "Vmin: #####"; + _ms_string[DSO_MS_PERD] = "Perd: #####"; + _ms_string[DSO_MS_FREQ] = "Freq: #####"; + _ms_string[DSO_MS_VP2P] = "Vp-p: #####"; + _ms_string[DSO_MS_VRMS] = "Vrms: #####"; + _ms_string[DSO_MS_VMEA] = "Vmean: #####"; } QColor measure_colour = _colour; diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index ecd534c6..3391317c 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -105,6 +105,11 @@ boost::shared_ptr LogicSignal::logic_data() const return _data; } +bool LogicSignal::has_trig() const +{ + return (_trig != NONTRIG); +} + LogicSignal::LogicSetRegions LogicSignal::get_trig() const { return _trig; diff --git a/DSView/pv/view/logicsignal.h b/DSView/pv/view/logicsignal.h index 9ccc40d0..542ba232 100644 --- a/DSView/pv/view/logicsignal.h +++ b/DSView/pv/view/logicsignal.h @@ -54,7 +54,7 @@ private: static const int StateRound; enum LogicSetRegions{ - NONTRIG = -1, + NONTRIG = 0, POSTRIG, HIGTRIG, NEGTRIG, @@ -82,6 +82,7 @@ public: /** * */ + bool has_trig() const; LogicSetRegions get_trig() const; void set_trig(int trig); diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index 77e9d199..be191e93 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -226,8 +226,11 @@ void View::zoom(double steps, int offset) } } } - _offset = cursor_offset - _scale * offset; - _offset = max(min(_offset, get_max_offset()), get_min_offset()); + + if (_session.get_device()->dev_inst()->mode != DSO) { + _offset = cursor_offset - _scale * offset; + _offset = max(min(_offset, get_max_offset()), get_min_offset()); + } if (_scale != _preScale || _offset != _preOffset) { _header->update(); diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index 8e1a9cf5..7d3fa6e8 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -1485,10 +1485,10 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, ch, SR_CONF_VPOS)); } if (ret == SR_OK) - sr_dbg("%s: setting VPOS of channel %d to %d mv", + sr_dbg("%s: setting VPOS of channel %d to %lf mv", __func__, ch->index, ch->vpos); else - sr_dbg("%s: setting VPOS of channel %d to %d mv failed", + sr_dbg("%s: setting VPOS of channel %d to %lf mv failed", __func__, ch->index, ch->vpos); } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index 895f7ec5..d87e870e 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -722,6 +722,7 @@ static int set_probes(struct sr_dev_inst *sdi, int num_probes) if (sdi->mode == DSO) { probe->vdiv = 1000; probe->vfactor = 1; + probe->vpos = 0; probe->coupling = SR_DC_COUPLING; probe->trig_value = 0x80; } @@ -1294,6 +1295,11 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, return SR_ERR; *data = g_variant_new_uint64(ch->vfactor); break; + case SR_CONF_VPOS: + if (!ch) + return SR_ERR; + *data = g_variant_new_double(ch->vpos); + break; case SR_CONF_TIMEBASE: if (!sdi) return SR_ERR; @@ -1558,71 +1564,75 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else if (id == SR_CONF_OPERATION_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; - if (!strcmp(stropt, opmodes[SR_OP_BUFFER]) && (devc->op_mode != SR_OP_BUFFER)) { - devc->op_mode = SR_OP_BUFFER; - devc->stream = FALSE; - devc->ch_mode = 0; - devc->samplerates_size = 14; - adjust_probes(sdi, buffer_ch_num[0]); - } else if (!strcmp(stropt, opmodes[SR_OP_STREAM]) && (devc->op_mode != SR_OP_STREAM)) { - devc->op_mode = SR_OP_STREAM; - devc->stream = TRUE; - devc->ch_mode = 0; - devc->samplerates_size = 10; - adjust_probes(sdi, stream_ch_num[0]); - } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST]) && (devc->op_mode != SR_OP_INTERNAL_TEST)) { - devc->op_mode = SR_OP_INTERNAL_TEST; - devc->stream = FALSE; - devc->ch_mode = 0; - devc->samplerates_size = 14; - adjust_probes(sdi, buffer_ch_num[0]); - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; - } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST]) && (devc->op_mode != SR_OP_EXTERNAL_TEST)) { - devc->op_mode = SR_OP_EXTERNAL_TEST; - devc->stream = FALSE; - devc->ch_mode = 0; - devc->samplerates_size = 14; - adjust_probes(sdi, buffer_ch_num[0]); - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; - } else if (!strcmp(stropt, opmodes[SR_OP_LOOPBACK_TEST]) && (devc->op_mode != SR_OP_LOOPBACK_TEST)) { - devc->op_mode = SR_OP_LOOPBACK_TEST; - devc->stream = FALSE; - devc->ch_mode = 0; - devc->samplerates_size = 14; - adjust_probes(sdi, buffer_ch_num[0]); - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; - } else { - ret = SR_ERR; + if (sdi->mode == LOGIC) { + if (!strcmp(stropt, opmodes[SR_OP_BUFFER]) && (devc->op_mode != SR_OP_BUFFER)) { + devc->op_mode = SR_OP_BUFFER; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + } else if (!strcmp(stropt, opmodes[SR_OP_STREAM]) && (devc->op_mode != SR_OP_STREAM)) { + devc->op_mode = SR_OP_STREAM; + devc->stream = TRUE; + devc->ch_mode = 0; + devc->samplerates_size = 10; + adjust_probes(sdi, stream_ch_num[0]); + } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST]) && (devc->op_mode != SR_OP_INTERNAL_TEST)) { + devc->op_mode = SR_OP_INTERNAL_TEST; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; + devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; + } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST]) && (devc->op_mode != SR_OP_EXTERNAL_TEST)) { + devc->op_mode = SR_OP_EXTERNAL_TEST; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; + devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; + } else if (!strcmp(stropt, opmodes[SR_OP_LOOPBACK_TEST]) && (devc->op_mode != SR_OP_LOOPBACK_TEST)) { + devc->op_mode = SR_OP_LOOPBACK_TEST; + devc->stream = FALSE; + devc->ch_mode = 0; + devc->samplerates_size = 14; + adjust_probes(sdi, buffer_ch_num[0]); + devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; + devc->cur_samplerate = DSLOGIC_MAX_LOGIC_SAMPLERATE; + } else { + ret = SR_ERR; + } + if (devc->cur_samplerate > samplerates[devc->samplerates_size-1]) + devc->cur_samplerate = samplerates[devc->samplerates_size-1]; } - if (devc->cur_samplerate > samplerates[devc->samplerates_size-1]) - devc->cur_samplerate = samplerates[devc->samplerates_size-1]; sr_dbg("%s: setting pattern to %d", __func__, devc->op_mode); } else if (id == SR_CONF_CHANNEL_MODE) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; - if (devc->stream) { - for (i = 0; i < ARRAY_SIZE(stream_ch_modes); i++) - if (!strcmp(stropt, stream_ch_modes[i])) { - devc->ch_mode = i; - devc->samplerates_size = 10 + i * 2; - adjust_probes(sdi, stream_ch_num[i]); - break; - } - } else { - for (i = 0; i < ARRAY_SIZE(buffer_ch_modes); i++) - if (!strcmp(stropt, buffer_ch_modes[i])) { - devc->ch_mode = i; - devc->samplerates_size = 14 + i; - adjust_probes(sdi, buffer_ch_num[i]); - break; - } + if (sdi->mode == LOGIC) { + if (devc->stream) { + for (i = 0; i < ARRAY_SIZE(stream_ch_modes); i++) + if (!strcmp(stropt, stream_ch_modes[i])) { + devc->ch_mode = i; + devc->samplerates_size = 10 + i * 2; + adjust_probes(sdi, stream_ch_num[i]); + break; + } + } else { + for (i = 0; i < ARRAY_SIZE(buffer_ch_modes); i++) + if (!strcmp(stropt, buffer_ch_modes[i])) { + devc->ch_mode = i; + devc->samplerates_size = 14 + i; + adjust_probes(sdi, buffer_ch_num[i]); + break; + } + } + if (devc->cur_samplerate > samplerates[devc->samplerates_size-1]) + devc->cur_samplerate = samplerates[devc->samplerates_size-1]; } - if (devc->cur_samplerate > samplerates[devc->samplerates_size-1]) - devc->cur_samplerate = samplerates[devc->samplerates_size-1]; sr_dbg("%s: setting channel mode to %d", __func__, devc->ch_mode); } else if (id == SR_CONF_THRESHOLD) { @@ -1635,32 +1645,34 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else { ret = SR_ERR; } - if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { - sr_err("Send FPGA configure command failed!"); - } else { - /* 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))) { - sr_err("fpag_bit path malloc error!"); - return SR_ERR_MALLOC; + if (sdi->mode == LOGIC) { + if ((ret = command_fpga_config(usb->devhdl)) != SR_OK) { + sr_err("Send FPGA configure command failed!"); + } else { + /* 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))) { + sr_err("fpag_bit path malloc error!"); + return SR_ERR_MALLOC; + } + strcpy(fpga_bit, config_path); + switch(devc->th_level) { + case SR_TH_3V3: + strcat(fpga_bit, devc->profile->fpga_bit33);; + break; + case SR_TH_5V0: + strcat(fpga_bit, devc->profile->fpga_bit50);; + break; + default: + return SR_ERR; + } + ret = fpga_config(usb->devhdl, fpga_bit); + if (ret != SR_OK) { + sr_err("Configure FPGA failed!"); + } + g_free(fpga_bit); } - strcpy(fpga_bit, config_path); - switch(devc->th_level) { - case SR_TH_3V3: - strcat(fpga_bit, devc->profile->fpga_bit33);; - break; - case SR_TH_5V0: - strcat(fpga_bit, devc->profile->fpga_bit50);; - break; - default: - return SR_ERR; - } - ret = fpga_config(usb->devhdl, fpga_bit); - if (ret != SR_OK) { - sr_err("Configure FPGA failed!"); - } - g_free(fpga_bit); } sr_dbg("%s: setting threshold to %d", __func__, devc->th_level); @@ -2225,7 +2237,7 @@ static void receive_transfer(struct libusb_transfer *transfer) packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = (*(struct sr_dev_inst *)(devc->cb_data)).channels; - analog.num_samples = transfer->actual_length / sample_width; + analog.num_samples = (transfer->actual_length / sample_width)/g_slist_length(analog.probes); analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; diff --git a/libsigrok4DSL/hardware/demo/demo.c b/libsigrok4DSL/hardware/demo/demo.c index df4414b7..cc38258b 100644 --- a/libsigrok4DSL/hardware/demo/demo.c +++ b/libsigrok4DSL/hardware/demo/demo.c @@ -56,9 +56,9 @@ #define CONST_LEN 50 -#define DEMO_MAX_LOGIC_DEPTH SR_MB(1) -#define DEMO_MAX_LOGIC_SAMPLERATE SR_MHZ(100) -#define DEMO_MAX_DSO_DEPTH SR_KB(32) +#define DEMO_MAX_LOGIC_DEPTH SR_MB(100) +#define DEMO_MAX_LOGIC_SAMPLERATE SR_MHZ(400) +#define DEMO_MAX_DSO_DEPTH SR_KB(20) #define DEMO_MAX_DSO_SAMPLERATE SR_MHZ(200) #define DEMO_MAX_DSO_PROBES_NUM 2 @@ -110,6 +110,10 @@ struct dev_context { gboolean data_lock; uint8_t max_height; + uint16_t *buf; + uint64_t pre_index; + struct sr_status mstatus; + int trigger_stage; uint16_t trigger_mask; uint16_t trigger_value; @@ -137,8 +141,79 @@ static const int32_t sessions[] = { SR_CONF_PATTERN_MODE, }; +static const int const_dc = 50; +static const int sinx[] = { + 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 18, 20, 21, 23, 24, 26, 27, 28, + 30, 31, 32, 33, 34, 35, 37, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, 47, + 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 50, 50, 50, 50, 50, 49, 49, 49, 48, 48, + 47, 47, 46, 46, 45, 44, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, 30, + 29, 28, 26, 25, 24, 22, 21, 19, 18, 16, 15, 13, 12, 10, 9, 7, 6, 4, 2, 1, + -1, -2, -4, -6, -7, -9, -10, -12, -13, -15, -16, -18, -19, -21, -22, -24, -25, -26, -28, -29, +-30, -31, -33, -34, -35, -36, -37, -38, -39, -40, -41, -42, -43, -44, -44, -45, -46, -46, -47, -47, +-48, -48, -49, -49, -49, -50, -50, -50, -50, -50, -50, -50, -50, -50, -49, -49, -49, -49, -48, -48, +-47, -47, -46, -45, -45, -44, -43, -42, -41, -41, -40, -39, -38, -37, -35, -34, -33, -32, -31, -30, +-28, -27, -26, -24, -23, -21, -20, -18, -17, -16, -14, -12, -11, -9, -8, -6, -5, -3, -2, 0, +}; + +static const int sqrx[] = { + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, + 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +-50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, +}; + +static const int trix[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, + 40, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, + 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, + 0, -1, -2, -3, -4, -5, -6, -7, -8, -9, -10, -11, -12, -13, -14, -15, -16, -17, -18, -19, +-20, -21, -22, -23, -24, -25, -26, -27, -28, -29, -30, -31, -32, -33, -34, -35, -36, -37, -38, -39, +-40, -41, -42, -43, -44, -45, -46, -47, -48, -49, -50, -49, -48, -47, -46, -45, -44, -43, -42, -41, +-40, -39, -38, -37, -36, -35, -34, -33, -32, -31, -30, -29, -28, -27, -26, -25, -24, -23, -22, -21, +-20, -19, -18, -17, -16, -15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, +}; + +static const int sawx[] = { + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, + 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, + 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, + 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, + 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 50, +-50, -49, -48, -48, -47, -47, -46, -46, -45, -45, -44, -44, -43, -43, -42, -42, -41, -41, -40, -40, +-39, -39, -38, -38, -37, -37, -36, -36, -35, -35, -34, -34, -33, -33, -32, -32, -31, -31, -30, -30, +-29, -29, -28, -28, -27, -27, -26, -26, -25, -25, -24, -24, -23, -23, -22, -22, -21, -21, -20, -20, +-19, -19, -18, -18, -17, -17, -16, -16, -15, -15, -14, -14, -13, -13, -12, -12, -11, -11, -10, -10, + -9, -9, -8, -8, -7, -7, -6, -6, -5, -5, -4, -4, -3, -3, -2, -2, -1, -1, 0, 0, +}; + +static const int ranx[] = { + -4, 47, -49, -1, -3, 6, -29, 26, 1, 14, -39, -38, 36, 17, 26, -37, -2, 27, -20, -15, +-49, -46, 36, 16, 29, 23, -30, -3, 28, -2, -6, 46, 43, 50, -42, 30, 48, -50, -38, -30, + 7, -36, -20, -24, -10, -34, -24, 3, -48, 46, -11, 22, 19, 28, 39, -49, -31, 34, 2, -29, + 9, 35, 8, 10, 38, 30, 17, 48, -3, -6, -28, 46, -19, 18, -43, -9, -31, -32, -41, 16, +-10, 46, -4, 4, -32, -43, -45, -39, -33, 28, 24, -17, -43, 42, -7, 36, -44, -5, 9, 39, + 17, -40, 12, 16, -42, -1, 2, -9, 50, -8, 27, 27, 14, 8, -18, 12, -8, 26, -8, 12, +-35, 49, 35, 2, -26, -24, -31, 33, 15, -47, 34, 46, -1, -12, 14, 32, -25, -31, -35, -18, +-48, -21, -5, 1, -27, -14, 12, 49, -11, 33, 31, 35, -36, 19, 20, 44, 29, -48, 14, -43, + 1, 30, -12, 44, 20, 49, 29, -43, 42, 30, -34, 24, 20, -40, 33, -12, 13, -45, 45, -24, +-41, 36, -8, 46, 47, -34, 28, -39, 7, -32, 38, -27, 28, -3, -8, 43, -37, -24, 6, 3, +}; static const uint64_t samplerates[] = { + SR_HZ(100), + SR_HZ(200), + SR_HZ(500), + SR_KHZ(1), + SR_KHZ(2), + SR_KHZ(5), SR_KHZ(10), SR_KHZ(20), SR_KHZ(50), @@ -156,25 +231,43 @@ static const uint64_t samplerates[] = { SR_MHZ(400), }; +//static const uint64_t samplecounts[] = { +// SR_KB(1), +// SR_KB(2), +// SR_KB(4), +// SR_KB(8), +// SR_KB(16), +// SR_KB(32), +// SR_KB(64), +// SR_KB(128), +// SR_KB(256), +// SR_KB(512), +// SR_MB(1), +// SR_MB(2), +// SR_MB(4), +// SR_MB(8), +// SR_MB(16), +//}; + static const uint64_t samplecounts[] = { SR_KB(1), SR_KB(2), - SR_KB(4), - SR_KB(8), - SR_KB(16), - SR_KB(32), - SR_KB(64), - SR_KB(128), - SR_KB(256), - SR_KB(512), + SR_KB(5), + SR_KB(10), + SR_KB(20), + SR_KB(50), + SR_KB(100), + SR_KB(200), + SR_KB(500), SR_MB(1), SR_MB(2), - SR_MB(4), - SR_MB(8), - SR_MB(16), + SR_MB(5), + SR_MB(10), + SR_MB(20), + SR_MB(50), + SR_MB(100), }; - /* We name the probes 0-7 on our demo driver. */ static const char *probe_names[NUM_PROBES + 1] = { "Channel 0", "Channel 1", "Channel 2", "Channel 3", @@ -238,11 +331,11 @@ static GSList *hw_scan(GSList *options) } devc->sdi = sdi; - devc->cur_samplerate = DEMO_MAX_LOGIC_SAMPLERATE; - devc->limit_samples = DEMO_MAX_LOGIC_DEPTH; + devc->cur_samplerate = SR_MHZ(1); + devc->limit_samples = SR_MB(1); devc->limit_msec = 0; devc->sample_generator = PATTERN_SINE; - devc->timebase = 10000; + devc->timebase = 200; devc->data_lock = FALSE; devc->max_height = 1; @@ -372,6 +465,9 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_MAX_HEIGHT_VALUE: *data = g_variant_new_byte(devc->max_height); break; + case SR_CONF_VPOS: + *data = g_variant_new_double(ch->vpos); + break; case SR_CONF_VDIV: *data = g_variant_new_uint64(ch->vdiv); break; @@ -417,6 +513,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, int ret; const char *stropt; struct sr_channel *probe; + uint64_t tmp_u64; (void) cg; @@ -427,6 +524,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (id == SR_CONF_SAMPLERATE) { devc->cur_samplerate = g_variant_get_uint64(data); + devc->samples_counter = 0; + devc->pre_index = 0; sr_dbg("%s: setting samplerate to %" PRIu64, __func__, devc->cur_samplerate); ret = SR_OK; @@ -463,8 +562,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else { probe->vdiv = 1000; probe->vfactor = 1; - probe->coupling = SR_DC_COUPLING; + probe->coupling = SR_AC_COUPLING; probe->trig_value = 0x80; + probe->vpos = (probe->index == 0 ? 0.5 : -0.5)*probe->vdiv; sdi->channels = g_slist_append(sdi->channels, probe); } } @@ -479,6 +579,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, else sdi->channels = g_slist_append(sdi->channels, probe); } + devc->cur_samplerate = SR_HZ(100); + devc->limit_samples = SR_KB(1); } else { ret = SR_ERR; } @@ -532,7 +634,9 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, devc->data_lock); ret = SR_OK; } else if (id == SR_CONF_VDIV) { - ch->vdiv = g_variant_get_uint64(data); + tmp_u64 = g_variant_get_uint64(data); + ch->vpos = (tmp_u64 * 1.0 / ch->vdiv) * ch->vpos; + ch->vdiv = tmp_u64; sr_dbg("%s: setting VDIV of channel %d to %" PRIu64, __func__, ch->index, ch->vdiv); ret = SR_OK; @@ -541,6 +645,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, sr_dbg("%s: setting FACTOR of channel %d to %" PRIu64, __func__, ch->index, ch->vfactor); ret = SR_OK; + } else if (id == SR_CONF_VPOS) { + ch->vpos = g_variant_get_double(data); + sr_dbg("%s: setting VPOS of channel %d to %lf", __func__, + ch->index, ch->vpos); + ret = SR_OK; } else if (id == SR_CONF_TIMEBASE) { devc->timebase = g_variant_get_uint64(data); sr_dbg("%s: setting TIMEBASE to %" PRIu64, __func__, @@ -617,144 +726,106 @@ static void samples_generator(uint16_t *buf, uint64_t size, const struct sr_dev_inst *sdi, struct dev_context *devc) { - static uint16_t p = 0; - uint64_t i; - uint16_t demo_data; + uint64_t i, pre0_i, pre1_i, index; + GSList *l; + struct sr_channel *probe; + int offset; + int start_rand; + const uint64_t span = DEMO_MAX_DSO_SAMPLERATE / devc->cur_samplerate; + const uint64_t len = ARRAY_SIZE(sinx) - 1; + int *pre_buf; - switch (devc->sample_generator) { + switch (devc->sample_generator) { case PATTERN_SINE: /* Sine */ - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - //demo_data = 0x8000 * sin(2 * PI * p / 0xffff) + 0x8000; - demo_data = 0x20 * (sin(2 * PI * p / 0xff) + 1); - p++; - } - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += ((0x40 + demo_data) << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += ((0x60 + demo_data) << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } - break; + pre_buf = sinx; + break; case PATTERN_SQUARE: - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - demo_data = p > 0x7fff ? 0x4040 : 0x0000; - p += CONST_LEN * 10; - } - *(buf + i) = demo_data; - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } + pre_buf = sqrx; break; case PATTERN_TRIANGLE: - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - demo_data = p > 0x7fff ? 0x40 * (1 + (0x8000 - p * 1.0) / 0x8000) : - 0x40 * (p * 1.0 / 0x8000); - p += CONST_LEN * 10; - } - *(buf + i) = demo_data + (demo_data << 8); - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } + pre_buf = trix; break; case PATTERN_SAWTOOTH: - for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) { - demo_data = p & 0x003f; - p ++; - } - *(buf + i) = demo_data + (demo_data << 8); - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; - } - } - } + pre_buf = sawx; break; - case PATTERN_RANDOM: /* Random */ + case PATTERN_RANDOM: + pre_buf = ranx; + break; + default: + pre_buf = sinx; + break; + } + + if (devc->samples_counter == devc->limit_samples && + size != devc->limit_samples) { + for (i = 0; i < devc->limit_samples; i++) + *(buf + i) = *(buf + ((i + size)%devc->limit_samples)); + } else if (sdi->mode != DSO) { + start_rand = rand()%len; for (i = 0; i < size; i++) { - if (i%CONST_LEN == 0) - demo_data = (uint16_t)(rand() * (0x40 * 1.0 / RAND_MAX)); - *(buf + i) = demo_data + (demo_data << 8); - GSList *l; - struct sr_channel *probe; - for (l = sdi->channels; l; l = l->next) { - probe = (struct sr_channel *)l->data; - if (probe->coupling == SR_DC_COUPLING) - *(buf + i) += (0x40 << (probe->index * 8)); - else if (probe->coupling == SR_AC_COUPLING) - *(buf + i) += (0x60 << (probe->index * 8)); - else - if (probe->index == 0) { - *(buf + i) &= 0xff00; - *(buf + i) += 0x0080; - }else { - *(buf + i) &= 0x00ff; - *(buf + i) += 0x8000; + index = (i/g_slist_length(sdi->channels)+start_rand)%len; + *(buf + i) = (uint16_t)(((const_dc+pre_buf[index]) << 8) + (const_dc+pre_buf[index])); + } + } else { + if (devc->pre_index == 0) { + devc->mstatus.ch0_max = 0; + devc->mstatus.ch0_min = 255; + devc->mstatus.ch1_max = 0; + devc->mstatus.ch1_min = 255; + devc->mstatus.ch0_period = 0; + devc->mstatus.ch0_pcnt = 1; + devc->mstatus.ch1_period = 0; + devc->mstatus.ch1_pcnt = 1; + } + memset(buf+devc->pre_index, 0, size*sizeof(uint16_t)); + for (l = sdi->channels; l; l = l->next) { + start_rand = devc->pre_index == 0 ? rand()%len : 0; + probe = (struct sr_channel *)l->data; + offset = ceil((0.5 - (probe->vpos/probe->vdiv/10.0)) * 255); + pre0_i = devc->pre_index; + pre1_i = devc->pre_index; + for (i = devc->pre_index; i < devc->pre_index + size; i++) { + if (probe->coupling == SR_DC_COUPLING) { + *(buf + i) += (uint8_t)(offset + (1000.0/probe->vdiv) * (pre_buf[(i*span+start_rand)%len] - const_dc)) << (probe->index * 8); + } else if (probe->coupling == SR_AC_COUPLING) { + *(buf + i) += (uint8_t)(offset + (1000.0/probe->vdiv) * pre_buf[(i*span+start_rand)%len]) << (probe->index * 8); + } else { + *(buf + i) += offset << (probe->index * 8); + } + + if (probe->index == 0) { + devc->mstatus.ch0_max = MAX(devc->mstatus.ch0_max, (*(buf + i) & 0x00ff)); + devc->mstatus.ch0_min = MIN(devc->mstatus.ch0_min, (*(buf + i) & 0x00ff)); + if (i > devc->pre_index && + pre_buf[(i*span+start_rand)%len] < 0 && + pre_buf[((i-1)*span+start_rand)%len] > 0) { + devc->mstatus.ch0_period = 2*(i - pre0_i)*pow(10, 8)/DEMO_MAX_DSO_SAMPLERATE; + pre0_i = i; } + } else { + devc->mstatus.ch1_max = MAX(devc->mstatus.ch1_max, ((*(buf + i) & 0xff00) >> 8)); + devc->mstatus.ch1_min = MIN(devc->mstatus.ch1_min, ((*(buf + i) & 0xff00) >> 8)); + if (i > devc->pre_index && + pre_buf[(i*span+start_rand)%len] < 0 && + pre_buf[((i-1)*span+start_rand)%len] > 0) { + devc->mstatus.ch1_period = 2*(i - pre1_i)*pow(10, 8)/DEMO_MAX_DSO_SAMPLERATE; + pre1_i = i; + } + } } } - break; - default: - sr_err("Unknown pattern: %d.", devc->sample_generator); - break; - } + + for (l = sdi->channels; l; l = l->next) { + probe = (struct sr_channel *)l->data; + if (!probe->enabled) { + devc->mstatus.ch1_max = MAX(devc->mstatus.ch0_max, devc->mstatus.ch1_max); + devc->mstatus.ch1_min = MIN(devc->mstatus.ch0_min, devc->mstatus.ch1_min); + devc->mstatus.ch0_max = MAX(devc->mstatus.ch0_max, devc->mstatus.ch1_max); + devc->mstatus.ch0_min = MIN(devc->mstatus.ch0_min, devc->mstatus.ch1_min); + break; + } + } + } } /* Callback handling data */ @@ -765,8 +836,6 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) struct sr_datafeed_logic logic; struct sr_datafeed_dso dso; struct sr_datafeed_analog analog; - //uint16_t buf[BUFSIZE]; - uint16_t *buf; static uint64_t samples_to_send, expected_samplenum, sending_now; int64_t time, elapsed; static uint16_t last_sample = 0; @@ -776,43 +845,39 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) (void)fd; (void)revents; - if (!(buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) { - sr_err("buf for receive_data malloc failed."); - return FALSE; - } - /* How many "virtual" samples should we have collected by now? */ time = g_get_monotonic_time(); elapsed = time - devc->starttime; devc->starttime = time; - expected_samplenum = elapsed * devc->cur_samplerate / 1000000; + //expected_samplenum = ceil(elapsed / 1000000.0 * devc->cur_samplerate); /* Of those, how many do we still have to send? */ //samples_to_send = (expected_samplenum - devc->samples_counter) / CONST_LEN * CONST_LEN; - samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN; + //samples_to_send = expected_samplenum / CONST_LEN * CONST_LEN; + samples_to_send = ceil(elapsed / 1000000.0 * devc->cur_samplerate); if (devc->limit_samples) { - if (sdi->mode == LOGIC || devc->instant) + if ((sdi->mode == DSO && !devc->instant) || sdi->mode == ANALOG) samples_to_send = MIN(samples_to_send, - devc->limit_samples - devc->samples_counter); + devc->limit_samples - devc->pre_index); else samples_to_send = MIN(samples_to_send, - devc->limit_samples); + devc->limit_samples - devc->samples_counter); } while (samples_to_send > 0) { sending_now = MIN(samples_to_send, BUFSIZE); - samples_generator(buf, sending_now, sdi, devc); + samples_generator(devc->buf, sending_now, sdi, devc); if (devc->trigger_stage != 0) { for (i = 0; i < sending_now; i++) { if (devc->trigger_edge == 0) { - if ((*(buf + i) | devc->trigger_mask) == + if ((*(devc->buf + i) | devc->trigger_mask) == (devc->trigger_value | devc->trigger_mask)) { devc->trigger_stage = 0; break; } } else { - cur_sample = *(buf + i); + cur_sample = *(devc->buf + i); if (((last_sample & devc->trigger_edge) == (~devc->trigger_value & devc->trigger_edge)) && ((cur_sample | devc->trigger_mask) == @@ -834,6 +899,14 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) } } + if (sdi->mode == ANALOG) + devc->samples_counter += sending_now/g_slist_length(sdi->channels); + else + devc->samples_counter += sending_now; + if (sdi->mode == DSO && !devc->instant && + devc->samples_counter > devc->limit_samples) + devc->samples_counter = devc->limit_samples; + if (devc->trigger_stage == 0){ samples_to_send -= sending_now; if (sdi->mode == LOGIC) { @@ -841,47 +914,56 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *sdi) packet.payload = &logic; logic.length = sending_now * (NUM_PROBES >> 3); logic.unitsize = (NUM_PROBES >> 3); - logic.data = buf; + logic.data = devc->buf; } else if (sdi->mode == DSO) { packet.type = SR_DF_DSO; packet.payload = &dso; dso.probes = sdi->channels; - dso.num_samples = sending_now; + if (devc->instant) + dso.num_samples = sending_now; + else + dso.num_samples = devc->samples_counter; dso.mq = SR_MQ_VOLTAGE; dso.unit = SR_UNIT_VOLT; dso.mqflags = SR_MQFLAG_AC; - dso.data = buf; + dso.data = devc->buf; }else { packet.type = SR_DF_ANALOG; packet.payload = &analog; analog.probes = sdi->channels; - analog.num_samples = sending_now; + analog.num_samples = sending_now / g_slist_length(sdi->channels); analog.mq = SR_MQ_VOLTAGE; analog.unit = SR_UNIT_VOLT; analog.mqflags = SR_MQFLAG_AC; - analog.data = buf; + analog.data = devc->buf; + } + + if (sdi->mode == DSO && !devc->instant) { + devc->pre_index += sending_now; + if (sdi->mode == DSO && !devc->instant && + devc->pre_index >= devc->limit_samples) + devc->pre_index = 0; } sr_session_send(sdi, &packet); - if (sdi->mode == LOGIC || devc->instant) - devc->samples_counter += sending_now; - else - devc->samples_counter = (devc->samples_counter + sending_now) % devc->limit_samples; + + devc->mstatus.trig_hit = (devc->trigger_stage == 0); + devc->mstatus.captured_cnt0 = devc->samples_counter; + devc->mstatus.captured_cnt1 = devc->samples_counter >> 8; + devc->mstatus.captured_cnt2 = devc->samples_counter >> 16; + devc->mstatus.captured_cnt3 = devc->samples_counter >> 32; } else { break; } } - if (devc->limit_samples && + if ((sdi->mode == LOGIC || devc->instant) && devc->limit_samples && devc->samples_counter >= devc->limit_samples) { sr_info("Requested number of samples reached."); hw_dev_acquisition_stop(sdi, NULL); - g_free(buf); return TRUE; } - g_free(buf); - return TRUE; } @@ -897,6 +979,11 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, //devc->cb_data = cb_data; devc->samples_counter = 0; + devc->pre_index = 0; + devc->mstatus.captured_cnt0 = 0; + devc->mstatus.captured_cnt1 = 0; + devc->mstatus.captured_cnt2 = 0; + devc->mstatus.captured_cnt3 = 0; devc->stop = FALSE; /* @@ -944,6 +1031,11 @@ static int hw_dev_acquisition_start(const struct sr_dev_inst *sdi, //std_session_send_df_header(cb_data, LOG_PREFIX); std_session_send_df_header(sdi, LOG_PREFIX); + if (!(devc->buf = g_try_malloc(BUFSIZE*sizeof(uint16_t)))) { + sr_err("buf for receive_data malloc failed."); + return FALSE; + } + /* We use this timestamp to decide how many more samples to send. */ devc->starttime = g_get_monotonic_time(); @@ -965,6 +1057,8 @@ static int hw_dev_acquisition_stop(struct sr_dev_inst *sdi, void *cb_data) g_io_channel_unref(devc->channel); devc->channel = NULL; + g_free(devc->buf); + /* Send last packet. */ packet.type = SR_DF_END; sr_session_send(sdi, &packet); @@ -986,11 +1080,7 @@ static int hw_dev_status_get(struct sr_dev_inst *sdi, struct sr_status *status, (void)end; if (sdi) { struct dev_context *const devc = sdi->priv; - status->trig_hit = (devc->trigger_stage == 0); - status->captured_cnt0 = devc->samples_counter; - status->captured_cnt1 = devc->samples_counter >> 8; - status->captured_cnt2 = devc->samples_counter >> 16; - status->captured_cnt3 = devc->samples_counter >> 32; + *status = devc->mstatus; return SR_OK; } else { return SR_ERR; @@ -998,7 +1088,7 @@ static int hw_dev_status_get(struct sr_dev_inst *sdi, struct sr_status *status, } SR_PRIV struct sr_dev_driver demo_driver_info = { - .name = "demo", + .name = "virtual-demo", .longname = "Demo driver and pattern generator", .api_version = 1, .init = hw_init, diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index b701b191..477d3646 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -753,6 +753,12 @@ enum { SR_CONF_ZERO, SR_CONF_ZERO_OVER, + /** status for dso channel */ + SR_CONF_STATUS_PERIOD, + SR_CONF_STATUS_PCNT, + SR_CONF_STATUS_MAX, + SR_CONF_STATUS_MIN, + /** Stream */ SR_CONF_STREAM, diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index 81b475de..fa1d0c0f 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -54,6 +54,8 @@ struct session_vdev { uint64_t total_samples; int unitsize; int num_probes; + uint64_t timebase; + struct sr_status mstatus; }; static GSList *dev_insts = NULL; @@ -69,6 +71,8 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) struct session_vdev *vdev; struct sr_datafeed_packet packet; struct sr_datafeed_logic logic; + struct sr_datafeed_dso dso; + struct sr_datafeed_analog analog; GSList *l; int ret, got_data; (void)fd; @@ -87,11 +91,31 @@ static int receive_data(int fd, int revents, const struct sr_dev_inst *cb_sdi) ret = zip_fread(vdev->capfile, vdev->buf, CHUNKSIZE); if (ret > 0) { got_data = TRUE; - packet.type = SR_DF_LOGIC; - packet.payload = &logic; - logic.length = ret; - logic.unitsize = vdev->unitsize; - logic.data = vdev->buf; + if (sdi->mode == DSO) { + packet.type = SR_DF_DSO; + packet.payload = &dso; + dso.num_samples = ret / vdev->unitsize; + dso.data = vdev->buf; + dso.probes = sdi->channels; + dso.mq = SR_MQ_VOLTAGE; + dso.unit = SR_UNIT_VOLT; + dso.mqflags = SR_MQFLAG_AC; + } else if (sdi->mode == ANALOG){ + packet.type = SR_DF_ANALOG; + packet.payload = &analog; + analog.probes = sdi->channels; + analog.num_samples = ret / vdev->unitsize; + analog.mq = SR_MQ_VOLTAGE; + analog.unit = SR_UNIT_VOLT; + analog.mqflags = SR_MQFLAG_AC; + analog.data = vdev->buf; + } else { + packet.type = SR_DF_LOGIC; + packet.payload = &logic; + logic.length = ret; + logic.unitsize = vdev->unitsize; + logic.data = vdev->buf; + } vdev->bytes_read += ret; sr_session_send(cb_sdi, &packet); } else { @@ -166,7 +190,9 @@ static int dev_close(struct sr_dev_inst *sdi) return SR_OK; } -static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) +static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, + const struct sr_channel *ch, + const struct sr_channel_group *cg) { struct session_vdev *vdev; @@ -185,14 +211,63 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi) } else return SR_ERR; break; - default: + case SR_CONF_TIMEBASE: + if (sdi) { + vdev = sdi->priv; + *data = g_variant_new_uint64(vdev->timebase); + } else + return SR_ERR; + break; + case SR_CONF_EN_CH: + if (sdi && ch) { + *data = g_variant_new_boolean(ch->enabled); + } else + return SR_ERR; + break; + case SR_CONF_COUPLING: + if (sdi && ch) { + *data = g_variant_new_byte(ch->coupling); + } else + return SR_ERR; + break; + case SR_CONF_VDIV: + if (sdi && ch) { + *data = g_variant_new_uint64(ch->vdiv); + } else + return SR_ERR; + break; + case SR_CONF_FACTOR: + if (sdi && ch) { + *data = g_variant_new_uint64(ch->vfactor); + } else + return SR_ERR; + break; + case SR_CONF_VPOS: + if (sdi && ch) { + *data = g_variant_new_double(ch->vpos); + } else + return SR_ERR; + break; + case SR_CONF_MAX_DSO_SAMPLERATE: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(vdev->samplerate); + break; + case SR_CONF_MAX_DSO_SAMPLELIMITS: + if (!sdi) + return SR_ERR; + *data = g_variant_new_uint64(vdev->total_samples); + break; + default: return SR_ERR_ARG; } return SR_OK; } -static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) +static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi, + struct sr_channel *ch, + const struct sr_channel_group *cg) { struct session_vdev *vdev; @@ -204,7 +279,11 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) samplerates[0] = vdev->samplerate; sr_info("Setting samplerate to %" PRIu64 ".", vdev->samplerate); break; - case SR_CONF_SESSIONFILE: + case SR_CONF_TIMEBASE: + vdev->timebase = g_variant_get_uint64(data); + sr_info("Setting timebase to %" PRIu64 ".", vdev->timebase); + break; + case SR_CONF_SESSIONFILE: vdev->sessionfile = g_strdup(g_variant_get_bytestring(data)); sr_info("Setting sessionfile to '%s'.", vdev->sessionfile); break; @@ -223,7 +302,46 @@ static int config_set(int id, GVariant *data, const struct sr_dev_inst *sdi) case SR_CONF_CAPTURE_NUM_PROBES: vdev->num_probes = g_variant_get_uint64(data); break; - default: + case SR_CONF_EN_CH: + ch->enabled = g_variant_get_boolean(data); + break; + case SR_CONF_COUPLING: + ch->coupling = g_variant_get_byte(data); + break; + case SR_CONF_VDIV: + ch->vdiv = g_variant_get_uint64(data); + break; + case SR_CONF_FACTOR: + ch->vfactor = g_variant_get_uint64(data); + break; + case SR_CONF_VPOS: + ch->vpos = g_variant_get_double(data); + break; + case SR_CONF_STATUS_PERIOD: + if (ch->index == 0) + vdev->mstatus.ch0_period = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_period = g_variant_get_uint64(data); + break; + case SR_CONF_STATUS_PCNT: + if (ch->index == 0) + vdev->mstatus.ch0_pcnt = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_pcnt = g_variant_get_uint64(data); + break; + case SR_CONF_STATUS_MAX: + if (ch->index == 0) + vdev->mstatus.ch0_max = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_max = g_variant_get_uint64(data); + break; + case SR_CONF_STATUS_MIN: + if (ch->index == 0) + vdev->mstatus.ch0_min = g_variant_get_uint64(data); + else + vdev->mstatus.ch1_min = g_variant_get_uint64(data); + break; + default: sr_err("Unknown capability: %d.", id); return SR_ERR; } @@ -268,6 +386,22 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi) return SR_OK; } +static int dev_status_get(struct sr_dev_inst *sdi, struct sr_status *status, int begin, int end) +{ + (void)begin; + (void)end; + + struct session_vdev *vdev; + + if (sdi) { + vdev = sdi->priv; + *status = vdev->mstatus; + return SR_OK; + } else { + return SR_ERR; + } +} + static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) { @@ -324,7 +458,7 @@ SR_PRIV struct sr_dev_driver session_driver = { .dev_open = dev_open, .dev_close = dev_close, .dev_test = NULL, - .dev_status_get = NULL, + .dev_status_get = dev_status_get, .dev_acquisition_start = dev_acquisition_start, .dev_acquisition_stop = NULL, .priv = NULL, diff --git a/libsigrok4DSL/session_file.c b/libsigrok4DSL/session_file.c index 5e84ee66..aa77128d 100644 --- a/libsigrok4DSL/session_file.c +++ b/libsigrok4DSL/session_file.c @@ -121,12 +121,15 @@ SR_API int sr_session_load(const char *filename) struct zip_stat zs; struct sr_dev_inst *sdi; struct sr_channel *probe; - int ret, devcnt, i, j; + int ret, devcnt, i, j, k; uint16_t probenum; uint64_t tmp_u64, total_probes, enabled_probes; uint16_t p; char **sections, **keys, *metafile, *val, s[11]; char probename[SR_MAX_PROBENAME_LEN + 1]; + int mode = LOGIC; + int channel_type = SR_CHANNEL_LOGIC; + double tmp_double; if (!filename) { sr_err("%s: filename was NULL", __func__); @@ -140,7 +143,7 @@ SR_API int sr_session_load(const char *filename) /* read "metadata" */ if (zip_stat(archive, "header", 0, &zs) == -1) { - sr_dbg("Not a valid DSLogic session file."); + sr_dbg("Not a valid DSView data file."); return SR_ERR; } @@ -175,8 +178,10 @@ SR_API int sr_session_load(const char *filename) keys = g_key_file_get_keys(kf, sections[i], NULL, NULL); for (j = 0; keys[j]; j++) { val = g_key_file_get_string(kf, sections[i], keys[j], NULL); - if (!strcmp(keys[j], "capturefile")) { - sdi = sr_dev_inst_new(LOGIC, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL); + if (!strcmp(keys[j], "device mode")) { + mode = strtoull(val, NULL, 10); + } else if (!strcmp(keys[j], "capturefile")) { + sdi = sr_dev_inst_new(mode, devcnt, SR_ST_ACTIVE, NULL, NULL, NULL); sdi->driver = &session_driver; if (devcnt == 0) /* first device, init the driver */ @@ -200,13 +205,19 @@ 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], "total probes")) { + } 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], "total probes")) { total_probes = strtoull(val, NULL, 10); sdi->driver->config_set(SR_CONF_CAPTURE_NUM_PROBES, g_variant_new_uint64(total_probes), sdi, NULL, NULL); + channel_type = (mode == DSO) ? SR_CHANNEL_DSO : + (mode == ANALOG) ? SR_CHANNEL_ANALOG : SR_CHANNEL_LOGIC; for (p = 0; p < total_probes; p++) { snprintf(probename, SR_MAX_PROBENAME_LEN, "%" PRIu64, p); - if (!(probe = sr_channel_new(p, SR_CHANNEL_LOGIC, FALSE, + if (!(probe = sr_channel_new(p, channel_type, FALSE, probename))) return SR_ERR; sdi->channels = g_slist_append(sdi->channels, probe); @@ -222,7 +233,79 @@ SR_API int sr_session_load(const char *filename) } else if (!strncmp(keys[j], "trigger", 7)) { probenum = strtoul(keys[j]+7, NULL, 10); sr_dev_trigger_set(sdi, probenum, val); - } + } else if (!strncmp(keys[j], "enable", 6)) { + probenum = strtoul(keys[j]+6, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_EN_CH, + g_variant_new_boolean(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "coupling", 8)) { + probenum = strtoul(keys[j]+8, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_COUPLING, + g_variant_new_byte(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "vDiv", 4)) { + probenum = strtoul(keys[j]+4, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_VDIV, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "vFactor", 7)) { + probenum = strtoul(keys[j]+7, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_FACTOR, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "vPos", 4)) { + probenum = strtoul(keys[j]+4, NULL, 10); + tmp_double = strtod(val, NULL); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_VPOS, + g_variant_new_double(tmp_double), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "period", 6)) { + probenum = strtoul(keys[j]+6, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_PERIOD, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "pcnt", 4)) { + probenum = strtoul(keys[j]+4, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_PCNT, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "max", 3)) { + probenum = strtoul(keys[j]+3, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_MAX, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } else if (!strncmp(keys[j], "min", 3)) { + probenum = strtoul(keys[j]+3, NULL, 10); + tmp_u64 = strtoull(val, NULL, 10); + if (probenum < g_slist_length(sdi->channels)) { + probe = g_slist_nth(sdi->channels, probenum)->data; + sdi->driver->config_set(SR_CONF_STATUS_MIN, + g_variant_new_uint64(tmp_u64), sdi, probe, NULL); + } + } } g_strfreev(keys); } @@ -257,8 +340,9 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, struct zip *zipfile; struct zip_source *versrc, *metasrc, *logicsrc; int tmpfile, ret, probecnt; - uint64_t samplerate; + uint64_t samplerate, timeBase, tmp_u64; char rawname[16], metafile[32], *s; + struct sr_status status; if (!filename) { sr_err("%s: filename was NULL", __func__); @@ -271,42 +355,68 @@ SR_API int sr_session_save(const char *filename, const struct sr_dev_inst *sdi, return SR_ERR; /* init "metadata" */ - strcpy(metafile, "DSLogic-meta-XXXXXX"); + strcpy(metafile, "DSView-meta-XXXXXX"); if ((tmpfile = g_mkstemp(metafile)) == -1) return SR_ERR; close(tmpfile); meta = g_fopen(metafile, "wb"); fprintf(meta, "[version]\n"); - fprintf(meta, "DSLogic version = %s\n", PACKAGE_VERSION); + fprintf(meta, "DSView version = %s\n", PACKAGE_VERSION); /* metadata */ fprintf(meta, "[header]\n"); - if (sdi->driver) + if (sdi->driver) { fprintf(meta, "driver = %s\n", sdi->driver->name); + fprintf(meta, "device mode = %d\n", sdi->mode); + } /* metadata */ fprintf(meta, "capturefile = data\n"); fprintf(meta, "unitsize = %d\n", unitsize); fprintf(meta, "total samples = %d\n", units); fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels)); - if (sr_dev_has_option(sdi, SR_CONF_SAMPLERATE)) { - if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, - &gvar) == SR_OK) { - samplerate = g_variant_get_uint64(gvar); - s = sr_samplerate_string(samplerate); - fprintf(meta, "samplerate = %s\n", s); - g_free(s); - g_variant_unref(gvar); - } + if (sr_config_get(sdi->driver, sdi, NULL, NULL, SR_CONF_SAMPLERATE, + &gvar) == SR_OK) { + samplerate = g_variant_get_uint64(gvar); + s = sr_samplerate_string(samplerate); + fprintf(meta, "samplerate = %s\n", s); + g_free(s); + g_variant_unref(gvar); + } + 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); + g_variant_unref(gvar); } probecnt = 1; for (l = sdi->channels; l; l = l->next) { probe = l->data; - if (probe->enabled) { + if (probe->enabled || sdi->mode == DSO) { if (probe->name) fprintf(meta, "probe%d = %s\n", probe->index, probe->name); if (probe->trigger) fprintf(meta, " trigger%d = %s\n", probe->index, probe->trigger); + if (sdi->mode == DSO) { + fprintf(meta, " enable%d = %d\n", probe->index, probe->enabled); + fprintf(meta, " coupling%d = %d\n", probe->index, probe->coupling); + fprintf(meta, " vDiv%d = %d\n", probe->index, probe->vdiv); + fprintf(meta, " vFactor%d = %d\n", probe->index, probe->vfactor); + 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, " 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, " max%d = %d\n", probe->index, status.ch1_max); + fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min); + } + } + } probecnt++; } }