From f3023e7917e20cee560a9102f1ab081907c47c4b Mon Sep 17 00:00:00 2001 From: DreamSourceLab Date: Sat, 26 Sep 2015 21:59:40 +0800 Subject: [PATCH] add RLE compress function --- DSView/pv/data/decode/annotation.cpp | 9 +- DSView/pv/data/decode/annotation.h | 1 + DSView/pv/data/decode/decoder.cpp | 6 +- DSView/pv/data/decode/row.cpp | 5 + DSView/pv/data/decode/row.h | 1 + DSView/pv/data/decode/rowdata.cpp | 5 + DSView/pv/data/decode/rowdata.h | 1 + DSView/pv/data/decoderstack.cpp | 8 +- DSView/pv/data/logicsnapshot.cpp | 10 +- DSView/pv/data/logicsnapshot.h | 3 +- DSView/pv/dialogs/deviceoptions.cpp | 99 +++++++- DSView/pv/dialogs/deviceoptions.h | 6 + .../pv/prop/binding/binding_deviceoptions.cpp | 12 +- DSView/pv/prop/property.cpp | 2 +- DSView/pv/prop/property.h | 6 +- DSView/pv/sigsession.cpp | 20 +- DSView/pv/storesession.cpp | 9 +- DSView/pv/toolbars/samplingbar.cpp | 78 +++++- DSView/pv/view/decodetrace.cpp | 12 + DSView/pv/view/decodetrace.h | 1 + DSView/pv/view/logicsignal.cpp | 1 + libsigrok4DSL/hardware/DSL/dscope.c | 10 +- libsigrok4DSL/hardware/DSL/dsl.h | 4 + libsigrok4DSL/hardware/DSL/dslogic.c | 230 ++++++++++++------ libsigrok4DSL/hwdriver.c | 4 +- libsigrok4DSL/libsigrok.h | 15 +- libsigrok4DSL/session_driver.c | 12 +- 27 files changed, 425 insertions(+), 145 deletions(-) diff --git a/DSView/pv/data/decode/annotation.cpp b/DSView/pv/data/decode/annotation.cpp index 32d38970..9cd82f4e 100644 --- a/DSView/pv/data/decode/annotation.cpp +++ b/DSView/pv/data/decode/annotation.cpp @@ -42,13 +42,18 @@ Annotation::Annotation(const srd_proto_data *const pdata) : _format = pda->ann_class; - const char *const *annotations = (char**)pda->ann_text; + const char *const *annotations = (char**)pda->ann_text; while(*annotations) { - _annotations.push_back(QString::fromUtf8(*annotations)); + _annotations.push_back(QString::fromUtf8(*annotations)); annotations++; } } +Annotation::~Annotation() +{ + _annotations.clear(); +} + uint64_t Annotation::start_sample() const { return _start_sample; diff --git a/DSView/pv/data/decode/annotation.h b/DSView/pv/data/decode/annotation.h index dcbdd5cd..a2676bd3 100644 --- a/DSView/pv/data/decode/annotation.h +++ b/DSView/pv/data/decode/annotation.h @@ -35,6 +35,7 @@ class Annotation { public: Annotation(const srd_proto_data *const pdata); + ~Annotation(); uint64_t start_sample() const; uint64_t end_sample() const; diff --git a/DSView/pv/data/decode/decoder.cpp b/DSView/pv/data/decode/decoder.cpp index da17fb48..6e8bd2e0 100644 --- a/DSView/pv/data/decode/decoder.cpp +++ b/DSView/pv/data/decode/decoder.cpp @@ -46,6 +46,10 @@ Decoder::~Decoder() for (map::const_iterator i = _options.begin(); i != _options.end(); i++) g_variant_unref((*i).second); + + for (map::const_iterator i = _options_back.begin(); + i != _options_back.end(); i++) + g_variant_unref((*i).second); } const srd_decoder* Decoder::decoder() const @@ -164,7 +168,7 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_si g_hash_table_insert(probes, (*i).first->id, gvar); } - srd_inst_channel_set_all(decoder_inst, probes, unit_size); + srd_inst_channel_set_all(decoder_inst, probes); return decoder_inst; } diff --git a/DSView/pv/data/decode/row.cpp b/DSView/pv/data/decode/row.cpp index 2aabf0f9..1c0ee9cc 100644 --- a/DSView/pv/data/decode/row.cpp +++ b/DSView/pv/data/decode/row.cpp @@ -38,6 +38,11 @@ Row::Row(const srd_decoder *decoder, const srd_decoder_annotation_row *row) : { } +Row::~Row() +{ + +} + const srd_decoder* Row::decoder() const { return _decoder; diff --git a/DSView/pv/data/decode/row.h b/DSView/pv/data/decode/row.h index 71ee071e..6826c0fc 100644 --- a/DSView/pv/data/decode/row.h +++ b/DSView/pv/data/decode/row.h @@ -36,6 +36,7 @@ class Row { public: Row(); + ~Row(); Row(const srd_decoder *decoder, const srd_decoder_annotation_row *row = NULL); diff --git a/DSView/pv/data/decode/rowdata.cpp b/DSView/pv/data/decode/rowdata.cpp index 1d3ed27f..840459a6 100644 --- a/DSView/pv/data/decode/rowdata.cpp +++ b/DSView/pv/data/decode/rowdata.cpp @@ -34,6 +34,11 @@ RowData::RowData() : { } +RowData::~RowData() +{ + _annotations.clear(); +} + uint64_t RowData::get_max_sample() const { if (_annotations.empty()) diff --git a/DSView/pv/data/decode/rowdata.h b/DSView/pv/data/decode/rowdata.h index ddcdfe24..03076494 100644 --- a/DSView/pv/data/decode/rowdata.h +++ b/DSView/pv/data/decode/rowdata.h @@ -33,6 +33,7 @@ class RowData { public: RowData(); + ~RowData(); public: uint64_t get_max_sample() const; diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index b78b9996..1df0abb0 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -88,6 +88,8 @@ DecoderStack::~DecoderStack() // _decode_thread.join(); // } stop_decode(); + _stack.clear(); + clear(); } const std::list< boost::shared_ptr >& @@ -335,7 +337,7 @@ void DecoderStack::decode_data( { //uint8_t chunk[DecodeChunkLength]; uint8_t *chunk = NULL; - chunk = (uint8_t *)realloc(chunk, DecodeChunkLength); + //chunk = (uint8_t *)realloc(chunk, DecodeChunkLength); const uint64_t chunk_sample_count = DecodeChunkLength / _snapshot->unit_size(); @@ -349,10 +351,10 @@ void DecoderStack::decode_data( const uint64_t chunk_end = min( i + chunk_sample_count, sample_count); - _snapshot->get_samples(chunk, i, chunk_end); + chunk = _snapshot->get_samples(i, chunk_end); if (srd_session_send(session, i, i + sample_count, chunk, - (chunk_end - i) * unit_size) != SRD_OK) { + (chunk_end - i) * unit_size, unit_size) != SRD_OK) { _error_message = tr("Decoder reported an error"); break; } diff --git a/DSView/pv/data/logicsnapshot.cpp b/DSView/pv/data/logicsnapshot.cpp index ec5e4df6..b78b9a9f 100644 --- a/DSView/pv/data/logicsnapshot.cpp +++ b/DSView/pv/data/logicsnapshot.cpp @@ -74,10 +74,9 @@ void LogicSnapshot::append_payload( append_payload_to_mipmap(); } -void LogicSnapshot::get_samples(uint8_t *const data, - int64_t start_sample, int64_t end_sample) const +uint8_t * LogicSnapshot::get_samples(int64_t start_sample, int64_t end_sample) const { - assert(data); + //assert(data); assert(start_sample >= 0); assert(start_sample <= (int64_t)_sample_count); assert(end_sample >= 0); @@ -86,8 +85,9 @@ void LogicSnapshot::get_samples(uint8_t *const data, //lock_guard lock(_mutex); - const size_t size = (end_sample - start_sample) * _unit_size; - memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size); + //const size_t size = (end_sample - start_sample) * _unit_size; + //memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size); + return (uint8_t*)_data + start_sample * _unit_size; } void LogicSnapshot::reallocate_mipmap_level(MipMapLevel &m) diff --git a/DSView/pv/data/logicsnapshot.h b/DSView/pv/data/logicsnapshot.h index 6e9aae12..ba40df84 100644 --- a/DSView/pv/data/logicsnapshot.h +++ b/DSView/pv/data/logicsnapshot.h @@ -67,8 +67,7 @@ public: void append_payload(const sr_datafeed_logic &logic); - void get_samples(uint8_t *const data, - int64_t start_sample, int64_t end_sample) const; + uint8_t * get_samples(int64_t start_sample, int64_t end_sample) const; private: void reallocate_mipmap_level(MipMapLevel &m); diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp index ade12c06..f8a1a88f 100644 --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -41,7 +41,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptrdev_inst()) { @@ -68,7 +68,16 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptrget_config(NULL, NULL, SR_CONF_OPERATION_MODE); + if (gvar != NULL) { + _mode = g_variant_get_string(gvar, NULL); + g_variant_unref(gvar); + } + connect(&_mode_check, SIGNAL(timeout()), this, SLOT(mode_check())); + _mode_check.setInterval(100); + _mode_check.start(); } void DeviceOptions::accept() @@ -100,9 +109,7 @@ void DeviceOptions::accept() void DeviceOptions::reject() { - using namespace Qt; - QDialog::reject(); - + accept(); } QWidget* DeviceOptions::get_property_form() @@ -116,8 +123,11 @@ QWidget* DeviceOptions::get_property_form() BOOST_FOREACH(boost::shared_ptr p, properties) { assert(p); - const QString label = p->labeled_widget() ? QString() : p->name(); - layout->addRow(label, p->get_widget(form)); + const QString label = p->labeled_widget() ? QString() : p->name(); + if (label == "Operation Mode") + layout->addRow(label, p->get_widget(form, true)); + else + layout->addRow(label, p->get_widget(form)); } return form; @@ -127,8 +137,9 @@ void DeviceOptions::setup_probes() { using namespace Qt; - int row = 0, col = 0; + int row0 = 0, row1 = 0, col = 0; int index = 0; + uint16_t ch_mode; while(_probes_box_layout.count() > 0) { @@ -140,6 +151,29 @@ void DeviceOptions::setup_probes() _probes_label_list.clear(); _probes_checkBox_list.clear(); + if (_dev_inst->dev_inst()->mode == LOGIC) { + GVariant *gvar_opts; + gsize num_opts; + if (sr_config_list(_dev_inst->dev_inst()->driver, _dev_inst->dev_inst(), NULL, SR_CONF_CHANNEL_MODE, + &gvar_opts) == SR_OK) { + const char **const options = g_variant_get_strv(gvar_opts, &num_opts); + GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_CHANNEL_MODE); + if (gvar != NULL) { + ch_mode = g_variant_get_uint16(gvar); + g_variant_unref(gvar); + } + for (int i=0; isetChecked(true); + } + } + g_variant_unref(gvar_opts); + } + for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) { sr_channel *const probe = (sr_channel*)l->data; assert(probe); @@ -147,14 +181,14 @@ void DeviceOptions::setup_probes() QLabel *probe_label = new QLabel(QString::number(probe->index), this); QCheckBox *probe_checkBox = new QCheckBox(this); probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); - _probes_box_layout.addWidget(probe_label, row * 2, col); - _probes_box_layout.addWidget(probe_checkBox, row * 2 + 1, col); + _probes_box_layout.addWidget(probe_label, row1 * 2 + row0, col); + _probes_box_layout.addWidget(probe_checkBox, row1 * 2 + 1 + row0, col); _probes_label_list.push_back(probe_label); _probes_checkBox_list.push_back(probe_checkBox); index++; col = index % 8; - row = index / 8; + row1 = index / 8; } QPushButton *_enable_all_probes = new QPushButton(tr("Enable All"), this); @@ -165,8 +199,8 @@ void DeviceOptions::setup_probes() connect(_disable_all_probes, SIGNAL(clicked()), this, SLOT(disable_all_probes())); - _probes_box_layout.addWidget(_enable_all_probes, (row + 1) * 2, 0, 1, 4); - _probes_box_layout.addWidget(_disable_all_probes, (row + 1) * 2, 4, 1, 4); + _probes_box_layout.addWidget(_enable_all_probes, (row1 + 1) * 2 + row0, 0, 1, 4); + _probes_box_layout.addWidget(_disable_all_probes, (row1 + 1) * 2 + row0, 4, 1, 4); } void DeviceOptions::set_all_probes(bool set) @@ -206,5 +240,44 @@ void DeviceOptions::zero_adj() } } +void DeviceOptions::mode_check() +{ + bool test; + QString mode; + GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_OPERATION_MODE); + if (gvar != NULL) { + mode = g_variant_get_string(gvar, NULL); + g_variant_unref(gvar); + + if (mode != _mode) { + setup_probes(); + _mode = mode; + } + } + + gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_TEST); + if (gvar != NULL) { + test = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + + if (test) { + QVector::iterator i = _probes_checkBox_list.begin(); + while(i != _probes_checkBox_list.end()) { + (*i)->setCheckState(Qt::Checked); + (*i)->setDisabled(TRUE); + i++; + } + } + } +} + +void DeviceOptions::channel_check() +{ + QRadioButton* sc=dynamic_cast(sender()); + if(sc != NULL) + _dev_inst->set_config(NULL, NULL, SR_CONF_CHANNEL_MODE, g_variant_new_string(sc->text().toLocal8Bit())); + setup_probes(); +} + } // namespace dialogs } // namespace pv diff --git a/DSView/pv/dialogs/deviceoptions.h b/DSView/pv/dialogs/deviceoptions.h index 14b1e5ce..e8cc4ce7 100644 --- a/DSView/pv/dialogs/deviceoptions.h +++ b/DSView/pv/dialogs/deviceoptions.h @@ -36,6 +36,7 @@ #include #include #include +#include #include @@ -68,6 +69,8 @@ private slots: void enable_all_probes(); void disable_all_probes(); void zero_adj(); + void mode_check(); + void channel_check(); private: boost::shared_ptr _dev_inst; @@ -84,6 +87,9 @@ private: QPushButton *_config_button; QDialogButtonBox _button_box; + QTimer _mode_check; + QString _mode; + pv::prop::binding::DeviceOptions _device_options_binding; }; diff --git a/DSView/pv/prop/binding/binding_deviceoptions.cpp b/DSView/pv/prop/binding/binding_deviceoptions.cpp index e1ce83ec..8b227ffb 100644 --- a/DSView/pv/prop/binding/binding_deviceoptions.cpp +++ b/DSView/pv/prop/binding/binding_deviceoptions.cpp @@ -91,7 +91,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : case SR_CONF_TEST: case SR_CONF_STATUS: case SR_CONF_FACTOR: - bind_enum(name, key, gvar_list); + bind_enum(name, key, gvar_list); break; case SR_CONF_VTH: @@ -110,11 +110,11 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) : break; case SR_CONF_TIMEBASE: - bind_enum(name, key, gvar_list, print_timebase); + bind_enum(name, key, gvar_list, print_timebase); break; case SR_CONF_VDIV: - bind_enum(name, key, gvar_list, print_vdiv); + bind_enum(name, key, gvar_list, print_vdiv); break; default: gvar_list = NULL; @@ -153,7 +153,7 @@ void DeviceOptions::bind_bool(const QString &name, int key) } void DeviceOptions::bind_enum(const QString &name, int key, - GVariant *const gvar_list, boost::function printer) + GVariant *const gvar_list, boost::function printer) { GVariant *gvar; GVariantIter iter; @@ -166,7 +166,7 @@ void DeviceOptions::bind_enum(const QString &name, int key, values.push_back(make_pair(gvar, printer(gvar))); _properties.push_back(boost::shared_ptr( - new Enum(name, values, + new Enum(name, values, bind(config_getter, _sdi, key), bind(config_setter, _sdi, key, _1)))); } @@ -235,7 +235,7 @@ void DeviceOptions::bind_samplerate(const QString &name, else if ((gvar_list_samplerates = g_variant_lookup_value(gvar_list, "samplerates", G_VARIANT_TYPE("at")))) { - bind_enum(name, SR_CONF_SAMPLERATE, + bind_enum(name, SR_CONF_SAMPLERATE, gvar_list_samplerates, print_samplerate); g_variant_unref(gvar_list_samplerates); } diff --git a/DSView/pv/prop/property.cpp b/DSView/pv/prop/property.cpp index d0ab15ea..48ca4a2c 100644 --- a/DSView/pv/prop/property.cpp +++ b/DSView/pv/prop/property.cpp @@ -29,7 +29,7 @@ namespace prop { Property::Property(QString name, Getter getter, Setter setter) : _getter(getter), _setter(setter), - _name(name) + _name(name) { } diff --git a/DSView/pv/prop/property.h b/DSView/pv/prop/property.h index d02bd510..6ef784d5 100644 --- a/DSView/pv/prop/property.h +++ b/DSView/pv/prop/property.h @@ -45,10 +45,10 @@ public: typedef boost::function Setter; protected: - Property(QString name, Getter getter, Setter setter); + Property(QString name, Getter getter, Setter setter); public: - const QString& name() const; + const QString& name() const; virtual QWidget* get_widget(QWidget *parent, bool auto_commit = false) = 0; @@ -61,7 +61,7 @@ protected: const Setter _setter; private: - QString _name; + QString _name; }; } // prop diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index 89957c24..7c67795a 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -793,12 +793,20 @@ void SigSession::reload() signal.reset(); switch(probe->type) { case SR_CHANNEL_LOGIC: - if (probe->enabled && probe->index < _signals.size()) - signal = boost::shared_ptr( - new view::LogicSignal(*_signals[probe->index].get(), _logic_data, probe)); - else if (probe->enabled) - signal = boost::shared_ptr( - new view::LogicSignal(_dev_inst, _logic_data, probe)); + if (probe->enabled) { + std::vector< boost::shared_ptr >::iterator i = _signals.begin(); + while (i != _signals.end()) { + if ((*i)->get_index() == probe->index) { + signal = boost::shared_ptr( + new view::LogicSignal(**i, _logic_data, probe)); + break; + } + i++; + } + if (!signal.get()) + signal = boost::shared_ptr( + new view::LogicSignal(_dev_inst, _logic_data, probe)); + } break; case SR_CHANNEL_DSO: diff --git a/DSView/pv/storesession.cpp b/DSView/pv/storesession.cpp index a687a0b0..6d2ea359 100644 --- a/DSView/pv/storesession.cpp +++ b/DSView/pv/storesession.cpp @@ -150,8 +150,9 @@ void StoreSession::store_proc(shared_ptr snapshot) uint64_t start_sample = 0; /// TODO: Wrap this in a std::unique_ptr when we transition to C++11 - uint8_t *const data = new uint8_t[BlockSize]; - assert(data); + uint8_t *data = NULL; + //uint8_t *const data = new uint8_t[BlockSize]; + //assert(data); const int unit_size = snapshot->unit_size(); assert(unit_size != 0); @@ -170,7 +171,7 @@ void StoreSession::store_proc(shared_ptr snapshot) const uint64_t end_sample = min( start_sample + samples_per_block, _unit_count); - snapshot->get_samples(data, start_sample, end_sample); + data = snapshot->get_samples(start_sample, end_sample); if(sr_session_append(_file_name.c_str(), data, unit_size, end_sample - start_sample) != SR_OK) @@ -189,7 +190,7 @@ void StoreSession::store_proc(shared_ptr snapshot) progress_updated(); - delete[] data; + //delete[] data; } } // pv diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index bad13045..90d6d29c 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -222,8 +222,10 @@ void SamplingBar::on_configure() pv::dialogs::DeviceOptions dlg(this, dev_inst); ret = dlg.exec(); - if (ret == QDialog::Accepted) + if (ret == QDialog::Accepted) { device_updated(); + update_sample_rate_selector(); + } GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO); if (gvar != NULL) { @@ -479,10 +481,10 @@ void SamplingBar::on_samplecount_sel(int index) { uint64_t sample_count = 0; uint64_t max_sample_count = 0; - uint64_t last_sample_count = 0; + //uint64_t last_sample_count = 0; bool stream_mode = false; - bool buffer2stream = false; - bool stream2buffer = false; + //bool buffer2stream = false; + //bool stream2buffer = false; if (index >= 0) sample_count = _sample_count.itemData( @@ -492,7 +494,7 @@ void SamplingBar::on_samplecount_sel(int index) assert(_devInst); if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) { - GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES); + /*GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES); if (gvar != NULL) { last_sample_count = g_variant_get_uint64(gvar); g_variant_unref(gvar); @@ -515,7 +517,7 @@ void SamplingBar::on_samplecount_sel(int index) } else if (stream_mode && sample_count <= max_sample_count) { stream_mode = sample_count > max_sample_count; stream2buffer = true; - } + }*/ // Set the sample count _devInst->set_config(NULL, NULL, @@ -523,8 +525,29 @@ void SamplingBar::on_samplecount_sel(int index) g_variant_new_uint64(sample_count)); + GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar != NULL) { + stream_mode = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + gvar = _devInst->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS); + if (gvar != NULL) { + max_sample_count = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } + if (!stream_mode) { + if (sample_count > max_sample_count) { + _devInst->set_config(NULL, NULL, + SR_CONF_RLE, + g_variant_new_boolean(true)); + } else { + _devInst->set_config(NULL, NULL, + SR_CONF_RLE, + g_variant_new_boolean(false)); + } + } - if (buffer2stream) { + /*if (buffer2stream) { pv::dialogs::StreamOptions stream(this, _devInst, sample_count, stream_mode); stream.setFixedSize(300, 150); stream.exec(); @@ -543,7 +566,7 @@ void SamplingBar::on_samplecount_sel(int index) g_variant_new_boolean(false)); } - device_updated(); + device_updated();*/ update_scale(); } } @@ -552,24 +575,53 @@ void SamplingBar::on_samplerate_sel(int index) { uint64_t sample_rate = 0; //uint64_t last_sample_rate = 0; + uint64_t max_sample_count = 0; + uint64_t sample_count = 0; + bool stream_mode = false; if (index >= 0) sample_rate = _sample_rate.itemData( index).value(); - const sr_dev_inst* _sdi = get_selected_device()->dev_inst(); - assert(_sdi); + boost::shared_ptr _devInst = get_selected_device(); + assert(_devInst); // Get last samplerate //last_sample_rate = get_selected_device()->get_sample_rate(); - if (strcmp(_sdi->driver->name, "DSLogic") == 0 && _sdi->mode != DSO) { + if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) { // Set the samplerate get_selected_device()->set_config(NULL, NULL, SR_CONF_SAMPLERATE, g_variant_new_uint64(sample_rate)); - update_sample_count_selector_value(); - device_updated(); + + GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_STREAM); + if (gvar != NULL) { + stream_mode = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + } + gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES); + if (gvar != NULL) { + sample_count = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } + gvar = _devInst->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS); + if (gvar != NULL) { + max_sample_count = g_variant_get_uint64(gvar); + g_variant_unref(gvar); + } + if (!stream_mode) { + if (sample_count > max_sample_count) { + _devInst->set_config(NULL, NULL, + SR_CONF_RLE, + g_variant_new_boolean(true)); + } else { + _devInst->set_config(NULL, NULL, + SR_CONF_RLE, + g_variant_new_boolean(false)); + } + } + update_scale(); } } diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index 22cfa930..25cbac8c 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -136,6 +136,18 @@ DecodeTrace::DecodeTrace(pv::SigSession &session, this, SLOT(on_show_hide_decoder(int))); } +DecodeTrace::~DecodeTrace() +{ + if (_popup_form) + delete _popup_form; + if (_popup) + delete _popup; + _cur_row_headings.clear(); + _decoder_forms.clear(); + _probe_selectors.clear(); + _bindings.clear(); +} + bool DecodeTrace::enabled() const { return true; diff --git a/DSView/pv/view/decodetrace.h b/DSView/pv/view/decodetrace.h index a7532dd0..44c5791f 100644 --- a/DSView/pv/view/decodetrace.h +++ b/DSView/pv/view/decodetrace.h @@ -89,6 +89,7 @@ public: DecodeTrace(pv::SigSession &session, boost::shared_ptr decoder_stack, int index); + ~DecodeTrace(); bool enabled() const; diff --git a/DSView/pv/view/logicsignal.cpp b/DSView/pv/view/logicsignal.cpp index 4395d48d..3b2527d6 100644 --- a/DSView/pv/view/logicsignal.cpp +++ b/DSView/pv/view/logicsignal.cpp @@ -85,6 +85,7 @@ LogicSignal::LogicSignal(const Signal &s, LogicSignal::~LogicSignal() { + _cur_edges.clear(); } const sr_channel* LogicSignal::probe() const diff --git a/libsigrok4DSL/hardware/DSL/dscope.c b/libsigrok4DSL/hardware/DSL/dscope.c index fbc1e0bb..77aca0bf 100644 --- a/libsigrok4DSL/hardware/DSL/dscope.c +++ b/libsigrok4DSL/hardware/DSL/dscope.c @@ -48,8 +48,6 @@ static struct sr_dev_mode mode_list[] = { static const char *opmodes[] = { "Normal", "Internal Test", - "External Test", - "DRAM Loopback Test", }; static const char *thresholds[] = { @@ -254,7 +252,7 @@ static int fpga_setting(const struct sr_dev_inst *sdi) ((devc->op_mode == SR_OP_EXTERNAL_TEST) << 14) + ((devc->op_mode == SR_OP_LOOPBACK_TEST) << 13) + trigger->trigger_en + - ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 1) + + ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 2) + (((devc->cur_samplerate == SR_MHZ(200) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) + ((devc->cur_samplerate == SR_MHZ(400)) << 6) + ((sdi->mode == ANALOG) << 7) + @@ -579,7 +577,7 @@ static struct DSL_context *DSCope_dev_new(void) devc->clock_type = FALSE; devc->clock_edge = FALSE; devc->instant = FALSE; - devc->op_mode = SR_OP_NORMAL; + devc->op_mode = SR_OP_BUFFER; devc->th_level = SR_TH_3V3; devc->filter = SR_FILTER_NONE; devc->timebase = 10000; @@ -1386,8 +1384,8 @@ 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_NORMAL])) { - devc->op_mode = SR_OP_NORMAL; + if (!strcmp(stropt, opmodes[SR_OP_BUFFER])) { + devc->op_mode = SR_OP_BUFFER; } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST])) { devc->op_mode = SR_OP_INTERNAL_TEST; } else if (!strcmp(stropt, opmodes[SR_OP_EXTERNAL_TEST])) { diff --git a/libsigrok4DSL/hardware/DSL/dsl.h b/libsigrok4DSL/hardware/DSL/dsl.h index a83a43a0..4f5d022b 100644 --- a/libsigrok4DSL/hardware/DSL/dsl.h +++ b/libsigrok4DSL/hardware/DSL/dsl.h @@ -150,13 +150,17 @@ struct DSL_context { /* Device/capture settings */ uint64_t cur_samplerate; uint64_t limit_samples; + uint64_t actual_samples; /* Operational settings */ gboolean sample_wide; gboolean clock_type; gboolean clock_edge; + gboolean rle_mode; gboolean instant; uint16_t op_mode; + uint16_t ch_mode; + uint16_t samplerates_size; uint16_t th_level; double vth; uint16_t filter; diff --git a/libsigrok4DSL/hardware/DSL/dslogic.c b/libsigrok4DSL/hardware/DSL/dslogic.c index e373e19c..75aa014e 100644 --- a/libsigrok4DSL/hardware/DSL/dslogic.c +++ b/libsigrok4DSL/hardware/DSL/dslogic.c @@ -52,10 +52,31 @@ static struct sr_dev_mode pro_mode_list[] = { }; static const char *opmodes[] = { - "Normal", + "Buffer Mode", + "Stream Mode", "Internal Test", - "External Test", - "DRAM Loopback Test", +}; + +static const char *stream_ch_modes[] = { + "Use Channels 0~15 (Max 10MHz)", + "Use Channels 0~7 (Max 25MHz)", +}; + +static const uint16_t stream_ch_num[] = { + 16, + 8, +}; + +static const char *buffer_ch_modes[] = { + "Use Channels 0~15 (Max 100MHz)", + "Use Channels 0~7 (Max 200MHz)", + "Use Channels 0~3 (Max 400MHz)", +}; + +static const uint16_t buffer_ch_num[] = { + 16, + 8, + 4, }; static const char *thresholds[] = { @@ -104,6 +125,7 @@ static const int32_t sessions[] = { SR_CONF_CLOCK_TYPE, SR_CONF_CLOCK_EDGE, SR_CONF_OPERATION_MODE, + SR_CONF_CHANNEL_MODE, SR_CONF_THRESHOLD, SR_CONF_FILTER, SR_CONF_TRIGGER_SLOPE, @@ -118,6 +140,7 @@ static const int32_t sessions_pro[] = { SR_CONF_CLOCK_TYPE, SR_CONF_CLOCK_EDGE, SR_CONF_OPERATION_MODE, + SR_CONF_CHANNEL_MODE, SR_CONF_VTH, SR_CONF_FILTER, SR_CONF_TRIGGER_SLOPE, @@ -318,9 +341,10 @@ static int fpga_setting(const struct sr_dev_inst *sdi) ((devc->stream) << 12) + ((trigger->trigger_mode == SERIAL_TRIGGER) << 11) + trigger->trigger_en + - ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 1) + - (((channel_cnt == 8 && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) + - ((channel_cnt == 4) << 6) + + ((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 2) + + (devc->rle_mode << 3) + + ((((devc->cur_samplerate == (2 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) + + ((devc->cur_samplerate == (4 * DSLOGIC_MAX_LOGIC_SAMPLERATE)) << 6) + ((sdi->mode == ANALOG) << 7) + ((devc->filter == SR_FILTER_1T) << 8) + (devc->instant << 9) + (devc->zero << 10); @@ -459,6 +483,7 @@ static int fpga_config(struct libusb_device_handle *hdl, const char *filename) offset += chunksize; } fclose(fw); + g_free(buf); if (result == SR_OK) sr_info("FPGA configure done"); @@ -596,12 +621,6 @@ static int configure_probes(const struct sr_dev_inst *sdi) if (probe->enabled == FALSE) continue; - if ((probe->index > 7 && probe->type == SR_CHANNEL_LOGIC) || - (probe->type == SR_CHANNEL_ANALOG || probe->type == SR_CHANNEL_DSO)) - devc->sample_wide = TRUE; - else - devc->sample_wide = FALSE; - probe_bit = 1 << (probe->index); if (!(probe->trigger)) continue; @@ -642,11 +661,14 @@ static struct DSL_context *DSLogic_dev_new(void) devc->fw_updated = 0; devc->cur_samplerate = DEFAULT_SAMPLERATE; devc->limit_samples = DEFAULT_SAMPLELIMIT; - devc->sample_wide = 0; + devc->sample_wide = TRUE; devc->clock_type = FALSE; devc->clock_edge = FALSE; + devc->rle_mode = FALSE; devc->instant = FALSE; - devc->op_mode = SR_OP_NORMAL; + devc->op_mode = SR_OP_BUFFER; + devc->ch_mode = 0; + devc->samplerates_size = 14; devc->th_level = SR_TH_3V3; devc->vth = 1.0; devc->filter = SR_FILTER_NONE; @@ -812,9 +834,11 @@ static GSList *scan(GSList *options) sdi->conn = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]), libusb_get_device_address(devlist[i]), NULL); } else { - char *firmware = malloc(strlen(config_path)+strlen(prof->firmware)+1); - if (firmware == NULL) + char *firmware; + if (!(firmware = g_try_malloc(strlen(config_path)+strlen(prof->firmware)+1))) { + sr_err("Firmware path malloc error!"); return NULL; + } strcpy(firmware, config_path); strcat(firmware, prof->firmware); if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION, @@ -824,6 +848,7 @@ static GSList *scan(GSList *options) else sr_err("Firmware upload failed for " "device %d.", devcnt); + g_free(firmware); sdi->inst_type = SR_INST_USB; sdi->conn = sr_usb_dev_inst_new (libusb_get_bus_number(devlist[i]), 0xff, NULL); @@ -1060,9 +1085,11 @@ static int dev_open(struct sr_dev_inst *sdi) } else { /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); - char *fpga_bit = malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1); - if (fpga_bit == NULL) + 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: @@ -1078,6 +1105,7 @@ static int dev_open(struct sr_dev_inst *sdi) if (ret != SR_OK) { sr_err("Configure FPGA failed!"); } + g_free(fpga_bit); } } @@ -1133,6 +1161,7 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, struct DSL_context *devc; struct sr_usb_dev_inst *usb; char str[128]; + uint64_t max_limits = DSLOGIC_MAX_LOGIC_DEPTH; (void)cg; @@ -1172,6 +1201,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; *data = g_variant_new_boolean(devc->clock_edge); break; + case SR_CONF_RLE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_boolean(devc->rle_mode); + break; case SR_CONF_INSTANT: if (!sdi) return SR_ERR; @@ -1184,11 +1219,18 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, devc = sdi->priv; *data = g_variant_new_string(opmodes[devc->op_mode]); break; + case SR_CONF_CHANNEL_MODE: + if (!sdi) + return SR_ERR; + devc = sdi->priv; + *data = g_variant_new_uint16(devc->ch_mode); + break; case SR_CONF_TEST: if (!sdi) return SR_ERR; devc = sdi->priv; - *data = g_variant_new_boolean(devc->op_mode != SR_OP_NORMAL); + *data = g_variant_new_boolean((devc->op_mode != SR_OP_BUFFER) && + (devc->op_mode != SR_OP_STREAM)); break; case SR_CONF_FILTER: if (!sdi) @@ -1306,7 +1348,12 @@ static int config_get(int id, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_MAX_LOGIC_SAMPLELIMITS: if (!sdi) return SR_ERR; - *data = g_variant_new_uint64(DSLOGIC_MAX_LOGIC_DEPTH); + if (devc->cur_samplerate == 2*DSLOGIC_MAX_LOGIC_SAMPLERATE) { + max_limits = DSLOGIC_MAX_LOGIC_DEPTH * 2; + } else if (devc->cur_samplerate == 4*DSLOGIC_MAX_LOGIC_SAMPLERATE) { + max_limits = DSLOGIC_MAX_LOGIC_DEPTH * 4; + } + *data = g_variant_new_uint64(max_limits); break; case SR_CONF_STATUS: if (!sdi) @@ -1328,6 +1375,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, const char *stropt; int ret, num_probes; struct sr_usb_dev_inst *usb; + int i; (void)cg; @@ -1339,37 +1387,22 @@ 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); - if (sdi->mode == LOGIC) { - if (devc->limit_samples > DSLOGIC_MAX_LOGIC_DEPTH) { - if (devc->cur_samplerate > SR_MHZ(25)) { - devc->limit_samples = DSLOGIC_MAX_LOGIC_DEPTH; - } else if (devc->cur_samplerate >= SR_MHZ(20) || - devc->limit_samples >= SR_GB(1)) { - adjust_probes(sdi, 8); - } else { - adjust_probes(sdi, 16); - } - } - - if (devc->limit_samples <= DSLOGIC_MAX_LOGIC_DEPTH) { - if (devc->cur_samplerate >= SR_MHZ(200)) { - adjust_probes(sdi, SR_MHZ(1600)/devc->cur_samplerate); - } else { - adjust_probes(sdi, 16); - } - } - - ret = SR_OK; - } else if(sdi->mode == DSO) { + if(sdi->mode == DSO) { + devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_DSO_SAMPLERATE); ret = command_dso_ctrl(usb->devhdl, dso_cmd_gen(sdi, 0, SR_CONF_SAMPLERATE)); + } else { + devc->sample_wide = (devc->cur_samplerate <= DSLOGIC_MAX_LOGIC_SAMPLERATE); + ret = SR_OK; } - } else if (id == SR_CONF_CLOCK_TYPE) { devc->clock_type = g_variant_get_boolean(data); ret = SR_OK; } else if (id == SR_CONF_CLOCK_EDGE) { devc->clock_edge = g_variant_get_boolean(data); ret = SR_OK; + } else if (id == SR_CONF_RLE) { + devc->rle_mode = g_variant_get_boolean(data); + ret = SR_OK; } else if (id == SR_CONF_INSTANT) { if (sdi->mode == DSO) { devc->instant = g_variant_get_boolean(data); @@ -1494,18 +1527,40 @@ 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_NORMAL])) { - devc->op_mode = SR_OP_NORMAL; - } else if (!strcmp(stropt, opmodes[SR_OP_INTERNAL_TEST])) { + 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])) { + } 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])) { + } 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 { @@ -1513,6 +1568,28 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } 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; + } + } + sr_dbg("%s: setting channel mode to %d", + __func__, devc->ch_mode); } else if (id == SR_CONF_THRESHOLD) { stropt = g_variant_get_string(data, NULL); ret = SR_OK; @@ -1528,9 +1605,11 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, } else { /* Takes >= 10ms for the FX2 to be ready for FPGA configure. */ g_usleep(10 * 1000); - char *fpga_bit = malloc(strlen(config_path)+strlen(devc->profile->fpga_bit33)+1); - if (fpga_bit == NULL) + 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: @@ -1546,6 +1625,7 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, if (ret != SR_OK) { sr_err("Configure FPGA failed!"); } + g_free(fpga_bit); } sr_dbg("%s: setting threshold to %d", __func__, devc->th_level); @@ -1724,11 +1804,13 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi, static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, const struct sr_channel_group *cg) { + struct DSL_context *devc; GVariant *gvar; GVariantBuilder gvb; //(void)sdi; (void)cg; + devc = sdi->priv; switch (key) { case SR_CONF_SCAN_OPTIONS: @@ -1766,7 +1848,7 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, // gvar = g_variant_new_fixed_array(G_VARIANT_TYPE("t"), samplerates, // ARRAY_SIZE(samplerates), sizeof(uint64_t)); gvar = g_variant_new_from_data(G_VARIANT_TYPE("at"), - samplerates, ARRAY_SIZE(samplerates)*sizeof(uint64_t), TRUE, NULL, NULL); + samplerates, devc->samplerates_size*sizeof(uint64_t), TRUE, NULL, NULL); g_variant_builder_add(&gvb, "{sv}", "samplerates", gvar); *data = g_variant_builder_end(&gvb); break; @@ -1783,6 +1865,14 @@ static int config_list(int key, GVariant **data, const struct sr_dev_inst *sdi, case SR_CONF_OPERATION_MODE: *data = g_variant_new_strv(opmodes, ARRAY_SIZE(opmodes)); break; + case SR_CONF_CHANNEL_MODE: + if (devc->stream) + *data = g_variant_new_strv(stream_ch_modes, ARRAY_SIZE(stream_ch_modes)); + else if (devc->op_mode != SR_OP_BUFFER) + *data = g_variant_new_strv(buffer_ch_modes, 1); + else + *data = g_variant_new_strv(buffer_ch_modes, ARRAY_SIZE(buffer_ch_modes)); + break; case SR_CONF_THRESHOLD: *data = g_variant_new_strv(thresholds, ARRAY_SIZE(thresholds)); break; @@ -1919,12 +2009,7 @@ static void receive_transfer(struct libusb_transfer *transfer) /* Save incoming transfer before reusing the transfer struct. */ cur_buf = transfer->buffer; - GSList *l; - int channel_cnt = 0; - for (l = ((struct sr_dev_inst *)(devc->cb_data))->channels; l; l = l->next) - channel_cnt++; - - sample_width = (channel_cnt > 8) ? 2 : 1; + sample_width = (devc->sample_wide) ? 2 : 1; cur_sample_count = transfer->actual_length / sample_width; switch (transfer->status) { @@ -2098,9 +2183,9 @@ static void receive_transfer(struct libusb_transfer *transfer) analog.data = cur_buf + trigger_offset_bytes; } - if ((devc->limit_samples && devc->num_samples < devc->limit_samples) || + if ((devc->limit_samples && devc->num_samples < devc->actual_samples) || (*(struct sr_dev_inst *)(devc->cb_data)).mode != LOGIC ) { - const uint64_t remain_length= (devc->limit_samples - devc->num_samples) * sample_width; + const uint64_t remain_length= (devc->actual_samples - devc->num_samples) * sample_width; logic.length = min(logic.length, remain_length); /* in test mode, check data content*/ @@ -2145,9 +2230,9 @@ static void receive_transfer(struct libusb_transfer *transfer) } devc->num_samples += cur_sample_count; - if (((*(struct sr_dev_inst *)(devc->cb_data)).mode == LOGIC || devc->instant) && + if (((*(struct sr_dev_inst *)(devc->cb_data)).mode == LOGIC || devc->instant) && devc->limit_samples && - (unsigned int)devc->num_samples >= devc->limit_samples) { + (unsigned int)devc->num_samples >= devc->actual_samples) { //abort_acquisition(devc); free_transfer(transfer); devc->status = DSL_STOP; @@ -2327,14 +2412,21 @@ static void receive_trigger_pos(struct libusb_transfer *transfer) switch (transfer->status) { case LIBUSB_TRANSFER_COMPLETED: if (transfer->actual_length == sizeof(struct ds_trigger_pos)) { - packet.type = SR_DF_TRIGGER; - packet.payload = trigger_pos; - sr_session_send(devc->cb_data, &packet); + if (trigger_pos->remain_cnt < devc->limit_samples) { + devc->actual_samples = (devc->limit_samples - ceil(devc->cur_samplerate * 1.0 / DSLOGIC_MAX_LOGIC_SAMPLERATE) * (trigger_pos->remain_cnt + devc->rle_mode)); - devc->status = DSL_TRIGGERED; - free_transfer(transfer); - devc->num_transfers = 0; - devc->empty_transfer_count = 0; + packet.type = SR_DF_TRIGGER; + packet.payload = trigger_pos; + sr_session_send(devc->cb_data, &packet); + + devc->status = DSL_TRIGGERED; + free_transfer(transfer); + devc->num_transfers = 0; + devc->empty_transfer_count = 0; + } else { + free_transfer(transfer); + devc->status = DSL_ERROR; + } } else { free_transfer(transfer); devc->status = DSL_ERROR; @@ -2447,7 +2539,7 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, void *cb_data) } if ((ret = command_start_acquisition (usb->devhdl, - devc->cur_samplerate, devc->sample_wide, (sdi->mode == LOGIC))) != SR_OK) { + devc->cur_samplerate, 1, (sdi->mode == LOGIC))) != SR_OK) { abort_acquisition(devc); return ret; } diff --git a/libsigrok4DSL/hwdriver.c b/libsigrok4DSL/hwdriver.c index 0d187cca..25b7dbf8 100644 --- a/libsigrok4DSL/hwdriver.c +++ b/libsigrok4DSL/hwdriver.c @@ -62,7 +62,7 @@ static struct sr_config_info sr_config_info_data[] = { {SR_CONF_CLOCK_TYPE, SR_T_BOOL, "clocktype", "Using External Clock", "Using External Clock", NULL}, {SR_CONF_CLOCK_EDGE, SR_T_BOOL, "clockedge", - "Using Clock Negedge", "Using Clock Negedge", NULL}, + "Using Clock Negedge", "Using Clock Negedge", NULL}, {SR_CONF_CAPTURE_RATIO, SR_T_UINT64, "captureratio", "Pre-trigger capture ratio", "Pre-trigger capture ratio", NULL}, {SR_CONF_PATTERN_MODE, SR_T_CHAR, "pattern", @@ -95,6 +95,8 @@ static struct sr_config_info sr_config_info_data[] = { "Datalog", "Datalog", NULL}, {SR_CONF_OPERATION_MODE, SR_T_CHAR, "operation", "Operation Mode", "Operation Mode", NULL}, + {SR_CONF_CHANNEL_MODE, SR_T_CHAR, "channel", + "Channel Mode", "Channel Mode", NULL}, {SR_CONF_THRESHOLD, SR_T_CHAR, "threshold", "Threshold Level", "Threshold Level", NULL}, {SR_CONF_VTH, SR_T_FLOAT, "threshold", diff --git a/libsigrok4DSL/libsigrok.h b/libsigrok4DSL/libsigrok.h index 60794b31..abe72ff3 100644 --- a/libsigrok4DSL/libsigrok.h +++ b/libsigrok4DSL/libsigrok.h @@ -801,6 +801,9 @@ enum { /** Device operation mode */ SR_CONF_OPERATION_MODE, + /** Device channel mode */ + SR_CONF_CHANNEL_MODE, + /** Device sample threshold */ SR_CONF_THRESHOLD, SR_CONF_VTH, @@ -919,13 +922,14 @@ enum { /** Device operation modes. */ enum { /** Normal */ - SR_OP_NORMAL = 0, + SR_OP_BUFFER = 0, + SR_OP_STREAM = 1, /** Internal pattern test mode */ - SR_OP_INTERNAL_TEST = 1, + SR_OP_INTERNAL_TEST = 2, /** External pattern test mode */ - SR_OP_EXTERNAL_TEST = 2, + SR_OP_EXTERNAL_TEST = 3, /** SDRAM loopback test mode */ - SR_OP_LOOPBACK_TEST = 3, + SR_OP_LOOPBACK_TEST = 4, }; /** Device threshold level. */ @@ -1065,7 +1069,8 @@ struct ds_trigger { struct ds_trigger_pos { uint32_t real_pos; uint32_t ram_saddr; - unsigned char first_block[504]; + uint32_t remain_cnt; + unsigned char first_block[500]; }; #include "proto.h" diff --git a/libsigrok4DSL/session_driver.c b/libsigrok4DSL/session_driver.c index dc9569b9..81b475de 100644 --- a/libsigrok4DSL/session_driver.c +++ b/libsigrok4DSL/session_driver.c @@ -141,6 +141,13 @@ static int dev_open(struct sr_dev_inst *sdi) return SR_ERR_MALLOC; } + struct session_vdev *vdev; + vdev = sdi->priv; + if (!(vdev->buf = g_try_malloc(CHUNKSIZE))) { + sr_err("%s: vdev->buf malloc failed", __func__); + return SR_ERR_MALLOC; + } + dev_insts = g_slist_append(dev_insts, sdi); return SR_OK; @@ -291,11 +298,6 @@ static int dev_acquisition_start(const struct sr_dev_inst *sdi, return SR_ERR; } - if (!(vdev->buf = g_try_malloc(CHUNKSIZE))) { - sr_err("%s: buf malloc failed", __func__); - return SR_ERR; - } - /* Send header packet to the session bus. */ std_session_send_df_header(sdi, LOG_PREFIX);